Files
Odin/core/rexcode/isa
Brendan Punsky 201dfdb454 rexcode/arm32: every VFP and NEON register list disassembled wrong
`vpush {d8, d9}` came out as `vpush {r2}`. VFP list operands kept only
the 8-bit count from the encoding and stored it in a REG_LIST operand,
whose immediate the printer reads as a GPR bitmask -- so the register
bank was wrong, the start register was gone entirely, and the count was
read as a bitmask. `vldm r0, {d1, d2, d3}` printed `{r1-r2}`.

A list is now a register plus a shape: how many, and what the run steps
by. VLDM/VSTM/VPUSH/VPOP recover their start register from Vd and their
count from imm8. A GPR list stays a bitmask, since `{r4, lr}` is not a
run at all.

The NEON structure loads were wrong in a second way. VLD1-4/ST1-4 encode
their register count in the type field at bits 11:8, not in imm8, so
writing a count into the low byte overwrote size, alignment and Rm. Rm
was left at 0, which is a register post-increment, where the plain form
needs 0b1111; every one of those 23 forms encoded a writeback nobody
asked for. The count now comes from the form, the encoding writes only
Vd, and Rm is fixed in the pattern.

Deriving those counts from llvm-mc rather than by hand turned up a
dimension that was not modelled at all: the spaced forms step two
registers at a time (`vld2.8 {d2, d4}`), and VLD1 has a to-all-lanes
form written `{d2[]}`.

All 31 A32 list forms are now byte-exact against llvm-mc, from 8. The
arm32 sweep holds at 1656/1656.

Still open here: those forms only exist for .8 data, because the size
field at bits 7:6 is unencoded, and the writeback variants
(`[r0]!`, `[r0], r1`) are not modelled.

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