feat(asm): lower the arm64 con(register) form to the ADD chain

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 02:36:24 +02:00
1 parent 9ef14bdb71
commit d786b90fa1
2 files changed
+193 -2

No files matched your search

+62
View File
@@ -1978,3 +1978,65 @@ func TestArm64SimdArrangementRejections(t *testing.T) {
}
}
}
// TestArm64ConRn pins the MOVD $con(Rn), Rd lowering against `go tool asm`
// words: the single ADD/SUB inside the addcon band, the hi<<12 plus lo pair
// in the 24-bit band, and the pool plus UXTX add beyond it.
func TestArm64ConRn(t *testing.T) {
got := arm64Words(t,
"\tMOVD $0x1002(RSP), R1\n"+
"\tMOVD $0x1708(RSP), RSP\n"+
"\tMOVD $0x2001(R7), R1\n"+
"\tMOVD $0xffffff(R7), R1\n"+
"\tMOVD $-1(R7), R1\n"+
"\tMOVD $-0x30(R7), R1\n"+
"\tMOVD $-0x2000(RSP), R1\n"+
"\tMOVD $-0x10000(RSP), RSP\n"+
"\tMOVD $0(R7), R1\n"+
"\tMOVD $4096(R7), R1\n"+
"\tMOVD $5(R3), R1\n")
want := []uint32{
0x914007e1, // ADD $(1<<12), RSP, R1
0x91000821, // ADD $2, R1, R1
0x914007ff, // ADD $(1<<12), RSP, RSP
0x911c23ff, // ADD $0x708, RSP, RSP
0x914008e1, // ADD $(2<<12), R7, R1
0x91000421, // ADD $1, R1, R1
0x917ffce1, // ADD $(4095<<12), R7, R1
0x913ffc21, // ADD $4095, R1, R1
0xd10004e1, // SUB $1, R7, R1
0xd100c0e1, // SUB $0x30, R7, R1
0xd1400be1, // SUB $(2<<12), RSP, R1
0xd14043ff, // SUB $(16<<12), RSP, RSP
0x910000e1, // ADD $0, R7, R1
0x914004e1, // ADD $(1<<12), R7, R1
0x91001461, // ADD $5, R3, R1
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])
}
}
}
// TestArm64ConRnRejections pins the shapes the toolchain refuses for the
// con(register) form: every other width and the ZR destination.
func TestArm64ConRnRejections(t *testing.T) {
for _, src := range []string{
"\tMOVW\t$5(R3), R1\n",
"\tMOVD\t$5(R7), ZR\n",
} {
f, errs := parser.Parse("test_arm64.s", "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n"+src+"\tRET\n")
if len(errs) > 0 {
continue // a parse rejection is a rejection
}
if _, err := AssembleFileARM64(f); err == nil {
t.Errorf("expected rejection for %q, got nil", strings.TrimSpace(src))
}
}
}