feat(asm): encode the arm64 register-offset addressing forms
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
a344399b81
commit
458cdd2066
4 files changed
+221
-1
No files matched your search
@@ -1825,3 +1825,72 @@ func TestArm64SplitFrameSpadj(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64RegOffsetEncodings pins the register-offset addressing forms of
|
||||
// the MOV family against `go tool asm` words (Go 1.27, arm64): the LSL,
|
||||
// UXTW, SXTW and SXTX options, the shift amount equal to the access size's
|
||||
// log2, and the rejections the toolchain raises for the other spellings.
|
||||
func TestArm64RegOffsetEncodings(t *testing.T) {
|
||||
got := arm64Words(t,
|
||||
"\tMOVD (R2)(R6.SXTW), R4\n"+
|
||||
"\tMOVD (R3)(R6), R5\n"+
|
||||
"\tMOVD (R2)(R6<<3), R4\n"+
|
||||
"\tMOVWU (R5)(R4.UXTW), R10\n"+
|
||||
"\tMOVW (R9)(R8.SXTW<<2), R19\n"+
|
||||
"\tMOVD (R3)(R7.SXTX<<3), R8\n"+
|
||||
"\tMOVBU (R10)(R6), R15\n"+
|
||||
"\tFMOVS (R2)(R6<<2), F4\n"+
|
||||
"\tFMOVD (R2)(R6), F4\n"+
|
||||
"\tMOVD R5, (R2)(R6<<3)\n"+
|
||||
"\tMOVW R7, (R3)(R4.SXTW)\n"+
|
||||
"\tMOVD ZR, (R6)(R7.SXTX<<3)\n")
|
||||
want := []uint32{
|
||||
0xf866c844, // MOVD (R2)(R6.SXTW), R4
|
||||
0xf8666865, // MOVD (R3)(R6), R5
|
||||
0xf8667844, // MOVD (R2)(R6<<3), R4
|
||||
0xb86448aa, // MOVWU (R5)(R4.UXTW), R10
|
||||
0xb8a8d933, // MOVW (R9)(R8.SXTW<<2), R19
|
||||
0xf867f868, // MOVD (R3)(R7.SXTX<<3), R8
|
||||
0x3866694f, // MOVBU (R10)(R6), R15
|
||||
0xbc667844, // FMOVS (R2)(R6<<2), F4
|
||||
0xfc666844, // FMOVD (R2)(R6), F4
|
||||
0xf8267845, // MOVD R5, (R2)(R6<<3)
|
||||
0xb824c867, // MOVW R7, (R3)(R4.SXTW)
|
||||
0xf827f8df, // MOVD ZR, (R6)(R7.SXTX<<3)
|
||||
0xd65f03c0, // RET
|
||||
}
|
||||
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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64RegOffsetRejections pins the spellings the toolchain refuses for
|
||||
// the register-offset addressing: the UXTX/UXTB/SXTH extend names, a shift
|
||||
// amount outside {0, log2(access)}, the scaled *k index, writeback with an
|
||||
// index, and the FMOVQ form the toolchain rejects outright.
|
||||
func TestArm64RegOffsetRejections(t *testing.T) {
|
||||
for _, src := range []string{
|
||||
"\tMOVD\t(R2)(R3.UXTX), R1\n",
|
||||
"\tMOVD\t(R2)(R3.UXTB), R1\n",
|
||||
"\tMOVD\t(R2)(R3.SXTH), R1\n",
|
||||
"\tMOVD\t(R2)(R3<<1), R1\n",
|
||||
"\tMOVD\t(R2)(R3<<2), R1\n",
|
||||
"\tMOVBU\t(R1)(R2<<1), R3\n",
|
||||
"\tMOVD\t(R2)(R3*8), R1\n",
|
||||
"\tMOVD.P\tR5, (R2)(R3)\n",
|
||||
"\tFMOVQ\t(R2)(R6), F4\n",
|
||||
} {
|
||||
f, errs := parser.Parse("test_arm64.s", "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n"+src+"\tRET\n")
|
||||
if len(errs) > 0 {
|
||||
continue // a parse rejection is a rejection
|
||||
}
|
||||
if _, err := AssembleFileARM64(f); err == nil {
|
||||
t.Errorf("expected rejection for %q, got nil", strings.TrimSpace(src))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user