fix(asm): reject the arm64 REGTMP spellings the toolchain refuses

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:49:49 +02:00
1 parent 2385bb7069
commit 7a69be8b59
3 files changed
+88 -14

No files matched your search

+46
View File
@@ -2267,6 +2267,52 @@ func TestArm64NoopVsNop(t *testing.T) {
}
}
// TestArm64RegtmpBoundaries pins the REGTMP acceptance the toolchain holds
// (probed against `go tool asm`, Go 1.27, arm64): the plain imm12 and the
// ±4095 offsets tolerate a REGTMP source or pair member, while every
// lowering that itself writes REGTMP (the constant materialisations, the
// pool path, the pair store expansions) refuses one, and the pool path
// refuses a REGTMP base on both the loads and the stores.
func TestArm64RegtmpBoundaries(t *testing.T) {
accept := []string{
"\tADD\t$5, R27, R3\n", // imm12, no REGTMP sequence
"\tLDP\t700(R2), (R26, R27)\n", // load add/sub path: unchecked pair
"\tMOVD\tR27, 4000(R2)\n", // misaligned ±4095: unchecked data
"\tSTP\t(R26, R3), 700(R2)\n", // store add/sub path, no pair member
"\tLDP\t0x1234567(R2), (R27, R3)\n", // pool load: base alone decides
"\tMOVD\t$0x1000000(R27), R1\n", // lacon: case 34 reads the base
}
reject := []string{
"\tADD\t$0x1234567, R27, R3\n", // materialisation, REGTMP source
"\tAND\t$0x22220000, R27, R4\n", // logical materialisation, ditto
"\tSTP\t(R26, R27), 700(R2)\n", // store add/sub path, pair member
"\tSTP\t(R3, R4), 0x1234567(R27)\n", // pool store, REGTMP base
"\tLDP\t0x1234567(R27), (R3, R4)\n", // pool load, REGTMP base
"\tSTP\t(R27, R3), 0x1234567(R2)\n", // pool store, REGTMP pair member
"\tMOVD\tR27, 0x1234567(R2)\n", // pool store, REGTMP data
"\tMOVD\t0x1234567(R2), R27\n", // pool load, REGTMP data
}
for _, src := range accept {
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 {
t.Errorf("expected acceptance for %q, got parse rejection", strings.TrimSpace(src))
continue
}
if _, err := AssembleFileARM64(f); err != nil {
t.Errorf("expected acceptance for %q, got %v", strings.TrimSpace(src), err)
}
}
for _, src := range reject {
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))
}
}
}
// TestArm64VLDSTPostIndexContract pins the structure-load post-index rules
// against `go tool asm` (Go 1.27, arm64): the implicit by-size increment of
// an unspelled or zero offset (both load and replicate forms, the words