feat(asm): split wide arm64 load and store offsets into REGTMP
Offsets the single-instruction forms cannot carry lower the way the toolchain lowers them: ADD or SUB moves the whole distance into REGTMP within the ±4095 band, and the 24-bit band above it splits into an ADD of the high half and an access of the low half, with the pair family taking the two-ADD sequence. The split band follows loadStoreClass per width, byte accesses taking the full 24 bits and the Q width the widest, so an offset the toolchain pools is never split instead. Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
2bd52eb7ad
commit
71e8dd550d
3 files changed
+282
-42
No files matched your search
@@ -719,6 +719,40 @@ func TestArm64QMove(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64OffsetSplit pins the ADD/SUB-into-REGTMP fallbacks against the
|
||||
// toolchain words: the whole-offset form for ±4095 and the 24-bit hi/lo
|
||||
// split for the wide bands, on the MOV and pair families alike.
|
||||
func TestArm64OffsetSplit(t *testing.T) {
|
||||
got := arm64Words(t, "\tMOVD R1, 4094(R2)\n\tMOVD R1, -300(R2)\n\tMOVD R1, 0x1006ff8(R2)\n\tMOVB R1, 4096(R2)\n"+
|
||||
"\tSTP (R3, R4), 11(R0)\n\tSTP (R3, R4), 65536(R2)\n\tLDP -31(R0), (R1, R2)\n")
|
||||
want := []uint32{
|
||||
0x913ff85b, // ADD $4094, R2, R27
|
||||
0xf9000361, // MOVD R1, (R27)
|
||||
0xd104b05b, // SUB $300, R2, R27
|
||||
0xf9000361, // MOVD R1, (R27)
|
||||
0x917ffc5b, // ADD $(4095<<12), R2, R27
|
||||
0xf93fff61, // MOVD R1, 32760(R27)
|
||||
0x9100045b, // ADD $1, R2, R27
|
||||
0x393fff61, // MOVB R1, 4095(R27)
|
||||
0x91002c1b, // ADD $11, R0, R27
|
||||
0xa9001363, // STP (R3, R4), (R27)
|
||||
0x9100005b, // ADD $0, R2, R27
|
||||
0x9140437b, // ADD $(16<<12), R27, R27
|
||||
0xa9001363, // STP (R3, R4), (R27)
|
||||
0xd1007c1b, // SUB $31, R0, R27
|
||||
0xa9400b61, // LDP (R27), (R1, R2)
|
||||
0xd65f03c0,
|
||||
}
|
||||
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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64BTI pins the landing-pad family against the toolchain words:
|
||||
// only the uppercase C/J/JC spellings assemble, and bare BTI is a
|
||||
// diagnostic, never a panic.
|
||||
|
||||
Reference in new issue
Block a user