fix(asm): size the arm64 logical-immediate materialisation exactly

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:49:49 +02:00
1 parent 4ccd3bb4c6
commit 4fc96decc4
2 files changed
+45 -4

No files matched your search

+34
View File
@@ -2070,6 +2070,40 @@ func TestArm64ConRnRejections(t *testing.T) {
}
}
// TestArm64LogicalMaterialisationBranch pins a forward branch over the
// three-word logical materialisation against `go tool asm -S` (Go 1.27,
// arm64): the size pass must count the MOVZ/MOVK pair the encoder lays down,
// or the label offsets desynchronise from the bytes and the branch lands a
// word early.
func TestArm64LogicalMaterialisationBranch(t *testing.T) {
// The body closes with its own RET under the end label, so the file is
// parsed as written rather than through arm64Words' appended RET.
f, errs := parser.Parse("test_arm64.s", "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n\tCBZ\tR2, end\n\tTST\t$0x4900000049, R0\nend:\tRET\n")
if len(errs) > 0 {
t.Fatalf("parse: %v", errs)
}
img, err := AssembleFileARM64(f)
if err != nil {
t.Fatalf("AssembleFileARM64: %v", err)
}
got := leWords(img.Code)
want := []uint32{
0xb4000082, // CBZ R2, +16 (four words ahead)
0xd280093b, // MOVZ $0x49, R27
0xf2c0093b, // MOVK $(0x49<<32), R27
0xea1b001f, // TST R27, R0
0xd65f03c0, // RET
}
if len(got) != len(want) {
t.Fatalf("word count = %d, want %d", len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Errorf("word %d = %08x, want %08x", i, got[i], want[i])
}
}
}
// TestArm64FPImmediate pins the FP immediate moves against `go tool asm`
// words: the FMOV (immediate) instruction for the 8-bit encodable values and
// the FMOV-from-ZR move for zero, plus the rejections the toolchain raises