mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 02:03:35 +00:00
Chasing the SME2 gap turned up that the thing blocking it was much
larger than SME2. Every predicated SVE instruction printed its predicate
bare -- `p0` where the syntax needs `p0/z` or `p0/m` -- and an assembler
rejects that outright. 357 forms carried one.
A predicate's governing qualifier is fixed by the form, so it comes from
the operand type and rides in the operand as a marker the printer reads.
Predicated SVE loads and stores also write their vector as a list, so
those 42 forms go through the same one-register list path the NEON work
added: `ld1b { z0.b }, p0/z, [x0, x0]`.
SME2 then needed three things it did not have. A predicate-as-counter
register class -- SME2 governs with pn8..pn15, numbered from 8, sharing
the field but not the register bank. An element size on the pair and
quad operands, which cannot ride on the encoding the way the list length
does, because it is what separates LD1B from LD1H. And the list length
itself, which the pair/quad encodings now carry.
The sweep that verified this found two real encoding bugs behind it:
- 97 SVE predicated binary ops read Zm from bits 20:16, where the
architecture has the opcode. `add z0.b, p0/m, z0.b, z1.b` encoded
0x04010000, which is SUB. Their masks left that opcode field free
too, so each mnemonic's pattern also matched its siblings'.
- AND/ORR/EOR/BIC predicated had one form apiece, labelled .d but
encoding .b, since the size field at bits 23:22 was never in the
pattern. Split into the four sizes.
SVE/SME2 decode entries against llvm-mc: 312 byte-exact and 1
mismatched, from 211 and 78. The one left is XAR, whose four forms are
legitimately bit-identical -- the element size shares a field with the
shift.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018UmHLRF11EoWwNWCJ7JGaA