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:
+13
-2
@@ -507,7 +507,8 @@ func vecReg(op Operand) (Reg, bool) {
|
||||
|
||||
// vecOrMem reports whether op is a vector register or a memory reference.
|
||||
func vecOrMem(op Operand) bool {
|
||||
if _, ok := op.(Mem); ok {
|
||||
switch op.(type) {
|
||||
case Mem, sbMem:
|
||||
return true
|
||||
}
|
||||
r, ok := op.(Reg)
|
||||
@@ -518,7 +519,7 @@ func vecOrMem(op Operand) bool {
|
||||
// acceptable: memory always is, a GPR only for VMOVD/VMOVQ.
|
||||
func validMoveOther(ms vexMoveSpec, op Operand) bool {
|
||||
switch o := op.(type) {
|
||||
case Mem:
|
||||
case Mem, sbMem:
|
||||
return true
|
||||
case Reg:
|
||||
return ms.gprOK && !o.isVec()
|
||||
@@ -533,6 +534,7 @@ func (e *enc) emitVexFields(spec vexSpec, l, regField, rBit, vvvvBar int, rm Ope
|
||||
var modrm, sib int
|
||||
var disp []byte
|
||||
var xBit, bBit int
|
||||
var sb *sbRef
|
||||
switch r := rm.(type) {
|
||||
case Reg:
|
||||
modrm = 0xC0 | regField<<3 | (r.idx & 7)
|
||||
@@ -546,6 +548,12 @@ func (e *enc) emitVexFields(spec vexSpec, l, regField, rBit, vvvvBar int, rm Ope
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case sbMem:
|
||||
// RIP-relative static-symbol reference; disp32 patched at link time.
|
||||
modrm = regField<<3 | 0x05
|
||||
sib = -1
|
||||
disp = le32(0)
|
||||
sb = &sbRef{name: r.name, addend: r.addend}
|
||||
default:
|
||||
return fmt.Errorf("invalid VEX r/m operand")
|
||||
}
|
||||
@@ -561,6 +569,9 @@ func (e *enc) emitVexFields(spec vexSpec, l, regField, rBit, vvvvBar int, rm Ope
|
||||
if sib >= 0 {
|
||||
e.out = append(e.out, byte(sib))
|
||||
}
|
||||
if sb != nil {
|
||||
e.patches = append(e.patches, encPatch{off: len(e.out), name: sb.name, addend: sb.addend})
|
||||
}
|
||||
e.out = append(e.out, disp...)
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user