feat(asm): assemble static symbols and the whole go-flac AVX2 kernel byte-identically

Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
2026-07-09 15:56:03 +02:00
parent a82f575aee
commit 56ecc39539
10 changed files with 553 additions and 54 deletions
+28 -1
View File
@@ -19,7 +19,16 @@ func Encode(mnemonic string, ops ...Operand) ([]byte, error) {
}
type enc struct {
out []byte
out []byte
patches []encPatch // disp32 fields awaiting static-symbol resolution
}
// encPatch marks a 4-byte displacement field in enc.out that must receive the
// RIP-relative offset of a static symbol once the file layout is settled.
type encPatch struct {
off int
name string
addend int64
}
func (e *enc) encode(mnem string, ops []Operand) error {
@@ -120,6 +129,14 @@ type instr struct {
sib int // -1 if absent
disp []byte
imm []byte
sb *sbRef // static-symbol displacement in disp, awaiting resolution
}
// sbRef records that an instruction's displacement refers to a static symbol
// rather than holding a literal value.
type sbRef struct {
name string
addend int64
}
func (e *enc) emit(i *instr) error {
@@ -152,6 +169,9 @@ func (e *enc) emit(i *instr) error {
if i.sib >= 0 {
e.out = append(e.out, byte(i.sib))
}
if i.sb != nil {
e.patches = append(e.patches, encPatch{off: len(e.out), name: i.sb.name, addend: i.sb.addend})
}
e.out = append(e.out, i.disp...)
e.out = append(e.out, i.imm...)
return nil
@@ -199,6 +219,13 @@ func setRMReg(i *instr, regField int, rexR, regForced bool, rm Operand, opSize i
return nil
case Mem:
return setMem(i, regField, r)
case sbMem:
// RIP-relative reference; the displacement is patched once the static
// symbol's address is known.
i.modrm = regField<<3 | 0x05 // mod=00, rm=101 → (RIP)+disp32
i.disp = le32(0)
i.sb = &sbRef{name: r.name, addend: r.addend}
return nil
default:
return fmt.Errorf("invalid r/m operand %T", rm)
}