fix(asm): enforce the arm64 TLBI, RPRFM, FCVT and integer-pair arities

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:49:49 +02:00
1 parent 7a69be8b59
commit 33e7fdac98
4 files changed
+140 -33

No files matched your search

+50
View File
@@ -2363,6 +2363,56 @@ func TestArm64VLDSTPostIndexContract(t *testing.T) {
}
}
// TestArm64OperandArities pins the operand-shape rules the error corpus
// drove home: the TLBI register arity follows the operation, RPRFM's second
// operand is a plain register, the FCVT conversions are pinned to their one
// width pair, and the integer pairs take integer registers alone.
func TestArm64OperandArities(t *testing.T) {
accept := []string{
"\tTLBI\tVAE1, R1\n",
"\tTLBI\tVMALLE1IS\n",
"\tTLBI\tALLE3OS\n",
"\tRPRFM\t(R1), R2, PLDKEEP\n",
"\tRPRFM\t(R1), R27, PLDKEEP\n",
"\tVFCVTL\tV1.S2, V2.D2\n",
"\tVFCVTL2\tV1.S4, V2.D2\n",
"\tVFCVTN\tV1.D2, V2.S2\n",
"\tVFCVTN2\tV1.D2, V2.S4\n",
"\tLDP\t(R0), (R0, R1)\n",
}
reject := []string{
"\tTLBI\tVMALLE1IS, R0\n", // whole-entry op: extraneous register
"\tTLBI\tALLE3OS, ZR\n", // ditto, the ZR spelling included
"\tTLBI\tVAE1IS\n", // by-address op: missing register
"\tTLBI\tRVALE3\n", // ditto
"\tRPRFM\t(R1), RSP, PLDKEEP\n",
"\tRPRFM\t(R1), ZR, PLDKEEP\n",
"\tVFCVTL\tV1.H4, V2.S4\n", // no half-precision conversion
"\tVFCVTN\tV1.D2, V2.H4\n", // ditto on the narrowing side
"\tLDP\t(R0), (F0, F1)\n", // FP pair on the integer mnemonic
"\tSTP\t(F2, F3), (R0)\n", // ditto
}
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))
}
}
}
// 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