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:
petrbalvin committed 2026-10-07 02:36:24 +02:00
1 parent 71e8dd550d
commit a0fa7e802c
4 files changed
+381 -38

No files matched your search

+6 -2
View File
@@ -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) {