feat(arch): the shift-immediate tsz:imm3 scheme
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
718181e7a7
commit
eda8b16c5f
4 files changed
+555
-2
No files matched your search
@@ -1683,6 +1683,184 @@ func extSveRow(t *testing.T, mnem string, mode uint8, shift int, base, arr ExtAr
|
||||
return ExtInstr{}
|
||||
}
|
||||
|
||||
// TestArm64ExtShiftImmGolden pins the shift-immediate classes against the
|
||||
// toolchain-generated corpus at the metadata layer: the narrowing and
|
||||
// widening three-vector shifts and the predicated saturating left shifts.
|
||||
// Every row is one arm64sveenc.s line and the want word is that line's own
|
||||
// encoding; the amount's tsz:imm3 split is derived in the encoders, right
|
||||
// shifts taking C = 2 x esize - amount over the destination's element size
|
||||
// and left shifts C = esize + amount over the source's (or the
|
||||
// destination's own, in the predicated class).
|
||||
func TestArm64ExtShiftImmGolden(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
mnem string
|
||||
form ExtForm
|
||||
ops []ExtOperand
|
||||
want uint32
|
||||
}{
|
||||
// The narrowing family, one corpus line each over .S+.H.
|
||||
{"ZSHRNB $9, Z7.S, Z23.H", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453710f7},
|
||||
{"ZSHRNT $9, Z7.S, Z23.H", "ZSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453714f7},
|
||||
{"ZRSHRNB $9, Z7.S, Z23.H", "ZRSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453718f7},
|
||||
{"ZRSHRNT $9, Z7.S, Z23.H", "ZRSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x45371cf7},
|
||||
{"ZSQSHRNB $9, Z7.S, Z23.H", "ZSQSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453720f7},
|
||||
{"ZSQSHRNT $9, Z7.S, Z23.H", "ZSQSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453724f7},
|
||||
{"ZSQRSHRNB $9, Z7.S, Z23.H", "ZSQRSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453728f7},
|
||||
{"ZSQRSHRNT $9, Z7.S, Z23.H", "ZSQRSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x45372cf7},
|
||||
{"ZSQSHRUNB $9, Z7.S, Z23.H", "ZSQSHRUNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453700f7},
|
||||
{"ZSQSHRUNT $9, Z7.S, Z23.H", "ZSQSHRUNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453704f7},
|
||||
{"ZUQSHRNB $9, Z7.S, Z23.H", "ZUQSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453730f7},
|
||||
{"ZUQSHRNT $9, Z7.S, Z23.H", "ZUQSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453734f7},
|
||||
{"ZUQRSHRNB $9, Z7.S, Z23.H", "ZUQRSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x453738f7},
|
||||
{"ZUQRSHRNT $9, Z7.S, Z23.H", "ZUQRSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
0x45373cf7},
|
||||
// The width extensions the corpus does not carry: .H+.B and .D+.S,
|
||||
// derived the same way and pinned to the words the fields give.
|
||||
{"ZSHRNB $8, Z6.H, Z22.B", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(8), ExtVector(6, ExtArrH), ExtVector(22, ExtArrB)},
|
||||
0x452810d6},
|
||||
{"ZSQSHRNT $16, Z5.D, Z4.S", "ZSQSHRNT", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(16), ExtVector(5, ExtArrD), ExtVector(4, ExtArrS)},
|
||||
0x457024a4},
|
||||
// The widening family, one corpus line each over .S+.D.
|
||||
{"ZSSHLLB $5, Z22.S, Z10.D", "ZSSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrD)},
|
||||
0x4545a2ca},
|
||||
{"ZSSHLLT $5, Z22.S, Z10.D", "ZSSHLLT", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrD)},
|
||||
0x4545a6ca},
|
||||
{"ZUSHLLB $5, Z22.S, Z10.D", "ZUSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrD)},
|
||||
0x4545aaca},
|
||||
{"ZUSHLLT $5, Z22.S, Z10.D", "ZUSHLLT", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrD)},
|
||||
0x4545aeca},
|
||||
{"ZSSHLLB $0, Z3.B, Z2.H", "ZSSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(0), ExtVector(3, ExtArrB), ExtVector(2, ExtArrH)},
|
||||
0x4508a062},
|
||||
// The predicated saturating left shifts, one corpus line each.
|
||||
{"ZSQSHL $6, Z23.B, P1.M, Z23.B", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
0x040685d7},
|
||||
{"ZSQSHLU $6, Z23.B, P1.M, Z23.B", "ZSQSHLU", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
0x040f85d7},
|
||||
{"ZUQSHL $6, Z23.B, P1.M, Z23.B", "ZUQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
0x040785d7},
|
||||
{"ZSQSHL $20, Z8.S, P4.M, Z8.S", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(20), ExtVector(8, ExtArrS), ExtPredicate(4, ExtQualMerging), ExtVector(8, ExtArrS)},
|
||||
0x04469288},
|
||||
} {
|
||||
in := extInstructionMeta(t, tt.mnem, tt.form, 0, ExtArrNone)
|
||||
got, err := in.Encode(tt.ops)
|
||||
if err != nil {
|
||||
t.Errorf("%s: encode: %v", tt.name, err)
|
||||
continue
|
||||
}
|
||||
if want := hex.EncodeToString(extWordLE(tt.want)); hex.EncodeToString(got) != want {
|
||||
t.Errorf("%s:\n got %x\n want %s", tt.name, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64ExtShiftImmRejects pins the diagnostics the shift-immediate
|
||||
// forms give: the element-step pairs the classes take, the amount ranges
|
||||
// and the read-back and qualifier rules of the predicated class.
|
||||
func TestArm64ExtShiftImmRejects(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
mnem string
|
||||
form ExtForm
|
||||
ops []ExtOperand
|
||||
quote string
|
||||
}{
|
||||
{"source not one step wide", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrD), ExtVector(23, ExtArrH)},
|
||||
"one element step below .D"},
|
||||
{"destination not one step narrow", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrS), ExtVector(23, ExtArrS)},
|
||||
"one element step below"},
|
||||
{"byte source", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(9), ExtVector(7, ExtArrB), ExtVector(23, ExtArrB)},
|
||||
"want .H, .S or .D"},
|
||||
{"amount over the destination element", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(17), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
"outside the range 1..16"},
|
||||
{"amount zero on a right shift", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtImmediate(0), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
"outside the range 1..16"},
|
||||
{"LSL spelling refused", "ZSHRNB", ExtFormShiftImmNarrow,
|
||||
[]ExtOperand{ExtShiftedImmediate(9, 8), ExtVector(7, ExtArrS), ExtVector(23, ExtArrH)},
|
||||
"takes no LSL shift"},
|
||||
{"source not one step narrow", "ZSSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrS)},
|
||||
"one element step above .S"},
|
||||
{"destination not one step wide", "ZSSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(5), ExtVector(22, ExtArrS), ExtVector(10, ExtArrQ)},
|
||||
"one element step above"},
|
||||
{"amount over the source element", "ZSSHLLB", ExtFormShiftImmWide,
|
||||
[]ExtOperand{ExtImmediate(32), ExtVector(22, ExtArrS), ExtVector(10, ExtArrD)},
|
||||
"outside the range 0..31"},
|
||||
{"zeroing qualifier", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualZeroing), ExtVector(23, ExtArrB)},
|
||||
"/M"},
|
||||
{"destination read-back mismatch", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrB)},
|
||||
"the same register Zdn"},
|
||||
{"destination arrangement mismatch", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrH)},
|
||||
"the same register Zdn"},
|
||||
{"quadword has no size encoding", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrQ), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrQ)},
|
||||
"no size encoding"},
|
||||
{"amount over the element size", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(8), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
"outside the range 1..7"},
|
||||
{"amount zero", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(0), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
"outside the range 1..7"},
|
||||
} {
|
||||
in := extInstruction(t, tt.mnem, tt.form)
|
||||
_, err := in.Encode(tt.ops)
|
||||
if err == nil {
|
||||
t.Errorf("%s: encode succeeded, want an error", tt.name)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), tt.quote) {
|
||||
t.Errorf("%s: error %q lacks %q", tt.name, err, tt.quote)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestArm64ExtGatherGolden pins the gather/scatter family against the
|
||||
// toolchain-generated corpus at the metadata layer: one row per addressing
|
||||
// mode, the want word that corpus line's own encoding. The asm-level
|
||||
|
||||
Reference in new issue
Block a user