feat(asm): add VEX shuffle, extract, permute, move and FP forms

Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
2026-07-07 13:57:53 +02:00
parent d5a4a6de45
commit 39870f91f6
9 changed files with 590 additions and 36 deletions
+20 -9
View File
@@ -188,16 +188,27 @@ registers are translated onto the hardware stack pointer — `x+N(FP)` becomes
`(N+8)(SP)` for a zero-frame function and `(N+frame+16)(SP)` once a frame
pointer is set up, with the matching Go prologue/epilogue generated — so the
output is byte-identical to the Go assembler for these cases. SIMD is handled
SIMD is handled
by a VEX (AVX/AVX2) encoder — the two- and three-byte VEX prefixes with XMM/YMM
registers — across three operand forms (the three-operand NDS form, the
two-operand reg/rm form, and the immediate-shift form), together covering the
bulk of the integer SIMD set; each encoding is validated by round-trip
decoding. This increment covers register / memory / immediate / FP-frame
operands, local-label jumps and these VEX SIMD forms; the remaining SIMD forms
(shuffles, extract/insert, permute, moves), EVEX / AVX-512, `SB` (global
symbol) operands (relocations) and object-file emission are the rest of
Phase 2.
registers — across seven operand forms: the three-operand NDS form, the
two-operand reg/rm form, the immediate-shift form, the immediate shuffle form
(`VPSHUFD`, `VPERMQ`), the three-operand-plus-immediate form (`VSHUFPD`,
`VPERM2I128`, `VINSERTI128`), the lane-extract form (`VEXTRACTI128`,
lane-extract form (`VEXTRACTI128`,
`VEXTRACTF128`, where the YMM source occupies the reg field and the XMM or
memory destination r/m), the direction-sensitive moves (`VMOVDQU`, `VMOVUPD`,
`VMOVD`, `VMOVQ`, `VMOVSD`), the floating-point and FMA arithmetic (`VADDPD`,
`VMULPD`, `VXORPD`, `VUNPCKHPD`, the scalar `VADDSD`/`VMULSD`, `VCVTDQ2PD`,
`VFMADD231PD`) and the no-operand `VZEROUPPER` — together with `VPERMD`,
covering every integer, shuffle and FP instruction the go-flac AVX2 kernels
use. Every encoding is validated two ways: by round-trip decoding
through `golang.org/x/arch`, and byte-for-byte against the machine code the
real Go assembler emits (which also locks the v̄vvv = 1111 rule for unused
vvvv fields — a value the hardware rejects with #UD and the decoder silently
ignores). This increment covers register / memory / immediate / FP-frame
operands, local-label jumps and these VEX SIMD forms; EVEX / AVX-512, `SB`
(global symbol) operands (relocations), a handful of scalar gaps the kernels
hit (`CMOVcc`, `SETcc`, `LZCNT`, `MOVSX`/`MOVZX`) and object-file emission
are the rest of Phase 2.
## Extension points