Files
Odin/core/rexcode
Flāvius e59cf23275 rexcode/arm64: extended-register addressing, and the shift that printed its S bit
Register offset and extended-register offset are one instruction word --
the option field at 15:13 picks LSL / UXTW / SXTW / SXTX -- but only LSL
was reachable: no encode form used MEM_EXT, so [Xn, Wm, SXTW #s] had a
matcher, a packer, and no way to be asked for. Worse, decoding such a word
produced mode REG_OFFSET with a stray extend, which re-encoded as LSL --
a silent corruption round-trip.

The one MEM_REG form now serves both modes, the way the RM slot takes
plain and shifted registers: the matcher accepts EXT_REG_OFFSET and checks
the index width against the extend (UXTW/SXTW take Wm, UXTX/SXTX take Xm,
the byte/half extends match nothing -- and a REG_OFFSET index must now be
an X register), the OFFSET_REG packer writes option from the operand's
mode, and the decoder derives the mode from option rather than from which
form matched. MEM_EXT/OFFSET_EXT stay in their enums -- the values are
baked into the table blobs -- marked subsumed.

Also fixed while there: the decoder stored the raw S bit as the shift
amount, so LDR X0, [X1, X2, LSL #3] decoded -- and printed -- as LSL #1.
The amount is log2 of the transfer size, recovered from size(31:30) and,
for SIMD, opc<1>(23). The one thing Memory cannot represent is a byte
access with an explicit #0 (S=1, amount 0); it decodes as no amount.

New pipeline tests: ten llvm-mc golden words across the extends and
widths, decode/print round-trips matching llvm's canonical spelling, the
LSL amount, and four malformed-operand rejections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFeLCDKi5kRMtHrskUaRfw
2026-08-30 18:36:34 -04:00
..
2026-07-14 13:28:12 +01:00