Skip to content

target/mips: add partial Cavium Octeon (cnMIPS) instruction support#2318

Open
retrocpugeek wants to merge 5 commits into
unicorn-engine:devfrom
retrocpugeek:mips-octeon-plus-support
Open

target/mips: add partial Cavium Octeon (cnMIPS) instruction support#2318
retrocpugeek wants to merge 5 commits into
unicorn-engine:devfrom
retrocpugeek:mips-octeon-plus-support

Conversation

@retrocpugeek

@retrocpugeek retrocpugeek commented Apr 25, 2026

Copy link
Copy Markdown

Summary

Adds partial Cavium Octeon (cnMIPS) instruction support so that Octeon userspace (e.g. OpenWrt busybox for mips64_octeonplus) no longer traps on common integer, popcount, and atomic-add ops.

Implemented: bbit0, bbit032, bbit1, bbit132, cins, cins32, exts, exts32, dmul, seq, sne, seqi, snei, saa, saad, baddu, pop, dpop, and hardware register 31 (rdhwr $31, CvmCount).

Not implemented (still trap as RI): syncs/syncw/synciobdma, the CVM_MT_* / CVM_MF_* COP2 crypto ops, Octeon MMI, any Octeon II (CN6XXX) additions.

Behaviour follows CN50XX HRM §"Cavium Networks-Specific Instruction Descriptions" (pages 827–937). saa/saad are store-atomic-add; since unicorn is single-threaded per emulation they are implemented as a plain load/add/store on the naturally-aligned address. saad/dpop are gated with check_mips_64().

rdhwr rt, $31 reads the Octeon-specific free-running core-cycle counter (CvmCount). Generic MIPS treats hardware register 31 as invalid and raises a Reserved Instruction exception; on an Octeon core it must return the cycle count. As this configuration runs no CP0 cycle timer, CvmCount is modelled as a per-CPU 64-bit counter advanced a fixed amount on each read, giving a monotonically increasing value. The decode case is gated with check_insn(ctx, INSN_OCTEON).

A new INSN_OCTEON ISA flag gates the dispatch cases; a new UC_CPU_MIPS64_OCTEON_PLUS CPU model exposes the extensions (PRId 0x000d0600, CompanyID 0x0d / ProcessorID 0x06 per HRM).

Test plan

  • bindings/python/tests/test_mips_octeon.py — 34 unit tests covering all implemented mnemonics: seq/sne/seqi/snei, dmul, cins/cins32, exts/exts32, taken/not-taken paths for each BBIT variant, saa/saad (add, 32-bit wrap, adjacent-word integrity), baddu (byte truncation), pop/dpop (low-32 vs full-64 popcount), and rdhwr $31 (CvmCount is non-faulting and strictly increases between reads)
  • Verified against a real openwrt busybox built for mips64_octeonplus_64_musl (function using exts in a delay slot)
  • Existing MIPS CPU models unaffected (ops only decoded when INSN_OCTEON is set)

@retrocpugeek retrocpugeek force-pushed the mips-octeon-plus-support branch from 20d6b0d to 3385fe9 Compare April 25, 2026 03:51
wtdcode and others added 3 commits June 25, 2026 20:47
Octeon userspace (e.g. OpenWrt busybox built for mips64_octeonplus)
frequently emits cnMIPS-specific ops that trapped as Reserved
Instruction on every existing MIPS64 CPU model.  This patch adds the
subset used by typical Octeon-Plus integer userspace:

  BBIT0 / BBIT032 / BBIT1 / BBIT132   (primary opcodes 0x32 / 0x36 /
                                       0x3A / 0x3E, reusing non-R6
                                       LWC2/LDC2/SWC2/SDC2 slots)
  CINS / CINS32                       (SPECIAL2 func 0x32 / 0x33)
  EXTS / EXTS32                       (SPECIAL2 func 0x3A / 0x3B)
  DMUL                                (SPECIAL2 func 0x03)
  SEQ / SNE                           (SPECIAL2 func 0x2A / 0x2B)
  SEQI / SNEI                         (SPECIAL2 func 0x2E / 0x2F)

All codegen uses existing TCG primitives (tcg_gen_setcond,
tcg_gen_mul_tl, tcg_gen_deposit_z_tl, tcg_gen_sextract_tl,
tcg_gen_extract_tl) and reuses the standard MIPS branch bookkeeping for
BBIT delay slots.  Instruction behaviour matches the CN50XX HRM
(§ "Cavium Networks-Specific Instruction Descriptions", pages 827-937).

A new coarse INSN_OCTEON flag gates the dispatch cases, and a new
"Octeon-Plus" CPU model (PRId=0x000d0600 per HRM: CompanyID=0x0d,
ProcessorID=0x06 for CN50XX) is exposed as UC_CPU_MIPS64_OCTEON_PLUS.

Not implemented in this patch (still trap as RI): BADDU, POP/DPOP,
SAA/SAAD, SYNCS/SYNCW/SYNCIOBDMA, the CVM_MT_*/CVM_MF_* COP2 crypto
ops, Octeon MMI, and all Octeon II (CN6XXX) additions.

Tests: bindings/python/tests/test_mips_octeon.py covers all nine new
mnemonics including taken/not-taken paths for each BBIT variant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@retrocpugeek retrocpugeek force-pushed the mips-octeon-plus-support branch from 3385fe9 to 7e85015 Compare June 25, 2026 10:47
retrocpugeek and others added 2 commits July 4, 2026 22:22
Extend the partial Cavium Octeon (cnMIPS) SPECIAL2 decode with five more
instructions:

  SAA   (funct 0x18) mem32[base] += rt<31:0>
  SAAD  (funct 0x19) mem64[base] += rt<63:0>   (64-bit)
  BADDU (funct 0x28) rd = (rs + rt) & 0xff
  POP   (funct 0x2c) rd = popcount(rs<31:0>)
  DPOP  (funct 0x2d) rd = popcount(rs<63:0>)   (64-bit)

SAA/SAAD are store-atomic-add; unicorn is single-threaded per emulation
so a plain load/add/store on the naturally-aligned address suffices.
DPOP/SAAD are gated with check_mips_64(); all are gated INSN_OCTEON.

Adds correctness tests for all five to test_mips_octeon.py.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rdhwr rt, $31 reads the Octeon-specific free-running core-cycle counter
(CvmCount). Generic MIPS decodes rd=31 as an invalid hardware register and
raises a Reserved Instruction exception; on an Octeon core it must return the
cycle count.

This configuration runs no CP0 cycle timer, so model CvmCount as a per-CPU
64-bit counter advanced a fixed amount on each read, giving a monotonically
increasing value. Add a decode case guarded by INSN_OCTEON, a helper, the
per-arch symbol aliases, and a unit test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants