feat(asm): encode the arm64 SIMD arrangement bits
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
458cdd2066
commit
9ef14bdb71
5 files changed
+407
-133
No files matched your search
@@ -1894,3 +1894,87 @@ func TestArm64RegOffsetRejections(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64SimdArrangementBits pins the arrangement bits the first SIMD pass
|
||||
// got wrong, word-verified against `go tool asm` (Go 1.27, arm64): the FP
|
||||
// one-bit size field (S=0, D=1 at bit 22), the SSHL/USHL size bits, the long
|
||||
// extends' immh field, the narrow family's fixed bit 16, the UADDW size bits
|
||||
// off the narrow side with Q from the spelling, the scalar D forms of the
|
||||
// bare VADD/VSUB spellings and the INS lane packing.
|
||||
func TestArm64SimdArrangementBits(t *testing.T) {
|
||||
got := arm64Words(t,
|
||||
"\tVFADD V0.S4, V0.S4, V1.S4\n"+
|
||||
"\tVFADD V0.D2, V0.D2, V1.D2\n"+
|
||||
"\tVFABS V0.D2, V1.D2\n"+
|
||||
"\tVSCVTF V1.D2, V2.D2\n"+
|
||||
"\tVSSHL V1.B8, V2.B8, V3.B8\n"+
|
||||
"\tVSSHL V1.S4, V2.S4, V3.S4\n"+
|
||||
"\tVUSHL V1.H4, V2.H4, V3.H4\n"+
|
||||
"\tVRBIT V24.B8, V24.B8\n"+
|
||||
"\tVUXTL V30.B8, V30.H8\n"+
|
||||
"\tVUXTL V29.S2, V2.D2\n"+
|
||||
"\tVUXTL2 V30.H8, V30.S4\n"+
|
||||
"\tVXTN V1.H8, V2.B8\n"+
|
||||
"\tVFCVTN V1.D2, V2.S2\n"+
|
||||
"\tVFCVTL V1.S2, V2.D2\n"+
|
||||
"\tVUADDW V13.H4, V10.S4, V11.S4\n"+
|
||||
"\tVUADDW2 V13.H8, V20.S4, V30.S4\n"+
|
||||
"\tVADD V1, V2, V3\n"+
|
||||
"\tVSUB V12, V20, V30\n"+
|
||||
"\tVMOV V12.S[2], V12.S[3]\n"+
|
||||
"\tVMOV V12.H[3], V12.H[5]\n")
|
||||
want := []uint32{
|
||||
0x4e20d401, // VFADD V0.4S: FP size field clear for S
|
||||
0x4e60d401, // VFADD V0.2D: FP size bit 22, not bit 23
|
||||
0x4ee0f801, // VFABS V1.2D: one-bit FP size
|
||||
0x4e61d822, // VSCVTF V2.2D: bit 22, the Q-only mask must not strip it
|
||||
0x0e214443, // VSSHL V3.8B: base without the pre-set size and Q bits
|
||||
0x4ea14443, // VSSHL V3.4S: integer size bits from the arrangement
|
||||
0x2e614443, // VUSHL V3.4H: U bit plus the H size
|
||||
0x2e605b18, // VRBIT V24.8B: no Q bit in the base
|
||||
0x2f08a7de, // VUXTL: immh = 1 at bit 19 for the byte extend
|
||||
0x2f20a7a2, // VUXTL: immh = 4 at bit 21 for the word extend
|
||||
0x6f10a7de, // VUXTL2: immh = 2 plus the 128-bit flag
|
||||
0x0e212822, // VXTN: fixed bit 16 in the base
|
||||
0x0e616822, // VFCVTN: bits 16 and 22, Q rides the spelling
|
||||
0x0e617822, // VFCVTL: bit 22, Q rides the spelling
|
||||
0x2e6d114b, // VUADDW: size bits off the narrow side, Q clear
|
||||
0x6e6d129e, // VUADDW2: size off the narrow side, Q from the spelling
|
||||
0x5ee18443, // VADD scalar D form for the bare spelling
|
||||
0x7eec869e, // VSUB scalar D form for the bare spelling
|
||||
0x6e1c458c, // INS: imm4 = 2<<2 for the word source lane 2
|
||||
0x6e16358c, // INS: imm4 = 3<<1 for the halfword source lane 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64SimdArrangementRejections pins the arrangements the toolchain
|
||||
// refuses on the FP SIMD rows and the element-to-element moves: the
|
||||
// half-width FP spellings, the Q1 spelling on the integer shifts, and the
|
||||
// mixed element letters of INS.
|
||||
func TestArm64SimdArrangementRejections(t *testing.T) {
|
||||
for _, src := range []string{
|
||||
"\tVFADD\tV1.H4, V2.H4, V3.H4\n",
|
||||
"\tVFADD\tV1.H8, V2.H8, V3.H8\n",
|
||||
"\tVFABS\tV1.H4, V2.H4\n",
|
||||
"\tVSCVTF\tV1.H4, V2.H4\n",
|
||||
"\tVSSHL\tV1.Q1, V2.Q1, V3.Q1\n",
|
||||
"\tVMOV\tV12.S[0], V12.D[1]\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