feat(arch): the same-size shift-immediate family
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
eda8b16c5f
commit
1031cd9ae7
4 files changed
+234
-13
No files matched your search
+164
-11
@@ -785,6 +785,28 @@ const (
|
||||
// source's element size, split like the narrowing class; the amount
|
||||
// runs 0..esize-1.
|
||||
ExtFormShiftImmWide
|
||||
// ExtFormShiftImmSame is the same-size shift by immediate, ZSRI $6,
|
||||
// Z7.D, Z23.D and its accumulating siblings ZSSRA, ZUSRA, ZSRSRA and
|
||||
// ZURSRA: a right shift within one shared arrangement, the
|
||||
// destination (or the read-modify-write accumulator) in the
|
||||
// destination slot. Operands: imm, Zn.T, Zd.T. C = 2 x esize -
|
||||
// amount over the shared element size, split imm3 into bits 18..16,
|
||||
// the low tsz pair into bits 20..19 and the top tsz pair into bits
|
||||
// 23..22; the amount runs 1..esize-1.
|
||||
ExtFormShiftImmSame
|
||||
// ExtFormShiftImmPredRight is the predicated right shift by
|
||||
// immediate, ZASR $6, Z23.B, P1.M, Z23.B and ZASRD beside it: the
|
||||
// right-shift counterpart of the predicated left shifts. Operands:
|
||||
// imm, Zdn.T, Pg/M, Zdn.T. C = 2 x esize - amount over the
|
||||
// destination's element size, split like the predicated left shifts;
|
||||
// the amount runs 1..esize-1.
|
||||
ExtFormShiftImmPredRight
|
||||
// ExtFormShiftImmXar is the three-source extract and narrow, ZXAR
|
||||
// $6, Z23.B, Z21.B, Z21.B: the destination is spelled twice and
|
||||
// encoded once. Operands: imm, Zm.T, Zdn.T, Zdn.T. C = 2 x esize -
|
||||
// amount over the shared element size, split like the same-size
|
||||
// class; the amount runs 1..esize-1.
|
||||
ExtFormShiftImmXar
|
||||
)
|
||||
|
||||
// Arity returns the operand count the form takes.
|
||||
@@ -823,9 +845,9 @@ func (f ExtForm) Arity() int {
|
||||
return 2
|
||||
case ExtFormCountPnVec:
|
||||
return 2
|
||||
case ExtFormShiftImmPred:
|
||||
case ExtFormShiftImmPred, ExtFormShiftImmPredRight, ExtFormShiftImmXar:
|
||||
return 4
|
||||
case ExtFormShiftImmNarrow, ExtFormShiftImmWide:
|
||||
case ExtFormShiftImmNarrow, ExtFormShiftImmWide, ExtFormShiftImmSame:
|
||||
return 3
|
||||
case ExtFormReduceReadBack:
|
||||
return 4
|
||||
@@ -895,9 +917,9 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
||||
return []ExtOperandKind{ExtPReg, ExtGReg}
|
||||
case ExtFormCountPnVec:
|
||||
return []ExtOperandKind{ExtPReg, ExtZReg}
|
||||
case ExtFormShiftImmPred:
|
||||
case ExtFormShiftImmPred, ExtFormShiftImmPredRight, ExtFormShiftImmXar:
|
||||
return []ExtOperandKind{ExtImm, ExtZReg, ExtPReg, ExtZReg}
|
||||
case ExtFormShiftImmNarrow, ExtFormShiftImmWide:
|
||||
case ExtFormShiftImmNarrow, ExtFormShiftImmWide, ExtFormShiftImmSame:
|
||||
return []ExtOperandKind{ExtImm, ExtZReg, ExtZReg}
|
||||
case ExtFormCountPnW:
|
||||
return []ExtOperandKind{ExtGReg, ExtPReg, ExtGReg}
|
||||
@@ -1041,6 +1063,12 @@ func (f ExtForm) String() string {
|
||||
return "narrowing shift by immediate"
|
||||
case ExtFormShiftImmWide:
|
||||
return "widening shift by immediate"
|
||||
case ExtFormShiftImmSame:
|
||||
return "same-size shift by immediate"
|
||||
case ExtFormShiftImmPredRight:
|
||||
return "predicated right shift by immediate"
|
||||
case ExtFormShiftImmXar:
|
||||
return "three-source extract and narrow"
|
||||
case ExtFormCountPnW:
|
||||
return "counter step to a register"
|
||||
case ExtFormReduce:
|
||||
@@ -1319,10 +1347,16 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeCountPnVec(ops)
|
||||
case ExtFormShiftImmPred:
|
||||
return in.encodeShiftImmPred(ops)
|
||||
case ExtFormShiftImmPredRight:
|
||||
return in.encodeShiftImmPredRight(ops)
|
||||
case ExtFormShiftImmNarrow:
|
||||
return in.encodeShiftImmNarrow(ops)
|
||||
case ExtFormShiftImmWide:
|
||||
return in.encodeShiftImmWide(ops)
|
||||
case ExtFormShiftImmSame:
|
||||
return in.encodeShiftImmSame(ops)
|
||||
case ExtFormShiftImmXar:
|
||||
return in.encodeShiftImmXar(ops)
|
||||
case ExtFormCountPnW:
|
||||
return in.encodeCountPnW(ops)
|
||||
case ExtFormReduce:
|
||||
@@ -2474,13 +2508,25 @@ func (in ExtInstr) shiftImmAmount(op ExtOperand, position, lo, hi int) (int, err
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// encodeShiftImmPred fills the predicated shift by immediate: imm, Zdn.T,
|
||||
// Pg/M, Zdn.T, the destination spelled twice and encoded once. The amount
|
||||
// rides the class's tsz:imm3 fields: C = esize + amount, split imm3 into
|
||||
// bits 7..5, the low tsz pair into bits 9..8 and the top tsz pair into
|
||||
// bits 23..22, where the tsz bits spell the arrangement and stand in for
|
||||
// the size field the class does not carry.
|
||||
// encodeShiftImmPred fills the predicated left shift by immediate: imm,
|
||||
// Zdn.T, Pg/M, Zdn.T, the destination spelled twice and encoded once.
|
||||
func (in ExtInstr) encodeShiftImmPred(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeShiftImmPredC(ops, func(esize, v int) int { return esize + v })
|
||||
}
|
||||
|
||||
// encodeShiftImmPredRight fills the predicated right shift by immediate,
|
||||
// the right-shift counterpart of the predicated left shifts.
|
||||
func (in ExtInstr) encodeShiftImmPredRight(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeShiftImmPredC(ops, func(esize, v int) int { return 2*esize - v })
|
||||
}
|
||||
|
||||
// encodeShiftImmPredC carries the predicated shift-by-immediate layout the
|
||||
// left and right shifts share: the amount rides the class's tsz:imm3
|
||||
// fields, C = dir(esize, amount), split imm3 into bits 7..5, the low tsz
|
||||
// pair into bits 9..8 and the top tsz pair into bits 23..22, where the tsz
|
||||
// bits spell the arrangement and stand in for the size field the class
|
||||
// does not carry.
|
||||
func (in ExtInstr) encodeShiftImmPredC(ops []ExtOperand, dir func(esize, v int) int) ([]byte, error) {
|
||||
imm, zdn, pg, zdn2 := ops[0], ops[1], ops[2], ops[3]
|
||||
if err := in.zVector(zdn, 2); err != nil {
|
||||
return nil, err
|
||||
@@ -2508,7 +2554,7 @@ func (in ExtInstr) encodeShiftImmPred(ops []ExtOperand) ([]byte, error) {
|
||||
return nil, fmt.Errorf("%s: operands 2 and 4 are the same register Zdn, got Z%d and Z%d",
|
||||
in.Name, zdn.Reg, zdn2.Reg)
|
||||
}
|
||||
c := esize + v
|
||||
c := dir(esize, v)
|
||||
word := in.Word
|
||||
word = extSet(word, extFieldImm3T5, uint32(c))
|
||||
word = extSet(word, extFieldTszM8, uint32(c>>3))
|
||||
@@ -2518,6 +2564,86 @@ func (in ExtInstr) encodeShiftImmPred(ops []ExtOperand) ([]byte, error) {
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// setShiftImmTsz16 ORs the three-vector tsz:imm3 chunks of c into the
|
||||
// word: imm3 into bits 18..16, the low tsz pair into bits 20..19 and the
|
||||
// top tsz pair into bits 23..22.
|
||||
func setShiftImmTsz16(word uint32, c int) uint32 {
|
||||
word = extSet(word, extFieldImm3T16, uint32(c))
|
||||
word = extSet(word, extFieldTszM19, uint32(c>>3))
|
||||
word = extSet(word, extFieldTszH22W, uint32(c>>5))
|
||||
return word
|
||||
}
|
||||
|
||||
// encodeShiftImmSame fills the same-size shift by immediate: imm, Zn.T,
|
||||
// Zd.T, a right shift within one shared arrangement, the destination (or
|
||||
// the read-modify-write accumulator) in the destination slot. C = 2 x
|
||||
// esize - amount over the shared element size.
|
||||
func (in ExtInstr) encodeShiftImmSame(ops []ExtOperand) ([]byte, error) {
|
||||
imm, zn, zd := ops[0], ops[1], ops[2]
|
||||
if err := in.zVector(zn, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := zn.Arr.sizeBits(); !ok {
|
||||
return nil, fmt.Errorf("%s: arrangement %s has no size encoding in this class",
|
||||
in.Name, zn.Arr)
|
||||
}
|
||||
if err := in.zVector(zd, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zd.Arr != zn.Arr {
|
||||
return nil, fmt.Errorf("%s: operands 2 and 3 carry arrangements %s and %s, they must match",
|
||||
in.Name, zn.Arr, zd.Arr)
|
||||
}
|
||||
esize := zn.Arr.elemBits()
|
||||
v, err := in.shiftImmAmount(imm, 1, 1, esize-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := 2*esize - v
|
||||
word := setShiftImmTsz16(in.Word, c)
|
||||
word = extSet(word, extFieldRn, uint32(zn.Reg))
|
||||
word = extSet(word, extFieldRd, uint32(zd.Reg))
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeShiftImmXar fills the three-source extract and narrow: imm, Zm.T,
|
||||
// Zdn.T, Zdn.T, the destination spelled twice and encoded once. C = 2 x
|
||||
// esize - amount over the shared element size.
|
||||
func (in ExtInstr) encodeShiftImmXar(ops []ExtOperand) ([]byte, error) {
|
||||
imm, zm, zdn, zdn2 := ops[0], ops[1], ops[2], ops[3]
|
||||
if err := in.zVector(zm, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := zm.Arr.sizeBits(); !ok {
|
||||
return nil, fmt.Errorf("%s: arrangement %s has no size encoding in this class",
|
||||
in.Name, zm.Arr)
|
||||
}
|
||||
if err := in.zVector(zdn, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.zVector(zdn2, 4); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zdn2.Reg != zdn.Reg || zdn2.Arr != zdn.Arr {
|
||||
return nil, fmt.Errorf("%s: operands 3 and 4 are the same register Zdn, got Z%d and Z%d",
|
||||
in.Name, zdn.Reg, zdn2.Reg)
|
||||
}
|
||||
if zdn.Arr != zm.Arr {
|
||||
return nil, fmt.Errorf("%s: operands 2 and 3 carry arrangements %s and %s, they must match",
|
||||
in.Name, zm.Arr, zdn.Arr)
|
||||
}
|
||||
esize := zm.Arr.elemBits()
|
||||
v, err := in.shiftImmAmount(imm, 1, 1, esize-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := 2*esize - v
|
||||
word := setShiftImmTsz16(in.Word, c)
|
||||
word = extSet(word, extFieldRn, uint32(zm.Reg))
|
||||
word = extSet(word, extFieldRd, uint32(zdn.Reg))
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeShiftImmNarrow fills the three-vector narrowing shift by immediate:
|
||||
// imm, Zn.Tb, Zd.T, a right shift of the wide source whose result the
|
||||
// destination one element step down keeps (.H+.B, .S+.H, .D+.S). The
|
||||
@@ -5123,6 +5249,33 @@ var arm64Extensions = []ExtInstr{
|
||||
{Name: "ZUQSHL", Summary: "Saturating unsigned shift left by immediate, over a governing predicate",
|
||||
Word: 0x04078000, Form: ExtFormShiftImmPred, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: UQSHL (immediate, predicated); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZSRI", Summary: "Shift right and insert by immediate",
|
||||
Word: 0x4500f000, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: SRI (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZASR", Summary: "Arithmetic shift right by immediate",
|
||||
Word: 0x04209000, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ASR (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZSSRA", Summary: "Signed shift right and accumulate by immediate",
|
||||
Word: 0x4500e000, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: SSRA (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZUSRA", Summary: "Unsigned shift right and accumulate by immediate",
|
||||
Word: 0x4500e400, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: USRA (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZSRSRA", Summary: "Signed rounding shift right and accumulate by immediate",
|
||||
Word: 0x4500e800, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: SRSRA (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZURSRA", Summary: "Unsigned rounding shift right and accumulate by immediate",
|
||||
Word: 0x4500ec00, Form: ExtFormShiftImmSame, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: URSRA (immediate); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZASR", Summary: "Arithmetic shift right by immediate, over a governing predicate",
|
||||
Word: 0x04008000, Form: ExtFormShiftImmPredRight, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ASR (immediate, predicated); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZASRD", Summary: "Arithmetic shift right by immediate, rounding, over a governing predicate",
|
||||
Word: 0x04048000, Form: ExtFormShiftImmPredRight, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ASRD (immediate, predicated); inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZXAR", Summary: "Extract and narrow by immediate from three sources",
|
||||
Word: 0x04203400, Form: ExtFormShiftImmXar, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: XAR; inst_gen.go + arm64sveenc.s"},
|
||||
}
|
||||
|
||||
// Extensions returns the extended-instruction layer registered for a, outside
|
||||
|
||||
@@ -1779,6 +1779,34 @@ func TestArm64ExtShiftImmGolden(t *testing.T) {
|
||||
{"ZSQSHL $20, Z8.S, P4.M, Z8.S", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(20), ExtVector(8, ExtArrS), ExtPredicate(4, ExtQualMerging), ExtVector(8, ExtArrS)},
|
||||
0x04469288},
|
||||
// The same-size right shifts, the accumulator and the extract.
|
||||
{"ZSRI $6, Z7.D, Z23.D", "ZSRI", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x45daf0f7},
|
||||
{"ZSSRA $6, Z7.D, Z23.D", "ZSSRA", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x45dae0f7},
|
||||
{"ZUSRA $6, Z7.D, Z23.D", "ZUSRA", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x45dae4f7},
|
||||
{"ZSRSRA $6, Z7.D, Z23.D", "ZSRSRA", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x45dae8f7},
|
||||
{"ZURSRA $6, Z7.D, Z23.D", "ZURSRA", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x45daecf7},
|
||||
{"ZASR $6, Z7.D, Z23.D", "ZASR", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
0x04fa90f7},
|
||||
{"ZASR $6, Z23.B, P1.M, Z23.B", "ZASR", ExtFormShiftImmPredRight,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
0x04008557},
|
||||
{"ZASRD $6, Z23.B, P1.M, Z23.B", "ZASRD", ExtFormShiftImmPredRight,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
0x04048557},
|
||||
{"ZXAR $6, Z23.B, Z21.B, Z21.B", "ZXAR", ExtFormShiftImmXar,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtVector(21, ExtArrB), ExtVector(21, ExtArrB)},
|
||||
0x042a36f5},
|
||||
} {
|
||||
in := extInstructionMeta(t, tt.mnem, tt.form, 0, ExtArrNone)
|
||||
got, err := in.Encode(tt.ops)
|
||||
@@ -1848,6 +1876,24 @@ func TestArm64ExtShiftImmRejects(t *testing.T) {
|
||||
{"amount zero", "ZSQSHL", ExtFormShiftImmPred,
|
||||
[]ExtOperand{ExtImmediate(0), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
"outside the range 1..7"},
|
||||
{"same-size arrangements differ", "ZSRI", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrB), ExtVector(23, ExtArrH)},
|
||||
"must match"},
|
||||
{"same-size amount zero", "ZSRI", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(0), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
"outside the range 1..63"},
|
||||
{"same-size amount at the element size", "ZSRI", ExtFormShiftImmSame,
|
||||
[]ExtOperand{ExtImmediate(64), ExtVector(7, ExtArrD), ExtVector(23, ExtArrD)},
|
||||
"outside the range 1..63"},
|
||||
{"predicated right amount at the element size", "ZASR", ExtFormShiftImmPredRight,
|
||||
[]ExtOperand{ExtImmediate(8), ExtVector(23, ExtArrB), ExtPredicate(1, ExtQualMerging), ExtVector(23, ExtArrB)},
|
||||
"outside the range 1..7"},
|
||||
{"extract read-back mismatch", "ZXAR", ExtFormShiftImmXar,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtVector(21, ExtArrB), ExtVector(20, ExtArrB)},
|
||||
"the same register Zdn"},
|
||||
{"extract arrangements differ", "ZXAR", ExtFormShiftImmXar,
|
||||
[]ExtOperand{ExtImmediate(6), ExtVector(23, ExtArrB), ExtVector(21, ExtArrH), ExtVector(21, ExtArrH)},
|
||||
"must match"},
|
||||
} {
|
||||
in := extInstruction(t, tt.mnem, tt.form)
|
||||
_, err := in.Encode(tt.ops)
|
||||
|
||||
@@ -994,6 +994,16 @@ func TestArm64AssembleExtensionShiftImmGolden(t *testing.T) {
|
||||
{"ZSQSHRNT $16, Z5.D, Z4.S", 0x457024a4},
|
||||
{"ZSSHLLB $0, Z3.B, Z2.H", 0x4508a062},
|
||||
{"ZSQSHL $20, Z8.S, P4.M, Z8.S", 0x04469288},
|
||||
// The same-size right shifts, the accumulator and the extract.
|
||||
{"ZSRI $6, Z7.D, Z23.D", 0x45daf0f7},
|
||||
{"ZSSRA $6, Z7.D, Z23.D", 0x45dae0f7},
|
||||
{"ZUSRA $6, Z7.D, Z23.D", 0x45dae4f7},
|
||||
{"ZSRSRA $6, Z7.D, Z23.D", 0x45dae8f7},
|
||||
{"ZURSRA $6, Z7.D, Z23.D", 0x45daecf7},
|
||||
{"ZASR $6, Z7.D, Z23.D", 0x04fa90f7},
|
||||
{"ZASR $6, Z23.B, P1.M, Z23.B", 0x04008557},
|
||||
{"ZASRD $6, Z23.B, P1.M, Z23.B", 0x04048557},
|
||||
{"ZXAR $6, Z23.B, Z21.B, Z21.B", 0x042a36f5},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||
@@ -1029,6 +1039,11 @@ func TestArm64AssembleExtensionShiftImmRefusals(t *testing.T) {
|
||||
{"ZSQSHL $6, Z23.B, P1.M, Z22.B", "the same register Zdn"},
|
||||
{"ZSQSHL $6, Z23.Q, P1.M, Z23.Q", "no size encoding"},
|
||||
{"ZSQSHL $8, Z23.B, P1.M, Z23.B", "outside the range 1..7"},
|
||||
{"ZSRI $6, Z7.B, Z23.H", "must match"},
|
||||
{"ZSRI $0, Z7.D, Z23.D", "outside the range 1..63"},
|
||||
{"ZASR $8, Z23.B, P1.M, Z23.B", "outside the range 1..7"},
|
||||
{"ZXAR $6, Z23.B, Z21.B, Z20.B", "the same register Zdn"},
|
||||
{"ZXAR $6, Z23.B, Z21.H, Z21.H", "must match"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := assembleArm64SrcError(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||
|
||||
@@ -516,12 +516,19 @@ func TestExtensionNamesARM64(t *testing.T) {
|
||||
"ZSQSHL",
|
||||
"ZSQSHLU",
|
||||
"ZUQSHL",
|
||||
"ZSRI",
|
||||
"ZSSRA",
|
||||
"ZUSRA",
|
||||
"ZSRSRA",
|
||||
"ZURSRA",
|
||||
"ZASRD",
|
||||
"ZXAR",
|
||||
}
|
||||
got := ExtensionNames(arch.ARM64)
|
||||
if strings.Join(got, ",") != strings.Join(want, ",") {
|
||||
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
||||
}
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 528 {
|
||||
t.Errorf("the family registers %d instructions, want 528", n)
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 537 {
|
||||
t.Errorf("the family registers %d instructions, want 537", n)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user