feat(asm): pool the arm64 offsets the split bands cannot carry
Offsets beyond the split bands ride a per-function literal pool the way the toolchain lays one out: a PC-relative literal load into REGTMP, then the register-offset access (the pair family adds the base addition), the pooled words appended after the last instruction behind the UNDEF guard, deduplicated by value with the sign- and width-aware load selection. The same differential pass against the corpus exposed three wrong-code bugs and fixes them: the logical-immediate period marker rode the wrong position for every element below 64 bits, so the 32-bit forms encoded a different constant than written; the plain register operand of an ADD/SUB against SP took the shifted-register form where the toolchain uses the extended one with the identity extend, silently truncating through UXTB; and the AUTIA1716 and AUTIB1716 hint constants were the PACIA and PACIB encodings. An offset sweep across every band boundary now pins all three against the live oracle. Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
71e8dd550d
commit
a0fa7e802c
4 files changed
+381
-38
No files matched your search
@@ -167,8 +167,9 @@ func TestArm64Bitmask(t *testing.T) {
|
||||
{2, 1, 1, 63, 0, true}, // single bit at pos 1 (immr = esize-1)
|
||||
{0, 1, 0, 0, 0, false}, // zero is not a bitmask
|
||||
{0xFFFFFFFFFFFFFFFF, 1, 0, 0, 0, false}, // all ones is not a bitmask
|
||||
{0x5555555555555555, 1, 0, 0, 0x3E, true}, // alternating bits (esize=2, ones=1)
|
||||
{0x5555555555555555, 1, 0, 0, 0x3C, true}, // alternating bits (esize=2, ones=1)
|
||||
{0xFFFFFFFF00000000, 1, 1, 32, 31, true}, // upper 32 bits set (esize=64, ones=32)
|
||||
{0x3fffffc0, 0, 0, 26, 23, true}, // 24 ones at bit 6: the 32-bit period marker
|
||||
}
|
||||
for _, tt := range tests {
|
||||
N, immr, imms, ok := arm64Bitmask(tt.v, tt.sf)
|
||||
@@ -630,7 +631,8 @@ func TestArm64ADR(t *testing.T) {
|
||||
func TestArm64PairLoadStore(t *testing.T) {
|
||||
got := arm64Words(t, "\tSTP (R2, R3), 8(R5)\n\tLDP -8(R5), (R2, R3)\n\tLDPW 4(R0), (R1, R2)\n\tSTPW (R1, R2), 4(R0)\n"+
|
||||
"\tFLDPD 8(R0), (F1, F2)\n\tFSTPD (F3, F4), -8(R5)\n"+
|
||||
"\tFLDPQ 16(R0), (F1, F2)\n\tFSTPQ (F1, F2), 16(R0)\n")
|
||||
"\tFLDPQ 16(R0), (F1, F2)\n\tFSTPQ (F1, F2), 16(R0)\n"+
|
||||
"\tFLDPS 4(R0), (F1, F2)\n\tFSTPS (F1, F2), -4(R0)\n")
|
||||
want := []uint32{
|
||||
0xa9008ca2, // STP (R2, R3), 8(R5)
|
||||
0xa97f8ca2, // LDP -8(R5), (R2, R3)
|
||||
@@ -640,6 +642,8 @@ func TestArm64PairLoadStore(t *testing.T) {
|
||||
0x6d3f90a3, // FSTPD (F3, F4), -8(R5)
|
||||
0xad408801, // FLDPQ 16(R0), (F1, F2)
|
||||
0xad008801, // FSTPQ (F1, F2), 16(R0)
|
||||
0x2d408801, // FLDPS 4(R0), (F1, F2)
|
||||
0x2d3f8801, // FSTPS (F1, F2), -4(R0)
|
||||
0xd65f03c0,
|
||||
}
|
||||
if len(got) != len(want) {
|
||||
|
||||
Reference in new issue
Block a user