mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 02:03:35 +00:00
Predicates are written with an element size wherever they are an operand rather than the governing mask -- `zip1 p0.b, p1.b, p2.b`, and `and p0.b, p1/z, p2.b, p3.b`, where the same instruction has both. 59 source operands printed bare. Two paths were missing it outright: .PN never picked up the size at all, and the WHILE family had one form standing in for all four element sizes, so `whilelt` could only ever print `p0`. SVE gather and scatter name the element size of their vector index and how the base extends it (`[x0, z0.s, uxtw]`); none of that was printed. The two lay their fields out differently and the difference is not cosmetic: a gather has the extend at bit 22 and takes the index width from its opcode, while a scatter has the width at 22 and the extend at 14. Reading them the same way meant the .s scatters carried the .d encoding -- ST1B, ST1H and ST1W all had two forms with identical bits, so one of each pair was dead. Memory had no room left for the index's element size (16 + 16 + 23 + 3 + 3 + 3 is exactly 64; the "1 bit spare" comment was stale), so it travels in the operand's own size field, which memory operands do not otherwise use. INDEX had its two operands in each other's slots: SVE_IMM5 is bits 20:16, which is the *second* operand, so the first was written to the wrong field and the second was not written at all -- `index z0.b, #0,` with a trailing empty operand. It was also .b-only, and its register operands are W below .d rather than X. SVE LDR/STR move a whole register and take no element size; an earlier pass had given their operands one. SVE/SME2 decode entries against llvm-mc: 525 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