Commit Graph

3 Commits

Author SHA1 Message Date
Brendan Punsky
b8c391e9e1 rexcode/arm32: take the encoding-shaped names down to what assemblers spell
Of the 38 mnemonics still carrying an encoding-shaped name, 24 were simply
names no assembler accepts, and arm32's printer emits the enum name verbatim
-- so `vldrb_gather`, `vceq_z`, `vmov_q_r` and friends were the printed
output. Judged against llvm-mc in every case:

  renamed (base name was free)
    BFI_BR -> BFX      the V8.1M Branch Future indeXed, not a bitfield
                       insert; llvm assembles `bfx .L, r0` to F060E001,
                       which is exactly the bit pattern this entry held.
    VDOT_BF16  -> VDOT      `vdot.bf16 d0, d1, d2`
    VMMLA_BF16 -> VMMLA     `vmmla.bf16 q0, q1, q2`

  merged into the base mnemonic (21)
    VCEQ_Z/VCGE_Z/VCGT_Z/VCLE_Z/VCLT_Z -> the compare-against-zero forms
      are the same mnemonic with a literal `#0`: `vceq.i8 d0, d1, #0`.
    VCVT_FIXED, VCVT_BF16 -> VCVT      `vcvt.s16.f32 s0, s0, #4`
    VFMA_BF16 -> VFMA
    VLDR{B,H,W,D}_GATHER, VSTR{B,H,W,D}_SCATTER -> VLDR*/VSTR*: an MVE
      gather is spelled `vldrb.u8 q0, [r0, q1]`; the vector offset is an
      operand, not part of the mnemonic.
    VMOV_Q_R, VMOV_R_Q, VMOV_2GPR_Q -> VMOV
    VHCADD_SAT -> VHCADD, VCMLA_MVE -> VCMLA

  kept, but printed properly (2)
    PSB_CSYNC / TSB_CSYNC are written as two tokens, `psb csync`, the same
    shape as arm64's DC/AT/TLBI. The underscore now prints as a space; no
    other arm32 mnemonic has one.

Every merged form had an operand signature the matcher could already tell
apart from the base's, so nothing became unreachable. 631 -> 590 mnemonics,
underscore-bearing names 58 -> 14.

Test indices were re-derived by matching (bits, mask) against the rebuilt
table rather than by computing offsets -- every index the tests reference was
found, which is a check that the merge dropped no form.

Still blocked, and for the two reasons already known:
  VPADD_F, VRECPE_F, VRSQRTE_F  -- collide with their base because the NEON
    data type (.f32 vs .i8/.u32) is not an operand.
  VMOV_LANE, VLD1-4_LANE, VST1-4_LANE -- register lists and lane indices are
    not modelled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 23:21:57 -04:00
Brendan Punsky
5cba6402f6 rexcode: fix the mnemonic problems in arm32, mips, riscv and mos6502
The arm64 pass turned up the same class of bug elsewhere: mnemonics named
after an encoding rather than after what an assembler accepts, and forms
that no caller can reach because the thing that tells them apart is not
checked.

mips
  * The printer mapped every `_` to `.`, but MSA spells the sign qualifier
    with an underscore and only the element size with a dot: `adds_s.b`,
    `max_s.h`, `copy_u.w`. `adds.s.b` is rejected by an assembler. 91
    mnemonics were printing text that would not reassemble. The name alone
    cannot decide it -- MSA's ADDS_S_D and the FP convert CVT_S_D have the
    same shape and want opposite treatment -- so the family is read off the
    form's feature.
  * `encode` now takes `features: Feature_Set = FEATURES_ALL` and skips
    forms outside it, mirroring `decode`, which has had that parameter all
    along. That asymmetry was the reason 12 mnemonics carried an ISA-variant
    suffix: with no way to say which MIPS you were targeting, the pre-R6 and
    R6 encodings of `mul` had to be two enum members. They are now one
    mnemonic with two forms. Eight of the twelve did not even need the
    feature filter -- pre-R6 MADD takes rs,rt while the PS2 MMI MADD takes
    rd,rs,rt, so operand matching alone separates them. Verified against
    llvm-mc: pre-R6 `mul` 712a4002, R6 `mul` 012a4098, `madd $t1,$t2`
    712a0000. The printer's hand-written override table is gone.

arm32
  * 20 `*_LANE` mnemonics folded into their base. The lane form differs from
    the base in an operand TYPE already (DPR_ELEM vs DPR), so the matcher
    could always tell them apart; the split only cost us the printed name,
    which was the enum name verbatim -- `vqdmulh_lane`, which no assembler
    takes. VMOV/VLD1-4/VST1-4 are left alone: their lane forms collide with
    the base because register lists and lane indices are not modelled.

riscv
  * ZEXT_H and REV8 each carry an RV32 and an RV64 encoding with identical
    operands, and the forms were already tagged rv32_only / rv64_only -- the
    encoder just never looked. `encode` now takes `xlen: XLEN = .RV64` and
    filters, so the RV64 encodings are reachable at all: zext.h 0805c53b and
    rev8 6b85d513, both confirmed against llvm-mc.

mos6502
  * SAX_NMOS folded into SAX. The undocumented NMOS store-A&X and the
    HuC6280 register swap share the mnemonic `sax`; one takes a memory
    operand and the other takes none, so they are just two form sets.

Verified: every rexcode suite matches HEAD exactly, all 13 packages build,
and MIPS mnemonics llvm-mc does not recognise drop from 448 to 354.

Still open: arm32 has 201 form signatures no caller can select, because the
NEON data type (.i8/.i16/.f32) is not an operand -- `inst_vadd(d0,d1,d2)`
always yields the first form, and only a decoder-supplied form_id hint can
pick another. 38 arm32 mnemonics still carry encoding-shaped names
(VPADD_F, VCEQ_Z, VLDRB_GATHER, VMOV_Q_R, ...).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-26 20:46:33 -04:00
Brendan Punsky
95df04fbe1 rexcode: re-house ISA packages under core:rexcode/isa/<arch>
Move all ten ISA packages (x86, arm32, arm64, mips, riscv, ppc, ppc_vle,
rsp, mos6502, mos65816) from core/rexcode/<arch> to core/rexcode/isa/<arch>,
so the import pattern is now `import "core:rexcode/isa/x86"`. The shared
core stays at core:rexcode/isa.

Mechanical: relative `import "../isa"` / "../../isa" -> absolute
"core:rexcode/isa" (the only path that survives the move; the "../" and
"../.." self/generated imports move with their packages). build.lua now
builds paths as <root>/isa/<name>; stale `cd <arch>` hints in the verify
tools and the doc.odin paths updated.

WASM stays at core/rexcode/wasm for now -- it is an IR, not an ISA, and
will move under the forthcoming core:rexcode/ir once that layer lands.

All 10 arches gen/builders/check/test green; import core:rexcode/isa/x86
verified working; wasm still compiles.
2026-06-18 19:03:27 -04:00