feat(arch): the SVE2.1 narrowing two-to-one family
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
ee2c6d51b3
commit
31ab584eee
4 files changed
+254
-3
No files matched your search
+131
-1
@@ -666,6 +666,19 @@ const (
|
|||||||
// Operands: Zt.T (the row's locked list arrangement), Pg (bare, P0-P7),
|
// Operands: Zt.T (the row's locked list arrangement), Pg (bare, P0-P7),
|
||||||
// mem. The field layout mirrors the load with the list first.
|
// mem. The field layout mirrors the load with the list first.
|
||||||
ExtFormSveStore
|
ExtFormSveStore
|
||||||
|
// ExtFormNarrow is the SVE2.1 two-to-one narrowing form, ZADDHNB Z22.S,
|
||||||
|
// Z10.S, Z8.H: two wide vectors sum and the destination keeps the high
|
||||||
|
// half of each result. Operands: Zm.T2, Zn.T2, Zd.T, where T2 is one
|
||||||
|
// step wider than T (.H+.B, .S+.H, .D+.S). The single size field
|
||||||
|
// over-determines the pair, so the arrangements are validated together.
|
||||||
|
ExtFormNarrow
|
||||||
|
// ExtFormQuadReduce is the SVE2.1 quadword reduction, the accumulator
|
||||||
|
// first: ZADDQV Z25.S, P3, V5.S4. Operands: Zdn.T, Pg (bare, P0-P7),
|
||||||
|
// Vn with the counted quadword spelling .B16, .H8, .S4 or .D2 matching
|
||||||
|
// Zdn's arrangement. The fields place Zdn in the first-source slot,
|
||||||
|
// the predicate in the narrow governing field and the vector in the
|
||||||
|
// destination slot, the reduction class's own layout.
|
||||||
|
ExtFormQuadReduce
|
||||||
)
|
)
|
||||||
|
|
||||||
// Arity returns the operand count the form takes.
|
// Arity returns the operand count the form takes.
|
||||||
@@ -703,7 +716,7 @@ func (f ExtForm) Arity() int {
|
|||||||
return 2
|
return 2
|
||||||
case ExtFormReduceReadBack:
|
case ExtFormReduceReadBack:
|
||||||
return 4
|
return 4
|
||||||
case ExtFormSveLoad, ExtFormSveStore:
|
case ExtFormSveLoad, ExtFormSveStore, ExtFormNarrow, ExtFormQuadReduce:
|
||||||
return 3
|
return 3
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
return 0
|
return 0
|
||||||
@@ -774,6 +787,10 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
|||||||
return []ExtOperandKind{ExtSveMem, ExtPReg, ExtZReg}
|
return []ExtOperandKind{ExtSveMem, ExtPReg, ExtZReg}
|
||||||
case ExtFormSveStore:
|
case ExtFormSveStore:
|
||||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
||||||
|
case ExtFormNarrow:
|
||||||
|
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
||||||
|
case ExtFormQuadReduce:
|
||||||
|
return []ExtOperandKind{ExtZReg, ExtPReg, ExtVReg}
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
@@ -896,6 +913,10 @@ func (f ExtForm) String() string {
|
|||||||
return "gather load"
|
return "gather load"
|
||||||
case ExtFormSveStore:
|
case ExtFormSveStore:
|
||||||
return "scatter store"
|
return "scatter store"
|
||||||
|
case ExtFormNarrow:
|
||||||
|
return "narrowing two-to-one"
|
||||||
|
case ExtFormQuadReduce:
|
||||||
|
return "quadword reduction"
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
return "no operands"
|
return "no operands"
|
||||||
default:
|
default:
|
||||||
@@ -1148,6 +1169,10 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
|||||||
return in.encodeSveLoad(ops)
|
return in.encodeSveLoad(ops)
|
||||||
case ExtFormSveStore:
|
case ExtFormSveStore:
|
||||||
return in.encodeSveStore(ops)
|
return in.encodeSveStore(ops)
|
||||||
|
case ExtFormNarrow:
|
||||||
|
return in.encodeNarrow(ops)
|
||||||
|
case ExtFormQuadReduce:
|
||||||
|
return in.encodeQuadReduce(ops)
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
if len(ops) != 0 {
|
if len(ops) != 0 {
|
||||||
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
||||||
@@ -2522,6 +2547,77 @@ func (in ExtInstr) encodeSveStore(ops []ExtOperand) ([]byte, error) {
|
|||||||
return extWordLE(word), nil
|
return extWordLE(word), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// encodeNarrow fills the two-to-one narrowing form: Zm.T2, Zn.T2, Zd.T,
|
||||||
|
// where T is one step below T2. The wide sources combine and the
|
||||||
|
// destination keeps the high half of each result; the single size field
|
||||||
|
// serves both widths, the wide ladder on the sources and the narrow ladder
|
||||||
|
// on the destination carrying the same value, so the arrangement pair is
|
||||||
|
// validated as a whole.
|
||||||
|
func (in ExtInstr) encodeNarrow(ops []ExtOperand) ([]byte, error) {
|
||||||
|
zm, zn, zd := ops[0], ops[1], ops[2]
|
||||||
|
for i, op := range []ExtOperand{zm, zn, zd} {
|
||||||
|
if err := in.zVector(op, i+1); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if zm.Arr != zn.Arr {
|
||||||
|
return nil, fmt.Errorf("%s: operands 1 and 2 carry arrangements %s and %s, they must match",
|
||||||
|
in.Name, zm.Arr, zn.Arr)
|
||||||
|
}
|
||||||
|
if zm.Arr < ExtArrH || zm.Arr > ExtArrD {
|
||||||
|
return nil, fmt.Errorf("%s: the wide sources carry arrangement %s, want .H, .S or .D",
|
||||||
|
in.Name, zm.Arr)
|
||||||
|
}
|
||||||
|
if zd.Arr != zm.Arr-1 {
|
||||||
|
return nil, fmt.Errorf("%s: the destination carries arrangement %s, want %s",
|
||||||
|
in.Name, zd.Arr, zm.Arr-1)
|
||||||
|
}
|
||||||
|
size, _ := zm.Arr.sizeBits()
|
||||||
|
word := in.Word
|
||||||
|
word = extSet(word, extFieldRm, uint32(zm.Reg))
|
||||||
|
word = extSet(word, extFieldRn, uint32(zn.Reg))
|
||||||
|
word = extSet(word, extFieldRd, uint32(zd.Reg))
|
||||||
|
word = extSet(word, in.Size, size)
|
||||||
|
return extWordLE(word), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeQuadReduce fills the SVE2.1 quadword reduction, the accumulator
|
||||||
|
// first: Zdn.T, Pg (bare), Vn.T2. The scalable vector register accumulates
|
||||||
|
// the reduction of the quadword vector, whose counted spelling (.B16, .H8,
|
||||||
|
// .S4, .D2) names the lane width the class reduces over and must match the
|
||||||
|
// accumulator's arrangement; the encoding carries the accumulator's own
|
||||||
|
// size field. The fields mirror the reduction class: Zdn in the
|
||||||
|
// first-source slot, the predicate in the narrow governing field, the
|
||||||
|
// vector in the destination slot.
|
||||||
|
func (in ExtInstr) encodeQuadReduce(ops []ExtOperand) ([]byte, error) {
|
||||||
|
zdn, pg, vn := ops[0], ops[1], ops[2]
|
||||||
|
if err := in.zVector(zdn, 1); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := in.barePredicate(pg, 2, 0, 7); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := in.simdReg(vn, 3); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if vn.Arr != zdn.Arr {
|
||||||
|
return nil, fmt.Errorf("%s: operand 3 carries arrangement %s, want %s",
|
||||||
|
in.Name, vn.Arr, zdn.Arr)
|
||||||
|
}
|
||||||
|
size, err := in.zSize(zdn.Arr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
word := in.Word
|
||||||
|
word = extSet(word, extFieldRn, uint32(zdn.Reg))
|
||||||
|
word = extSet(word, extFieldPgN, uint32(pg.Reg))
|
||||||
|
word = extSet(word, extFieldRd, uint32(vn.Reg))
|
||||||
|
if size != 0 {
|
||||||
|
word = extSet(word, in.Size, size)
|
||||||
|
}
|
||||||
|
return extWordLE(word), nil
|
||||||
|
}
|
||||||
|
|
||||||
// sharedSize returns the one element-size encoding the given arrangements
|
// sharedSize returns the one element-size encoding the given arrangements
|
||||||
// agree on, or an error when any operand is bare, they disagree, or the
|
// agree on, or an error when any operand is bare, they disagree, or the
|
||||||
// arrangement has no size field.
|
// arrangement has no size field.
|
||||||
@@ -3059,6 +3155,40 @@ var arm64Extensions = []ExtInstr{
|
|||||||
{Name: "ZZIPQ2", Summary: "Z-alias of the unpredicated three-vector form",
|
{Name: "ZZIPQ2", Summary: "Z-alias of the unpredicated three-vector form",
|
||||||
Word: 0x4400e400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIPQ2; inst_gen.go + arm64sveenc.s"},
|
Word: 0x4400e400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIPQ2; inst_gen.go + arm64sveenc.s"},
|
||||||
|
|
||||||
|
// --- the SVE2.1 narrowing two-to-one family ------------------------------
|
||||||
|
//
|
||||||
|
// The add, rounding add, subtract and rounding subtract narrow steps:
|
||||||
|
// two wide vectors combine and the destination keeps the high half of
|
||||||
|
// each result, bottom or top. The sources carry .H, .S or .D and the
|
||||||
|
// destination the arrangement one step below; one size field serves
|
||||||
|
// both. Provenance as above: the toolchain encoding table and its
|
||||||
|
// generated corpus, both produced from Arm's official ISA description,
|
||||||
|
// and the golden test pins every corpus line of the family.
|
||||||
|
{Name: "ZADDHNB", Summary: "Add narrow high, bottom half destination",
|
||||||
|
Word: 0x45206000, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZADDHNB; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZADDHNT", Summary: "Add narrow high, top half destination",
|
||||||
|
Word: 0x45206400, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZADDHNT; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZRADDHNB", Summary: "Add narrow high with rounding, bottom half destination",
|
||||||
|
Word: 0x45206800, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZRADDHNB; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZRADDHNT", Summary: "Add narrow high with rounding, top half destination",
|
||||||
|
Word: 0x45206c00, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZRADDHNT; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZRSUBHNB", Summary: "Subtract narrow high with rounding, bottom half destination",
|
||||||
|
Word: 0x45207800, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZRSUBHNB; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZRSUBHNT", Summary: "Subtract narrow high with rounding, top half destination",
|
||||||
|
Word: 0x45207c00, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZRSUBHNT; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZSUBHNB", Summary: "Subtract narrow high, bottom half destination",
|
||||||
|
Word: 0x45207000, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZSUBHNB; inst_gen.go + arm64sveenc.s"},
|
||||||
|
{Name: "ZSUBHNT", Summary: "Subtract narrow high, top half destination",
|
||||||
|
Word: 0x45207400, Form: ExtFormNarrow, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||||
|
Ref: "ARM DDI 0487J SVE2.1: ZSUBHNT; inst_gen.go + arm64sveenc.s"},
|
||||||
|
|
||||||
// --- the SVE2 crypto family ----------------------------------------------
|
// --- the SVE2 crypto family ----------------------------------------------
|
||||||
//
|
//
|
||||||
// The multi-precision carry steps (ADCLB, ADCLT, SBCLB, SBCLT), the SHA3
|
// The multi-precision carry steps (ADCLB, ADCLT, SBCLB, SBCLT), the SHA3
|
||||||
|
|||||||
@@ -1338,6 +1338,62 @@ func TestArm64ExtStage3Golden(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestArm64ExtStage4Golden pins the SVE2.1 narrowing two-to-one family
|
||||||
|
// (ZADDHNB and friends) against the toolchain-generated corpus, the same
|
||||||
|
// provenance as the families above: every row is one arm64sveenc.s line and
|
||||||
|
// the want word is that line's own encoding, with two extra vectors pinning
|
||||||
|
// the widths the corpus line does not show (.H over .B, .D over .S).
|
||||||
|
func TestArm64ExtStage4Golden(t *testing.T) {
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
mnem string
|
||||||
|
form ExtForm
|
||||||
|
ops []ExtOperand
|
||||||
|
want uint32
|
||||||
|
}{
|
||||||
|
{"ZADDHNB Z22.S, Z10.S, Z8.H", "ZADDHNB", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b66148},
|
||||||
|
{"ZADDHNT Z22.S, Z10.S, Z8.H", "ZADDHNT", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b66548},
|
||||||
|
{"ZRADDHNB Z22.S, Z10.S, Z8.H", "ZRADDHNB", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b66948},
|
||||||
|
{"ZRADDHNT Z22.S, Z10.S, Z8.H", "ZRADDHNT", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b66d48},
|
||||||
|
{"ZRSUBHNB Z22.S, Z10.S, Z8.H", "ZRSUBHNB", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b67948},
|
||||||
|
{"ZRSUBHNT Z22.S, Z10.S, Z8.H", "ZRSUBHNT", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b67d48},
|
||||||
|
{"ZSUBHNB Z22.S, Z10.S, Z8.H", "ZSUBHNB", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b67148},
|
||||||
|
{"ZSUBHNT Z22.S, Z10.S, Z8.H", "ZSUBHNT", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(22, ExtArrS), ExtVector(10, ExtArrS), ExtVector(8, ExtArrH)},
|
||||||
|
0x45b67548},
|
||||||
|
{"ZADDHNB Z8.H, Z10.H, Z11.B", "ZADDHNB", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(8, ExtArrH), ExtVector(10, ExtArrH), ExtVector(11, ExtArrB)},
|
||||||
|
0x4568614b},
|
||||||
|
{"ZSUBHNT Z26.D, Z4.D, Z13.S", "ZSUBHNT", ExtFormNarrow,
|
||||||
|
[]ExtOperand{ExtVector(26, ExtArrD), ExtVector(4, ExtArrD), ExtVector(13, ExtArrS)},
|
||||||
|
0x45fa748d},
|
||||||
|
} {
|
||||||
|
in := extInstructionMeta(t, tt.mnem, tt.form, ExtQualNone, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// extSveRow finds the gather/scatter row whose mnemonic, addressing mode,
|
// extSveRow finds the gather/scatter row whose mnemonic, addressing mode,
|
||||||
// base size, shift and list arrangement all match.
|
// base size, shift and list arrangement all match.
|
||||||
func extSveRow(t *testing.T, mnem string, mode uint8, shift int, base, arr ExtArrangement) ExtInstr {
|
func extSveRow(t *testing.T, mnem string, mode uint8, shift int, base, arr ExtArrangement) ExtInstr {
|
||||||
|
|||||||
@@ -745,6 +745,62 @@ func TestArm64AssembleExtensionGatherGolden(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestArm64AssembleExtensionStage4Golden drives the SVE2.1 narrowing
|
||||||
|
// two-to-one family through the full assembler: corpus text in, corpus word
|
||||||
|
// out, with the two width extensions the arch-level golden test pins.
|
||||||
|
func TestArm64AssembleExtensionStage4Golden(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
stmt string
|
||||||
|
want uint32
|
||||||
|
}{
|
||||||
|
{"ZADDHNB Z22.S, Z10.S, Z8.H", 0x45b66148},
|
||||||
|
{"ZADDHNT Z22.S, Z10.S, Z8.H", 0x45b66548},
|
||||||
|
{"ZRADDHNB Z22.S, Z10.S, Z8.H", 0x45b66948},
|
||||||
|
{"ZRADDHNT Z22.S, Z10.S, Z8.H", 0x45b66d48},
|
||||||
|
{"ZRSUBHNB Z22.S, Z10.S, Z8.H", 0x45b67948},
|
||||||
|
{"ZRSUBHNT Z22.S, Z10.S, Z8.H", 0x45b67d48},
|
||||||
|
{"ZSUBHNB Z22.S, Z10.S, Z8.H", 0x45b67148},
|
||||||
|
{"ZSUBHNT Z22.S, Z10.S, Z8.H", 0x45b67548},
|
||||||
|
{"ZADDHNB Z8.H, Z10.H, Z11.B", 0x4568614b},
|
||||||
|
{"ZSUBHNT Z26.D, Z4.D, Z13.S", 0x45fa748d},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||||
|
if len(words) != 2 {
|
||||||
|
t.Fatalf("%s: got %d words, want the statement and RET", tt.stmt, len(words))
|
||||||
|
}
|
||||||
|
if words[0] != tt.want {
|
||||||
|
t.Errorf("%s:\n got %08x\n want %08x", tt.stmt, words[0], tt.want)
|
||||||
|
}
|
||||||
|
if words[1] != 0xd65f03c0 {
|
||||||
|
t.Errorf("%s: RET encoded %08x", tt.stmt, words[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestArm64AssembleExtensionStage4Refusals pins the diagnostics the
|
||||||
|
// narrowing statements get from the layer: the arrangement pair the single
|
||||||
|
// size field over-determines.
|
||||||
|
func TestArm64AssembleExtensionStage4Refusals(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
stmt string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"ZADDHNB Z22.B, Z10.B, Z8.H", "want .H, .S or .D"},
|
||||||
|
{"ZADDHNB Z22.S, Z10.H, Z8.H", "must match"},
|
||||||
|
{"ZADDHNB Z22.S, Z10.S, Z8.S", "want .H"},
|
||||||
|
{"ZADDHNB Z22.D, Z10.D, Z8.H", "want .S"},
|
||||||
|
{"ZADDHNB Z22.Q, Z10.Q, Z8.D", "want .H, .S or .D"},
|
||||||
|
{"ZADDHNB Z22.S, Z10.S, Z8", "carries no arrangement suffix"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := assembleArm64SrcError(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||||
|
if !strings.Contains(got, tt.want) {
|
||||||
|
t.Errorf("%s: error %q does not name %q", tt.stmt, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestArm64AssembleExtensionGatherRefusals pins the diagnostics the
|
// TestArm64AssembleExtensionGatherRefusals pins the diagnostics the
|
||||||
// gather/scatter statements get from the layer: the addressing-mode
|
// gather/scatter statements get from the layer: the addressing-mode
|
||||||
// mismatches, the locked list arrangements, the zeroing qualifier of the
|
// mismatches, the locked list arrangements, the zeroing qualifier of the
|
||||||
|
|||||||
+11
-2
@@ -273,6 +273,15 @@ func TestExtensionNamesARM64(t *testing.T) {
|
|||||||
"ZZIP2",
|
"ZZIP2",
|
||||||
"ZZIPQ1",
|
"ZZIPQ1",
|
||||||
"ZZIPQ2",
|
"ZZIPQ2",
|
||||||
|
// The stage-four families: the SVE2.1 narrowing two-to-one set.
|
||||||
|
"ZADDHNB",
|
||||||
|
"ZADDHNT",
|
||||||
|
"ZRADDHNB",
|
||||||
|
"ZRADDHNT",
|
||||||
|
"ZRSUBHNB",
|
||||||
|
"ZRSUBHNT",
|
||||||
|
"ZSUBHNB",
|
||||||
|
"ZSUBHNT",
|
||||||
// The stage-three families: the SVE2 crypto group, the predicate
|
// The stage-three families: the SVE2 crypto group, the predicate
|
||||||
// counters and loop terminators with the 32-bit while compares, and
|
// counters and loop terminators with the 32-bit while compares, and
|
||||||
// the reductions into a SIMD register.
|
// the reductions into a SIMD register.
|
||||||
@@ -385,7 +394,7 @@ func TestExtensionNamesARM64(t *testing.T) {
|
|||||||
if strings.Join(got, ",") != strings.Join(want, ",") {
|
if strings.Join(got, ",") != strings.Join(want, ",") {
|
||||||
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
if n := len(arch.Extensions(arch.ARM64)); n != 381 {
|
if n := len(arch.Extensions(arch.ARM64)); n != 389 {
|
||||||
t.Errorf("the family registers %d instructions, want 381", n)
|
t.Errorf("the family registers %d instructions, want 389", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user