feat(asm): byte-identical go-flac AVX2 assembly with scalar families and jump relaxation
Assisted-by: Qwen 3.8 Max Preview
This commit is contained in:
@@ -244,3 +244,76 @@ TEXT ·hsum(SB), NOSPLIT, $0
|
||||
t.Errorf("VEX kernel mismatch:\n got: %s\n want: %s", hexBytes(code), hexBytes(want))
|
||||
}
|
||||
}
|
||||
|
||||
// TestAssembleShortJumps checks that a tight loop settles on the short (rel8)
|
||||
// jump forms, byte for byte with the Go assembler.
|
||||
func TestAssembleShortJumps(t *testing.T) {
|
||||
fn := firstText(t, `
|
||||
#include "textflag.h"
|
||||
TEXT ·loop(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
l1:
|
||||
ADDQ $1, AX
|
||||
CMPQ AX, $10
|
||||
JLT l1
|
||||
RET
|
||||
`)
|
||||
code, _, err := Assemble(fn)
|
||||
if err != nil {
|
||||
t.Fatalf("Assemble: %v", err)
|
||||
}
|
||||
// From the Go-assembled function:
|
||||
// XORQ AX, AX 4831c0
|
||||
// ADDQ $1, AX 4883c001
|
||||
// CMPQ AX, $10 4883f80a
|
||||
// JLT l1 7cf6 (short, rel8)
|
||||
// RET c3
|
||||
want := []byte{
|
||||
0x48, 0x31, 0xc0,
|
||||
0x48, 0x83, 0xc0, 0x01,
|
||||
0x48, 0x83, 0xf8, 0x0a,
|
||||
0x7c, 0xf6,
|
||||
0xc3,
|
||||
}
|
||||
if hexBytes(code) != hexBytes(want) {
|
||||
t.Errorf("short-jump mismatch:\n got: %s\n want: %s", hexBytes(code), hexBytes(want))
|
||||
}
|
||||
}
|
||||
|
||||
// TestAssembleJumpFolding checks jump-to-jump folding: a conditional jump to a
|
||||
// label that only holds an unconditional jump is redirected to the ultimate
|
||||
// target, exactly as the Go toolchain does before it encodes branches.
|
||||
func TestAssembleJumpFolding(t *testing.T) {
|
||||
fn := firstText(t, `
|
||||
#include "textflag.h"
|
||||
TEXT ·fold(SB), NOSPLIT, $0
|
||||
XORQ AX, AX
|
||||
JGE done
|
||||
INCQ AX
|
||||
done:
|
||||
JMP end
|
||||
end:
|
||||
RET
|
||||
`)
|
||||
code, _, err := Assemble(fn)
|
||||
if err != nil {
|
||||
t.Fatalf("Assemble: %v", err)
|
||||
}
|
||||
// From the Go-assembled function: the JGE skips past the done: trampoline
|
||||
// straight to end:
|
||||
// XORQ AX, AX 4831c0
|
||||
// JGE end 7d05 (folded past done)
|
||||
// INCQ AX 48ffc0
|
||||
// JMP end eb00
|
||||
// RET c3
|
||||
want := []byte{
|
||||
0x48, 0x31, 0xc0,
|
||||
0x7d, 0x05,
|
||||
0x48, 0xff, 0xc0,
|
||||
0xeb, 0x00,
|
||||
0xc3,
|
||||
}
|
||||
if hexBytes(code) != hexBytes(want) {
|
||||
t.Errorf("jump-folding mismatch:\n got: %s\n want: %s", hexBytes(code), hexBytes(want))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user