fix(asm): validate the loong64 ll/sc offset span like the toolchain
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
6cc6165c2b
commit
1040739fbb
3 files changed
+138
-1
No files matched your search
@@ -131,6 +131,98 @@ TEXT ·ptr(SB), NOSPLIT, $0
|
||||
)
|
||||
}
|
||||
|
||||
// TestLOONG64_firr14Spans pins the 2RI14 offset spans of the LL/SC/MOVWP
|
||||
// families against the toolchain's operand classes: an unaligned offset is
|
||||
// rejected ("offset must be a multiple of 4"), a signed 16-bit offset rides
|
||||
// in si14 alone, and anything wider materialises its high half in R30 with
|
||||
// addu16i.d before the base folds in, with si14 keeping bits 15:2. The
|
||||
// pinned words are GOARCH=loong64 go tool asm's own bytes for the same
|
||||
// sources, boundaries included (-32766 and 32766 are the class edges).
|
||||
func TestLOONG64_firr14Spans(t *testing.T) {
|
||||
fn := firstTextLOONG64(t, `#include "textflag.h"
|
||||
TEXT ·spans(SB), NOSPLIT, $0
|
||||
SC R4, 32764(R5)
|
||||
SC R4, -32764(R5)
|
||||
SC R4, 32768(R5)
|
||||
SC R4, -32768(R5)
|
||||
SC R4, -32772(R5)
|
||||
LL 65540(R5), R4
|
||||
LLV 65540(R5), R4
|
||||
SCV R4, 65540(R5)
|
||||
MOVWP R4, 65540(R5)
|
||||
RET
|
||||
`)
|
||||
code := assembleLOONG64Helper(t, fn)
|
||||
wantWords(t, code,
|
||||
0x217FFCA4, // sc.w r4, 8191(r5) — inside si14
|
||||
0x218004A4, // sc.w r4, -8191(r5)
|
||||
0x1000001E, // addu16i.d r30, r0, 0
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x218003C4, // sc.w r4, 8192(r30)
|
||||
0x13FFFC1E, // addu16i.d r30, r0, -1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x218003C4, // sc.w r4, 8192(r30)
|
||||
0x13FFFC1E, // addu16i.d r30, r0, -1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x217FFFC4, // sc.w r4, 8191(r30)
|
||||
0x1000041E, // addu16i.d r30, r0, 1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x200007C4, // ll.w r4, 1(r30)
|
||||
0x1000041E, // addu16i.d r30, r0, 1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x220007C4, // ldptr.d r4, 1(r30)
|
||||
0x1000041E, // addu16i.d r30, r0, 1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x230007C4, // sc.d r4, 1(r30)
|
||||
0x1000041E, // addu16i.d r30, r0, 1
|
||||
0x001097DE, // add.d r30, r30, r5
|
||||
0x250007C4, // stptr.w r4, 1(r30)
|
||||
0x4C000020,
|
||||
)
|
||||
|
||||
// The expansion participates in layout: the function size carries the
|
||||
// six three-word forms plus the single-word pair and the RET.
|
||||
f, errs := parser.Parse("spans_loong64.s", `#include "textflag.h"
|
||||
TEXT ·spans(SB), NOSPLIT, $0
|
||||
SC R4, 32768(R5)
|
||||
LL 65540(R5), R4
|
||||
RET
|
||||
`)
|
||||
if len(errs) > 0 {
|
||||
t.Fatalf("parse: %v", errs)
|
||||
}
|
||||
img, err := AssembleFileLOONG64(f)
|
||||
if err != nil {
|
||||
t.Fatalf("AssembleFileLOONG64: %v", err)
|
||||
}
|
||||
if img.Funcs[0].Size != 8*3+4 {
|
||||
t.Errorf("function size = %d, want %d", img.Funcs[0].Size, 8*3+4)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLOONG64_firr14Alignment checks the LL/SC/MOVWP alignment rule the
|
||||
// toolchain enforces as "offset must be a multiple of 4": the LoongArch
|
||||
// ll/sc family requires a naturally scaled offset, and si14 cannot express
|
||||
// the remainder. GOARCH=loong64 go tool asm rejects every case here.
|
||||
func TestLOONG64_firr14Alignment(t *testing.T) {
|
||||
cases := []string{
|
||||
"SC R4, 1(R5)",
|
||||
"SCW R4, -1(R5)",
|
||||
"SCV R4, 2(R5)",
|
||||
"LL 1(R5), R4",
|
||||
"LLW 3(R5), R4",
|
||||
"LLV 6(R5), R4",
|
||||
"MOVWP R4, 1(R5)",
|
||||
"MOVVP R4, 2(R5)",
|
||||
}
|
||||
for _, src := range cases {
|
||||
fn := firstTextLOONG64(t, "#include \"textflag.h\"\nTEXT ·e(SB), NOSPLIT, $0\n\t"+src+"\n\tRET\n")
|
||||
if _, _, _, _, _, err := assembleLOONG64(fn); err == nil {
|
||||
t.Errorf("%s: expected an error, got none", src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestLOONG64_atomics exercises the AM* read-modify-write forms and
|
||||
// RDTIME, plus the MOVV FP→GP move.
|
||||
func TestLOONG64_atomics(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user