feat(asm): take the loong64 register-pair spellings the toolchain parses

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin authored and Petr Balvín committed 2026-10-07 21:42:14 +02:00
1 parent 1031cd9ae7
commit a3eaa82f87
5 files changed
+237 -18

No files matched your search

+56
View File
@@ -215,6 +215,62 @@ func TestLoong64ForeignErrorParity(t *testing.T) {
// and the pair of rejections is the parity this catalogue asserts.
var loong64RejectedNames = []string{"RFE", "DUFFCOPY", "DUFFZERO", "PCALIGNMAX"}
// loong64PairErrorShapes walks the register-pair sugar's negative shapes,
// every one measured against GOARCH=loong64 go tool asm. want carries the
// toolchain's diagnostic where gasm's wording matches it (checked through
// the same equivalence as the catalogue above); an empty want pins the
// rejection alone, and the row's comment records the toolchain's own words
// for the divergence.
var loong64PairErrorShapes = []struct {
body string
want string
}{
// A pair never splits inside an address; the toolchain's parse stage
// refuses it outright.
{"MULV (R4:R5), R6", "indirect through register pair"},
// The reordered list fails the instruction's operand shape. The
// toolchain words these "illegal combination ..." at the class match;
// gasm words them at the operand count.
{"MOVV R4:R5, R6", ""},
{"BEQ R4:R5, R6", ""},
{"JMP R4:R5", ""},
{"MULV R4:R5, R7:R8, R6", ""},
{"MULV R4:R5, (R6)", ""},
{"BEQ R4:R5, 2(PC)", ""},
// A right half outside the register table; the toolchain's parse stage
// again ("illegal or missing addressing mode for symbol label").
{"MULV R4:label", "illegal or missing addressing mode for symbol label"},
// An immediate half on either side. The toolchain reorders the pair
// first and rejects at the class match ("illegal combination MULV
// U3CON ...", "MULV: expected register; found $4"); gasm rejects the
// shape without the reorder.
{"MOVV $4:R5", ""},
{"MULV R4:$5", ""},
}
// TestLoong64PairErrorParity requires gasm to refuse every register-pair
// spelling the toolchain refuses, with an equivalent diagnostic where the
// row carries one. The toolchain's accept side of the sugar is pinned
// byte for byte by TestLOONG64PairSugar; the empty-want rows are documented
// wording divergences, not acceptance divergences.
func TestLoong64PairErrorParity(t *testing.T) {
for _, tt := range loong64PairErrorShapes {
src := "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n\t" + tt.body + "\n\tRET\n"
f, perr := parser.Parse("pairparity.s", src)
if len(perr) > 0 {
continue // the parser already rejects the spelling
}
_, aerr := AssembleFileLOONG64(f)
if aerr == nil {
t.Errorf("gasm accepts what the toolchain rejects: %s", tt.body)
continue
}
if tt.want != "" && !loong64DiagEquivalent(tt.want, aerr.Error()) {
t.Errorf("gasm rejects %s with an inequivalent diagnostic:\n toolchain: %s\n gasm: %s", tt.body, tt.want, aerr)
}
}
}
// TestLoong64BacklogNameParity walks the audit's known-but-unencodable
// backlog: the names go tool asm recognises on loong64 yet refuses to
// encode must be refused by gasm as well, and the one name the audit