mirror of
https://github.com/odin-lang/Odin.git
synced 2026-09-02 10:13:35 +00:00
NEON reuses one operand shape across every element width, so `vadd.i8` and `vadd.f32` are both DPR,DPR,DPR and only the type separates their encodings. The type existed nowhere in the data: the encoder could reach the first form of a shape and no other, and the printer reconstructed a suffix from the bit pattern at print time. 489 of 1680 forms -- 29% of the table -- were unreachable, and `inst_vadd(d0,d1,d2)` could only ever produce VFP vadd.f64. Add `Data_Type` and carry `dt: [2]Data_Type` on Instruction, Encoding and Decode_Entry. Two slots because the convert family names both ends (`vcvt.s32.f32`); everything else leaves the second .NONE. In A64 the arrangement belongs to each operand (`add v0.4s, v1.4s, v2.4s`); in A32 it belongs to the instruction, which is why it goes here and not on Operand. Instruction does not grow: it lands in bytes that were already padding, so 88 stays 88. Encoding and Decode_Entry go 21 -> 23, which is +3,360 B per table, +6.7 KB in all. The per-form type is derived from llvm-mc rather than hand-written: assemble each form's canonical word, disassemble it, take the suffix. 942 forms carry one, 38 carry two. (`.w` is the Thumb wide qualifier, not a type, and is excluded.) Effect: of 202 shape groups holding more than one form, 168 are now separated by the type -- 429 of the 489 unreachable forms become selectable. `dt` left at .NONE means "unspecified" and still takes the first matching form, so every existing caller behaves exactly as before. It also fixes printing. The old inference could only ever produce one type, so the whole convert family printed `vcvt.f32` -- 13 forms sharing one string that no assembler accepts. They now print `vcvt.f32.s32`, `vcvt.f64.f32`, `vcvta.u32.f64`, and so on. Verified: vadd.i8/i16/i32/i64/f32 encode to f2010802 / f2110802 / f2210802 / f2310802 / f2010d02, matching llvm-mc exactly; all 11 rexcode suites are identical to baseline. Still unreachable, 60 forms in 34 groups: register lists (VLD2-4/VST2-4), LDM/STM addressing modes, and a few lane-indexed and fixed-point convert forms whose element size is not captured by the type alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>