Files
Odin/core/rexcode
Brendan Punsky a0c10eab83 rexcode/arm64: XAR was never ambiguous, and the SVE element sizes were unreachable
I had this wrong. XAR is fully determined by the word: `tszh:tszl:imm3`
holds `2*esize - shift`, and since the shift is in [1, esize] the four
element sizes occupy disjoint ranges (.b 8-15, .h 16-31, .s 32-63,
.d 64-127), so the highest set bit names the size. Nothing is ambiguous;
the table just could not say "the element size is in an operand field".

So it was four identical (bits, mask) entries standing in for one. Encode
already worked -- the matcher picked among them by the operand -- but
decode had four entries tied on every sort key, and which one won was
whatever the unstable sort left. It answered `.s`, the fall-through,
because reg_size_for_type had no case at all for them.

Now there is one form. The Z operands' element size is read out of the
word (VD_TSZ/VN_TSZ), and the shift's is taken from the register the
caller passed rather than from the form -- which means the packer needs
to see the instruction, not just its operand, since this field genuinely
couples two of them. The tsz rule itself lived twice, as arithmetic in
the encoder and a threshold ladder in the decoder; it is one helper now.

Downstream, and much larger: every SVE element size collapsed onto a
single builder, exactly as the NEON arrangements did. 264 of the 470
forms with a Z operand were unreachable -- `inst_xar_z_z_z_i` could only
ever make .b. The size is in the name now (inst_add_zb_zb_zb and
friends), which took the builders from 1847 to 2141.

The sweep that verified it found two more:

  - A predicate that is the destination is written with an element size,
    not a qualifier: `cmpge p0.b, p1/z, ...`. 106 forms printed a bare
    `p0`. The two suffixes are told apart by encoding -- PD against PG --
    and by disjoint size codes.

  - SVE's indexed FMLA/FMLS printed their lane as `, #1` rather than
    `[1]`; those encodings were simply missing from the lane-index set.

The decode sort is now total (it ties on table order last), so which
entry wins can no longer vary between builds.

SVE/SME2 decode entries against llvm-mc: 370 byte-exact and 0
mismatched, from 211 and 78 at the start of the session.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UmHLRF11EoWwNWCJ7JGaA
2026-08-28 04:53:11 -04:00
..
2026-07-14 13:28:12 +01:00