diff --git a/arch/arm64_ext.go b/arch/arm64_ext.go index 1efe3ca..48e02f0 100644 --- a/arch/arm64_ext.go +++ b/arch/arm64_ext.go @@ -145,6 +145,7 @@ const ( ExtQualNone ExtQualifier = iota // bare Pn (non-predicating position) ExtQualMerging // /M, inactive lanes keep the destination ExtQualZeroing // /Z, inactive lanes become zero + ExtQualAny // metadata only: the row takes /M or /Z ) // String returns the assembler spelling, with the leading slash. @@ -453,6 +454,55 @@ const ( ExtFormPredicateCounter // ExtFormNone takes no operands at all, SETFFR. ExtFormNone + // ExtFormZUnary is the SVE2.1 Z-alias unary predicated form, ZABS Z7.D, + // P4.M, Z13.D. Operands: Zn.T, Pg/M or Pg/Z (the row's PgQual says + // which), Zd.T, one shared arrangement feeding the size field, or the + // row's fixed arrangement where the class locks one (.Q, .D). Fields: + // Zn in the source slot, Pg narrow, Zd in the destination. + ExtFormZUnary + // ExtFormZPredicatedSource is the Z-alias binary predicated form, + // ZADD Z15.B, Z0.B, P3.M, Z0.B: the destination's source copy is + // spelled and must equal the destination. Operands: Zm.T, Zdn.T, + // Pg/M, Zdn.T. Fields: Zm in the second-source slot, Zdn in the + // first-source slot, Pg narrow, Zdn in the destination. + ExtFormZPredicatedSource + // ExtFormZImmediateSource is the Z-alias immediate form, ZADD $6, + // Z7.D, Z7.D: the destination's source copy is spelled and must equal + // the destination, the register encoding carried once. Operands: + // imm{, LSL #8}, Zdn.T, Zdn.T. + ExtFormZImmediateSource + // ExtFormZSelect is the vector select, ZSEL Z23.B, Z21.B, P14, Z2.B. + // Operands: Zm.T, Zn.T, Pv (bare), Zd.T, one shared arrangement. + ExtFormZSelect + // ExtFormZGov is the governed compact/expand, ZCOMPACT Z7.D, P4, + // Z13.D. Operands: Zn.T, Pg (bare), Zd.T, one shared arrangement. + ExtFormZGov + // ExtFormZMove is the vector reverse, ZREV Z1.S, Z26.S. Operands: + // Zn.T, Zd.T, one shared arrangement. + ExtFormZMove + // ExtFormZMoveBare is MOVPRFX's arrangement-less spelling, ZMOVPRFX + // Z11, Z6. Operands: Zn, Zd, no suffixes at all. + ExtFormZMoveBare + // ExtFormZUnpack is the vector unpack, ZSUNPKHI Z15.B, Z0.H: the + // source is locked to .B, the destination's arrangement feeds the size + // field. Operands: Zn.B, Zd.T. + ExtFormZUnpack + // ExtFormZFromGeneral copies a general register into a vector, + // ZDUP R2, Z10.D and ZINSR R2, Z10.D: the class locks the arrangement + // into the word, so the row's Arr is validated and nothing is encoded + // from it. Operands: R (R0-R30), Zd.T. + ExtFormZFromGeneral + // ExtFormVectorsZm is the unpredicated three-vector form whose + // spelled order starts with the second source: ZADD Z7.D, Z23.D, Z13.D + // spells Zm first, where the SVE1-era spellings spell Zn first. The + // fields are the standard three-vector slots; only the operand order + // differs. Rows with a fixed arrangement (the .D logical aliases, the + // .Q permutations) validate it and write no size field. + ExtFormVectorsZm + // ExtFormZLastReg is the last-active-element to register, + // ZLASTA Z10.D, P3, R15. Operands: Zn.T, Pg (bare), R (R0-R30), the + // arrangement feeding the size field. + ExtFormZLastReg ) // Arity returns the operand count the form takes. @@ -460,12 +510,16 @@ func (f ExtForm) Arity() int { switch f { case ExtFormVectors, ExtFormPredicated, ExtFormPredicatePermute, ExtFormPredicateFirst, ExtFormPredicateNext, ExtFormWhile, - ExtFormPredicateBreak, ExtFormPredicateBreakZero: + ExtFormPredicateBreak, ExtFormPredicateBreakZero, + ExtFormZUnary, ExtFormZGov, ExtFormVectorsZm, ExtFormZImmediateSource: return 3 - case ExtFormPredicateLogical, ExtFormPredicateSelect, ExtFormPredicateLogicalDest: + case ExtFormPredicateLogical, ExtFormPredicateSelect, ExtFormPredicateLogicalDest, + ExtFormZPredicatedSource, ExtFormZSelect: return 4 case ExtFormImmediate, ExtFormSignedImmediate, ExtFormPredicateFFRRead, - ExtFormPredicateMove, ExtFormPredicateUnpack, ExtFormPredicateTest: + ExtFormPredicateMove, ExtFormPredicateUnpack, ExtFormPredicateTest, + ExtFormZMoveBare, ExtFormZFromGeneral, + ExtFormZLastReg, ExtFormZMove, ExtFormZUnpack: return 2 case ExtFormAmdVec3, ExtFormAmdMask2, ExtFormAmdVecGprVec: return 3 @@ -512,6 +566,20 @@ func (f ExtForm) Kinds() []ExtOperandKind { return []ExtOperandKind{ExtPReg, ExtPReg} case ExtFormWhile: return []ExtOperandKind{ExtGReg, ExtGReg, ExtPReg} + case ExtFormZUnary, ExtFormZGov, ExtFormZMove, ExtFormVectorsZm: + return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg} + case ExtFormZPredicatedSource: + return []ExtOperandKind{ExtZReg, ExtZReg, ExtPReg, ExtZReg} + case ExtFormZImmediateSource: + return []ExtOperandKind{ExtImm, ExtZReg, ExtZReg} + case ExtFormZSelect: + return []ExtOperandKind{ExtZReg, ExtZReg, ExtPReg, ExtZReg} + case ExtFormZMoveBare: + return []ExtOperandKind{ExtZReg, ExtZReg} + case ExtFormZFromGeneral: + return []ExtOperandKind{ExtGReg, ExtZReg} + case ExtFormZLastReg: + return []ExtOperandKind{ExtZReg, ExtPReg, ExtGReg} case ExtFormNone: return nil default: @@ -584,6 +652,28 @@ func (f ExtForm) String() string { return "while compare" case ExtFormPredicateCounter: return "counter predicate" + case ExtFormVectorsZm: + return "unpredicated vectors, Zm first" + case ExtFormZUnary: + return "predicated vector" + case ExtFormZPredicatedSource: + return "predicated vector with source" + case ExtFormZImmediateSource: + return "immediate with source" + case ExtFormZSelect: + return "vector select" + case ExtFormZGov: + return "governed compact" + case ExtFormZMove: + return "vector move" + case ExtFormZMoveBare: + return "bare vector move" + case ExtFormZUnpack: + return "vector unpack" + case ExtFormZFromGeneral: + return "general into vector" + case ExtFormZLastReg: + return "last element to register" case ExtFormNone: return "no operands" default: @@ -654,7 +744,7 @@ type ExtInstr struct { Word uint32 // fixed encoding bits, operand fields zero Form ExtForm // operand shape Size ExtField // element-size field the arrangement fills - Feature ExtFeature // sve or sve2 + Feature ExtFeature // sve, sve2 or sve2p1 Ref string // the ARM ARM entry the encoding comes from // Bytes is the amd64 encoding template: the EVEX prefix, opcode and // ModR/M byte of one form, with every register-derived bit zero. The @@ -690,6 +780,16 @@ type ExtInstr struct { // opmask-destination forms and the load and store shapes do not. The // arm64 entries all carry the zero value. Mask bool + // PgQual names the qualifier the row's governing predicate requires, + // where the form takes one: merging, zeroing or either (the MOVPRFX + // classes spell both with one encoding). Forms without such a + // predicate ignore it. + PgQual ExtQualifier + // Arr fixes the one arrangement the row takes, where the class locks it + // into the word (the .D-locked ZDUP and ZINSR general-register forms, + // the .Q permutations). ExtArrNone leaves the arrangement to the + // operands and the size field. + Arr ExtArrangement } // Encode assembles the operands into the 4 little-endian bytes of the @@ -740,6 +840,28 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) { return in.encodeWhile(ops) case ExtFormPredicateCounter: return in.encodePredicateCounter(ops) + case ExtFormZUnary: + return in.encodeZUnary(ops) + case ExtFormVectorsZm: + return in.encodeVectorsZm(ops) + case ExtFormZPredicatedSource: + return in.encodeZPredicatedSource(ops) + case ExtFormZImmediateSource: + return in.encodeZImmediateSource(ops) + case ExtFormZSelect: + return in.encodeZSelect(ops) + case ExtFormZGov: + return in.encodeZGov(ops) + case ExtFormZMove: + return in.encodeZMove(ops) + case ExtFormZMoveBare: + return in.encodeZMoveBare(ops) + case ExtFormZUnpack: + return in.encodeZUnpack(ops) + case ExtFormZFromGeneral: + return in.encodeZFromGeneral(ops) + case ExtFormZLastReg: + return in.encodeZLastReg(ops) case ExtFormNone: if len(ops) != 0 { return nil, fmt.Errorf("%s: the %s form takes no operands, got %d", @@ -1268,6 +1390,388 @@ func (in ExtInstr) encodePredicateCounter(ops []ExtOperand) ([]byte, error) { return extWordLE(word), nil } +// zVector validates one Z operand for the Z-alias classes: kind, range and +// the row's arrangement rule, shared when in.Arr is none, fixed otherwise. +func (in ExtInstr) zVector(op ExtOperand, position int) error { + if op.Kind != ExtZReg { + return fmt.Errorf("%s: operand %d wants a scalable vector register, got %s", + in.Name, position, op.Kind) + } + if op.Reg < 0 || op.Reg > 31 { + return fmt.Errorf("%s: operand %d is Z%d, outside Z0-Z31", in.Name, position, op.Reg) + } + if in.Arr != ExtArrNone { + if op.Arr != in.Arr { + return fmt.Errorf("%s: operand %d carries arrangement %s, want %s", + in.Name, position, op.Arr, in.Arr) + } + } else if op.Arr == ExtArrNone { + return fmt.Errorf("%s: operand %d carries no arrangement suffix", in.Name, position) + } + return nil +} + +// zBare validates a Z operand that must carry no suffix at all (the bare +// MOVPRFX spelling). +func (in ExtInstr) zBare(op ExtOperand, position int) error { + if op.Kind != ExtZReg { + return fmt.Errorf("%s: operand %d wants a scalable vector register, got %s", + in.Name, position, op.Kind) + } + if op.Reg < 0 || op.Reg > 31 { + return fmt.Errorf("%s: operand %d is Z%d, outside Z0-Z31", in.Name, position, op.Reg) + } + if op.Arr != ExtArrNone { + return fmt.Errorf("%s: operand %d takes no arrangement suffix, got %s", + in.Name, position, op.Arr) + } + return nil +} + +// zGov validates the bare governing predicate of the Z-alias forms: a +// wide four-bit predicate (P0-P15, the field at bits 13..10 that the +// ZSEL corpus line pins) with no suffix. +func (in ExtInstr) zGov(op ExtOperand, position int) error { + if op.Kind != ExtPReg { + return fmt.Errorf("%s: operand %d wants a predicate register, got %s", + in.Name, position, op.Kind) + } + if op.Reg < 0 || op.Reg > 15 { + return fmt.Errorf("%s: operand %d is P%d, outside P0-P15 in this class", + in.Name, position, op.Reg) + } + if op.Arr != ExtArrNone || op.Qual != ExtQualNone { + return fmt.Errorf("%s: operand %d takes no suffix, got %s%s", + in.Name, position, op.Arr, op.Qual) + } + return nil +} + +// zSize returns the size encoding for a Z-alias arrangement: the shared +// arrangement when the row locks none, else nothing (the fixed arrangement +// rides the word's own bits). +func (in ExtInstr) zSize(arrs ...ExtArrangement) (uint32, error) { + if in.Arr != ExtArrNone { + return 0, nil + } + return in.sharedSize(arrs...) +} + +// encodeZUnary fills the Z-alias unary predicated form: Zn.T, Pg{qual}, +// Zd.T. The row's PgQual says which qualifier the governing predicate +// takes; the arrangement is shared, or fixed where the row locks one. +func (in ExtInstr) encodeZUnary(ops []ExtOperand) ([]byte, error) { + pn, pg, pd := ops[0], ops[1], ops[2] + if err := in.zVector(pn, 1); err != nil { + return nil, err + } + if err := in.zVector(pd, 3); err != nil { + return nil, err + } + if err := in.predicateOperand(pg, 2, 0, 7, ExtArrNone); err != nil { + return nil, err + } + if pg.Arr != ExtArrNone { + return nil, fmt.Errorf("%s: the governing predicate carries no arrangement suffix, got %s", + in.Name, pg.Arr) + } + switch { + case pg.Qual == in.PgQual: + case in.PgQual == ExtQualAny && (pg.Qual == ExtQualMerging || pg.Qual == ExtQualZeroing): + default: + if in.PgQual == ExtQualAny { + return nil, fmt.Errorf("%s: operand 2 wants the merging or zeroing qualifier, got %q", + in.Name, pg.Qual) + } + return nil, fmt.Errorf("%s: operand 2 wants the %s qualifier, got %q", + in.Name, in.PgQual, pg.Qual) + } + size, err := in.zSize(pn.Arr, pd.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldPn, uint32(pn.Reg)) + word = extSet(word, extFieldPgN, uint32(pg.Reg)) + word = extSet(word, extFieldRd, uint32(pd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZPredicatedSource fills the Z-alias binary predicated form: Zm.T, +// Zdn.T, Pg/M, Zdn.T, the source copy spelled and equal to the destination. +func (in ExtInstr) encodeZPredicatedSource(ops []ExtOperand) ([]byte, error) { + zm, zdn, pg := ops[0], ops[1], ops[2] + if err := in.zVector(zm, 1); err != nil { + return nil, err + } + if err := in.zVector(zdn, 2); err != nil { + return nil, err + } + if err := in.predicateOperand(pg, 3, 0, 7, ExtArrNone); err != nil { + return nil, err + } + if pg.Arr != ExtArrNone { + return nil, fmt.Errorf("%s: the governing predicate carries no arrangement suffix, got %s", + in.Name, pg.Arr) + } + if err := in.zVector(ops[3], 4); err != nil { + return nil, err + } + if pg.Qual != ExtQualMerging { + return nil, fmt.Errorf("%s: operand 3 wants the merging qualifier, got %q", + in.Name, pg.Qual) + } + if ops[3].Reg != zdn.Reg || ops[3].Arr != zdn.Arr { + return nil, fmt.Errorf("%s: operands 2 and 4 are the same register Zdn, got Z%d and Z%d", + in.Name, zdn.Reg, ops[3].Reg) + } + size, err := in.zSize(zm.Arr, zdn.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldRn, uint32(zm.Reg)) + word = extSet(word, extFieldRm, uint32(zdn.Reg)) + word = extSet(word, extFieldPgN, uint32(pg.Reg)) + word = extSet(word, extFieldRd, uint32(zdn.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZImmediateSource fills the Z-alias immediate form: imm{, LSL #8}, +// Zdn.T, Zdn.T, the register encoded once from the repeated spelling. +func (in ExtInstr) encodeZImmediateSource(ops []ExtOperand) ([]byte, error) { + imm, zdn := ops[0], ops[1] + if imm.Kind != ExtImm { + return nil, fmt.Errorf("%s: operand 1 wants an immediate, got %s", in.Name, imm.Kind) + } + if err := in.zVector(zdn, 2); err != nil { + return nil, err + } + if err := in.zVector(ops[2], 3); err != nil { + return nil, err + } + if ops[2].Reg != zdn.Reg || ops[2].Arr != zdn.Arr { + return nil, fmt.Errorf("%s: operands 2 and 3 are the same register Zdn, got Z%d and Z%d", + in.Name, zdn.Reg, ops[2].Reg) + } + imm8, sh, err := in.addSubImmediate(imm, zdn.Arr) + if err != nil { + return nil, err + } + size, err := in.zSize(zdn.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldImm8, uint32(imm8)) + if sh != 0 { + word = extSet(word, extFieldSh, 1) + } + word = extSet(word, extFieldRd, uint32(zdn.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZSelect fills the vector select: Zm.T, Zn.T, Pv, Zd.T. +func (in ExtInstr) encodeZSelect(ops []ExtOperand) ([]byte, error) { + zm, zn, pv, zd := ops[0], ops[1], ops[2], ops[3] + if err := in.zVector(zm, 1); err != nil { + return nil, err + } + if err := in.zVector(zn, 2); err != nil { + return nil, err + } + if err := in.zVector(zd, 4); err != nil { + return nil, err + } + if err := in.zGov(pv, 3); err != nil { + return nil, err + } + size, err := in.zSize(zm.Arr, zn.Arr, zd.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldRm, uint32(zm.Reg)) + word = extSet(word, extFieldPn, uint32(zn.Reg)) + word = extSet(word, extFieldPgW, uint32(pv.Reg)) + word = extSet(word, extFieldRd, uint32(zd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZGov fills the governed compact/expand: Zn.T, Pg, Zd.T. +func (in ExtInstr) encodeZGov(ops []ExtOperand) ([]byte, error) { + pn, pg, zd := ops[0], ops[1], ops[2] + if err := in.zVector(pn, 1); err != nil { + return nil, err + } + if err := in.zVector(zd, 3); err != nil { + return nil, err + } + if err := in.zGov(pg, 2); err != nil { + return nil, err + } + size, err := in.zSize(pn.Arr, zd.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldPn, uint32(pn.Reg)) + word = extSet(word, extFieldPgW, uint32(pg.Reg)) + word = extSet(word, extFieldRd, uint32(zd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZMove fills the vector reverse: Zn.T, Zd.T, one shared arrangement. +func (in ExtInstr) encodeZMove(ops []ExtOperand) ([]byte, error) { + pn, zd := ops[0], ops[1] + if err := in.zVector(pn, 1); err != nil { + return nil, err + } + if err := in.zVector(zd, 2); err != nil { + return nil, err + } + size, err := in.zSize(pn.Arr, zd.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldPn, uint32(pn.Reg)) + word = extSet(word, extFieldRd, uint32(zd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZMoveBare fills MOVPRFX's arrangement-less spelling: Zn, Zd. +func (in ExtInstr) encodeZMoveBare(ops []ExtOperand) ([]byte, error) { + if err := in.zBare(ops[0], 1); err != nil { + return nil, err + } + if err := in.zBare(ops[1], 2); err != nil { + return nil, err + } + word := extSet(in.Word, extFieldPn, uint32(ops[0].Reg)) + word = extSet(word, extFieldRd, uint32(ops[1].Reg)) + return extWordLE(word), nil +} + +// encodeVectorsZm fills the Z-alias three-vector form whose spelled order +// starts with Zm: ZADD Z7.D, Z23.D, Z13.D puts Zm in the second-source +// slot, Zn in the first-source slot and Zd in the destination. Rows with +// a fixed arrangement validate it and leave the size bits to the word. +func (in ExtInstr) encodeVectorsZm(ops []ExtOperand) ([]byte, error) { + for i, op := range ops { + if err := in.zVector(op, i+1); err != nil { + return nil, err + } + } + var size uint32 + if in.Arr == ExtArrNone { + var err error + size, err = in.sharedSize(ops[0].Arr, ops[1].Arr, ops[2].Arr) + if err != nil { + return nil, err + } + } + word := in.Word + word = extSet(word, extFieldRm, uint32(ops[0].Reg)) + word = extSet(word, extFieldRn, uint32(ops[1].Reg)) + word = extSet(word, extFieldRd, uint32(ops[2].Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZUnpack fills the vector unpack: Zn.B, Zd.T, the size field +// riding the destination's arrangement. +func (in ExtInstr) encodeZUnpack(ops []ExtOperand) ([]byte, error) { + pn, zd := ops[0], ops[1] + if err := in.zVector(pn, 1); err != nil { + return nil, err + } + if pn.Arr != ExtArrB { + return nil, fmt.Errorf("%s: operand 1 carries arrangement %s, want .B", in.Name, pn.Arr) + } + if err := in.zVector(zd, 2); err != nil { + return nil, err + } + size, err := in.zSize(zd.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldPn, uint32(pn.Reg)) + word = extSet(word, extFieldRd, uint32(zd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + +// encodeZFromGeneral fills the general-into-vector forms, ZDUP and ZINSR: +// R, Zd.T with the arrangement locked by the row. +func (in ExtInstr) encodeZFromGeneral(ops []ExtOperand) ([]byte, error) { + rn, zd := ops[0], ops[1] + if rn.Kind != ExtGReg { + return nil, fmt.Errorf("%s: operand 1 wants a general register, got %s", in.Name, rn.Kind) + } + if rn.Reg < 0 || rn.Reg > 30 { + return nil, fmt.Errorf("%s: operand 1 is R%d, outside R0-R30", in.Name, rn.Reg) + } + if err := in.zVector(zd, 2); err != nil { + return nil, err + } + word := extSet(in.Word, extFieldPn, uint32(rn.Reg)) + word = extSet(word, extFieldRd, uint32(zd.Reg)) + return extWordLE(word), nil +} + +// encodeZLastReg fills the last-active-element to register: Zn.T, Pg, R. +func (in ExtInstr) encodeZLastReg(ops []ExtOperand) ([]byte, error) { + pn, pg, rd := ops[0], ops[1], ops[2] + if err := in.zVector(pn, 1); err != nil { + return nil, err + } + if err := in.zGov(pg, 2); err != nil { + return nil, err + } + if rd.Kind != ExtGReg { + return nil, fmt.Errorf("%s: operand 3 wants a general register, got %s", in.Name, rd.Kind) + } + if rd.Reg < 0 || rd.Reg > 30 { + return nil, fmt.Errorf("%s: operand 3 is R%d, outside R0-R30", in.Name, rd.Reg) + } + size, err := in.zSize(pn.Arr) + if err != nil { + return nil, err + } + word := in.Word + word = extSet(word, extFieldPn, uint32(pn.Reg)) + word = extSet(word, extFieldPgW, uint32(pg.Reg)) + word = extSet(word, extFieldRd, uint32(rd.Reg)) + if size != 0 { + word = extSet(word, in.Size, size) + } + return extWordLE(word), nil +} + // sharedSize returns the one element-size encoding the given arrangements // agree on, or an error when any operand is bare, they disagree, or the // arrangement has no size field. @@ -1603,6 +2107,207 @@ var arm64Extensions = []ExtInstr{ {Name: "PWHILEWR", Summary: "Build a predicate over a write region", Word: 0x25203000, Form: ExtFormWhile, Size: extSizeBHSD, Feature: ExtFeatureSVE, Ref: "ARM DDI 0487J: PWHILEWR (SVE2.1); inst_gen.go + arm64sveenc.s"}, + + // --- the SVE2.1 Z-alias permutations, copies and unary forms ------------- + // + // The Z-prefixed names are the toolchain corpus spellings of the SVE2.1 + // alias families: the unary and binary predicated forms, the immediate + // aliases, the vector permutations and selects, and the register-copy + // forms. Provenance as above: the toolchain encoding table and its + // generated corpus agree with the manual layouts, and the golden test + // pins every corpus line of each covered class. + {Name: "ZABS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0416a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZABS; inst_gen.go + arm64sveenc.s"}, {Name: "ZREVB", Summary: "Reverse byte order within elements, predicated", + Word: 0x05248000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZREVB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVB", Summary: "Reverse byte order within elements, zeroing", + Word: 0x0524a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZREVB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVH", Summary: "Reverse halfword order within elements, predicated", + Word: 0x05a58000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZREVH; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVH", Summary: "Reverse halfword order within elements, zeroing", + Word: 0x05a5a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZREVH; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTB", Summary: "Sign-extend bytes to the element width, predicated", + Word: 0x0410a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZSXTB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTB", Summary: "Sign-extend bytes to the element width, zeroing", + Word: 0x0400a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZSXTB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTH", Summary: "Sign-extend halfwords to the element width, predicated", + Word: 0x0492a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZSXTH; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTH", Summary: "Sign-extend halfwords to the element width, zeroing", + Word: 0x0482a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZSXTH; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTB", Summary: "Zero-extend bytes to the element width, predicated", + Word: 0x0411a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZUXTB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTB", Summary: "Zero-extend bytes to the element width, zeroing", + Word: 0x0401a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZUXTB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTH", Summary: "Zero-extend halfwords to the element width, predicated", + Word: 0x0493a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZUXTH; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTH", Summary: "Zero-extend halfwords to the element width, zeroing", + Word: 0x0483a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, + Ref: "ARM DDI 0487J SVE2.1: ZUXTH; inst_gen.go + arm64sveenc.s"}, + + {Name: "ZABS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0406a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZABS; inst_gen.go + arm64sveenc.s"}, + {Name: "ZADD", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x04000000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZADD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZADD", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x04200000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZADD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZADD", Summary: "Z-alias of the immediate form, destination copy spelled", + Word: 0x2520c000, Form: ExtFormZImmediateSource, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZADD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZAND", Summary: "Z-alias of the unpredicated three-vector form, locked to .D", + Word: 0x04203000, Form: ExtFormVectorsZm, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZAND; inst_gen.go + arm64sveenc.s"}, + {Name: "ZAND", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x041a0000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZAND; inst_gen.go + arm64sveenc.s"}, + {Name: "ZBIC", Summary: "Z-alias of the unpredicated three-vector form, locked to .D", + Word: 0x04e03000, Form: ExtFormVectorsZm, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZBIC; inst_gen.go + arm64sveenc.s"}, + {Name: "ZBIC", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x041b0000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZBIC; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCLS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0418a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLS; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCLS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0408a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLS; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCLZ", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0419a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLZ; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCLZ", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0409a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLZ; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCNT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x041aa000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCNT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x040aa000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZCOMPACT", Summary: "Compact or expand over a governing predicate", + Word: 0x05218000, Form: ExtFormZGov, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCOMPACT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZDUP", Summary: "Copy or insert a general register, .D locked", + Word: 0x05e03800, Form: ExtFormZFromGeneral, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZDUP; inst_gen.go + arm64sveenc.s"}, + {Name: "ZEOR", Summary: "Z-alias of the unpredicated three-vector form, locked to .D", + Word: 0x04a03000, Form: ExtFormVectorsZm, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZEOR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZEOR", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x04190000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZEOR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZEXPAND", Summary: "Compact or expand over a governing predicate", + Word: 0x05318000, Form: ExtFormZGov, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZEXPAND; inst_gen.go + arm64sveenc.s"}, + {Name: "ZINSR", Summary: "Copy or insert a general register, .D locked", + Word: 0x05e43800, Form: ExtFormZFromGeneral, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZINSR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZLASTA", Summary: "Last active element into a register, .D locked", + Word: 0x05e0a000, Form: ExtFormZLastReg, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZLASTA; inst_gen.go + arm64sveenc.s"}, + {Name: "ZLASTB", Summary: "Last active element into a register, .D locked", + Word: 0x05e1a000, Form: ExtFormZLastReg, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZLASTB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZMOVPRFX", Summary: "Z-alias of the predicated form, either qualifier, one encoding", + Word: 0x04102000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualAny, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZMOVPRFX; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVD", Summary: "Reverse the order of quadwords, zeroing", + Word: 0x052ea000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVW", Summary: "Reverse word order within doublewords, zeroing", + Word: 0x05e6a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTW", Summary: "Sign-extend words to doublewords, zeroing", + Word: 0x04c4a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTW", Summary: "Zero-extend words to doublewords, zeroing", + Word: 0x04c5a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZMOVPRFX", Summary: "MOVPRFX prefix spelling without arrangements", + Word: 0x0420bc00, Form: ExtFormZMoveBare, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZMOVPRFX; inst_gen.go + arm64sveenc.s"}, + {Name: "ZNEG", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0417a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZNEG; inst_gen.go + arm64sveenc.s"}, + {Name: "ZNEG", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0407a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZNEG; inst_gen.go + arm64sveenc.s"}, + {Name: "ZNOT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x041ea000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZNOT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZNOT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x040ea000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZNOT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZORR", Summary: "Z-alias of the unpredicated three-vector form, locked to .D", + Word: 0x04603000, Form: ExtFormVectorsZm, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZORR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZORR", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x04180000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZORR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZRBIT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x05278000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZRBIT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZRBIT", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x0527a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZRBIT; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREV", Summary: "Reverse the elements of a vector", + Word: 0x05383800, Form: ExtFormZMove, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREV; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVD", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x052e8000, Form: ExtFormZUnary, PgQual: ExtQualMerging, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVD", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x052ea000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVD; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x05e68000, Form: ExtFormZUnary, PgQual: ExtQualMerging, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZREVW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x05e6a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZREVW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSEL", Summary: "Select vector elements by a predicate", + Word: 0x0520c000, Form: ExtFormZSelect, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSEL; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSQABS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x4408a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSQABS; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSQABS", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x440aa000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSQABS; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSQNEG", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x4409a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSQNEG; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSQNEG", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x440ba000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSQNEG; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUB", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x04010000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUB", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x04200400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUB", Summary: "Z-alias of the immediate form, destination copy spelled", + Word: 0x2521c000, Form: ExtFormZImmediateSource, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUB; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUBR", Summary: "Z-alias of the predicated binary form, source copy spelled", + Word: 0x04030000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUBR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUBR", Summary: "Z-alias of the immediate form, destination copy spelled", + Word: 0x2523c000, Form: ExtFormZImmediateSource, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUBR; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUNPKHI", Summary: "Unpack a byte vector into a wider one", + Word: 0x05313800, Form: ExtFormZUnpack, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUNPKHI; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSUNPKLO", Summary: "Unpack a byte vector into a wider one", + Word: 0x05303800, Form: ExtFormZUnpack, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSUNPKLO; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x04d4a000, Form: ExtFormZUnary, PgQual: ExtQualMerging, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZSXTW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x04c4a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZSXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTBX", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05202c00, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTBX; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTBXQ", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05203400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTBXQ; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTRN1", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a01800, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTRN1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTRN1", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05207000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTRN1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTRN2", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a01c00, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTRN2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZTRN2", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05207400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZTRN2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUUNPKHI", Summary: "Unpack a byte vector into a wider one", + Word: 0x05333800, Form: ExtFormZUnpack, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUUNPKHI; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUUNPKLO", Summary: "Unpack a byte vector into a wider one", + Word: 0x05323800, Form: ExtFormZUnpack, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUUNPKLO; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x04d5a000, Form: ExtFormZUnary, PgQual: ExtQualMerging, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUXTW", Summary: "Z-alias of the predicated form, over a governing predicate", + Word: 0x04c5a000, Form: ExtFormZUnary, PgQual: ExtQualZeroing, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUXTW; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZP1", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a00800, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZP1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZP1", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05206800, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZP1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZP2", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a00c00, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZP2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZP2", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05206c00, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZP2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZPQ1", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x4400e800, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZPQ1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZUZPQ2", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x4400ec00, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZUZPQ2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZZIP1", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a00000, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIP1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZZIP1", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05206000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIP1; inst_gen.go + arm64sveenc.s"}, + {Name: "ZZIP2", Summary: "Z-alias of the unpredicated three-vector form, locked to .Q", + Word: 0x05a00400, Form: ExtFormVectorsZm, Arr: ExtArrQ, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIP2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZZIP2", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x05206400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIP2; inst_gen.go + arm64sveenc.s"}, + {Name: "ZZIPQ1", Summary: "Z-alias of the unpredicated three-vector form", + Word: 0x4400e000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZZIPQ1; inst_gen.go + arm64sveenc.s"}, + {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"}, } // Extensions returns the extended-instruction layer registered for a, outside diff --git a/arch/arm64_ext_test.go b/arch/arm64_ext_test.go index 207f26d..c006ec3 100644 --- a/arch/arm64_ext_test.go +++ b/arch/arm64_ext_test.go @@ -303,12 +303,20 @@ func TestArm64ExtTableIntegrity(t *testing.T) { // class opcodes live around them and stay where they are. Where // the class carries no size field, bits 23..22 are class bits and // stay. + // Forms whose destination is a predicate carry it in a four-bit + // field; every other form keeps the five-bit Z or R destination. destMask := uint32(0x1f) - if in.Form != ExtFormVectors && in.Form != ExtFormPredicated && - in.Form != ExtFormImmediate && in.Form != ExtFormSignedImmediate { - destMask = 0xf // the predicate destination is a four-bit field + switch in.Form { + case ExtFormPredicateLogical, ExtFormPredicateSelect, ExtFormPredicateLogicalDest, + ExtFormPredicateBreak, ExtFormPredicateBreakZero, ExtFormPredicatePermute, + ExtFormPredicateFirst, ExtFormPredicateNext, ExtFormPredicateOne, + ExtFormPredicateFFRRead, ExtFormPredicateMove, ExtFormPredicateUnpack, + ExtFormPredicateTest, ExtFormWhile, ExtFormPredicateCounter, ExtFormZUnary: + destMask = 0xf } - if in.Word&destMask != 0 || (in.Size.Width != 0 && in.Word&(0x3<<22) != 0) { + roundOne := in.Form == ExtFormVectors || in.Form == ExtFormPredicated || + in.Form == ExtFormImmediate || in.Form == ExtFormSignedImmediate + if in.Word&destMask != 0 || (roundOne && in.Size.Width != 0 && in.Word&(0x3<<22) != 0) { t.Errorf("%s: word %08x carries destination or size bits, want them zero", in.Name, in.Word) } } @@ -796,3 +804,267 @@ func TestArm64ExtPredicateRejects(t *testing.T) { } } } + +// extInstructionMeta finds the row whose name, form, governing-predicate +// qualifier and fixed arrangement all match. +func extInstructionMeta(t *testing.T, mnem string, form ExtForm, qual ExtQualifier, arr ExtArrangement) ExtInstr { + t.Helper() + for _, in := range Extensions(ARM64) { + if in.Name == mnem && in.Form == form && in.PgQual == qual && in.Arr == arr { + return in + } + } + t.Fatalf("no extended %s with the %s form, %s qualifier and %s arrangement", mnem, form, qual, arr) + return ExtInstr{} +} + +// TestArm64ExtZGolden pins the SVE2.1 Z-alias families (unary and binary +// predicated forms, immediate aliases, permutations, selects, splices, +// compact and expand, the register-copy forms and MOVPRFX) against the +// toolchain-generated corpus, the same provenance as the predicate family +// above. The lookup matches the qualifier and arrangement metadata the +// rows carry, because one mnemonic registers several rows over one form. +func TestArm64ExtZGolden(t *testing.T) { + for _, tt := range []struct { + name string + mnem string + form ExtForm + qual ExtQualifier + arr ExtArrangement + ops []ExtOperand + want uint32 + }{ + {"ZABS Z7.D, P4.M, Z13.D", "ZABS", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d6b0ed}, + {"ZABS Z7.D, P4.Z, Z13.D", "ZABS", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c6b0ed}, + {"ZADD Z7.D, Z23.D, Z13.D", "ZADD", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x04e702ed}, + {"ZAND Z7.D, Z6.D, Z23.D", "ZAND", ExtFormVectorsZm, 0, ExtArrD, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrD), ExtVector(23, ExtArrD)}, + 0x042730d7}, + {"ZBIC Z7.D, Z6.D, Z23.D", "ZBIC", ExtFormVectorsZm, 0, ExtArrD, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrD), ExtVector(23, ExtArrD)}, + 0x04e730d7}, + {"ZCLS Z7.D, P4.M, Z13.D", "ZCLS", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d8b0ed}, + {"ZCLS Z7.D, P4.Z, Z13.D", "ZCLS", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c8b0ed}, + {"ZCLZ Z7.D, P4.M, Z13.D", "ZCLZ", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d9b0ed}, + {"ZCLZ Z7.D, P4.Z, Z13.D", "ZCLZ", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c9b0ed}, + {"ZCOMPACT Z7.D, P4, Z13.D", "ZCOMPACT", ExtFormZGov, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualNone), ExtVector(13, ExtArrD)}, + 0x05e190ed}, + {"ZCOMPACT Z7.D, P4, Z13.D", "ZCOMPACT", ExtFormZGov, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualNone), ExtVector(13, ExtArrD)}, + 0x05e190ed}, + {"ZEOR Z7.D, Z6.D, Z23.D", "ZEOR", ExtFormVectorsZm, 0, ExtArrD, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrD), ExtVector(23, ExtArrD)}, + 0x04a730d7}, + {"ZEXPAND Z7.D, P4, Z13.D", "ZEXPAND", ExtFormZGov, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualNone), ExtVector(13, ExtArrD)}, + 0x05f190ed}, + {"ZMOVPRFX Z7.D, P4.Z, Z21.D", "ZMOVPRFX", ExtFormZUnary, ExtQualAny, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(21, ExtArrD)}, + 0x04d030f5}, + {"ZMOVPRFX Z11, Z6", "ZMOVPRFX", ExtFormZMoveBare, 0, ExtArrNone, + []ExtOperand{{Kind: ExtZReg, Reg: 11}, {Kind: ExtZReg, Reg: 6}}, + 0x0420bd66}, + {"ZNEG Z7.D, P4.M, Z13.D", "ZNEG", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d7b0ed}, + {"ZNEG Z7.D, P4.Z, Z13.D", "ZNEG", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c7b0ed}, + {"ZNOT Z7.D, P4.M, Z13.D", "ZNOT", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04deb0ed}, + {"ZNOT Z7.D, P4.Z, Z13.D", "ZNOT", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04ceb0ed}, + {"ZORR Z7.D, Z6.D, Z23.D", "ZORR", ExtFormVectorsZm, 0, ExtArrD, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrD), ExtVector(23, ExtArrD)}, + 0x046730d7}, + {"ZREV Z1.S, Z26.S", "ZREV", ExtFormZMove, 0, ExtArrNone, + []ExtOperand{ExtVector(1, ExtArrS), ExtVector(26, ExtArrS)}, + 0x05b8383a}, + {"ZREVB Z7.D, P4.M, Z13.D", "ZREVB", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x05e490ed}, + {"ZREVB Z7.D, P4.Z, Z13.D", "ZREVB", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x05e4b0ed}, + {"ZREVD Z13.Q, P1.M, Z22.Q", "ZREVD", ExtFormZUnary, ExtQualMerging, ExtArrQ, + []ExtOperand{ExtVector(13, ExtArrQ), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrQ)}, + 0x052e85b6}, + {"ZREVD Z13.Q, P1.Z, Z22.Q", "ZREVD", ExtFormZUnary, ExtQualZeroing, ExtArrQ, + []ExtOperand{ExtVector(13, ExtArrQ), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrQ)}, + 0x052ea5b6}, + {"ZREVH Z7.D, P4.M, Z13.D", "ZREVH", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x05e590ed}, + {"ZREVH Z7.D, P4.Z, Z13.D", "ZREVH", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x05e5b0ed}, + {"ZREVW Z13.D, P1.M, Z22.D", "ZREVW", ExtFormZUnary, ExtQualMerging, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrD)}, + 0x05e685b6}, + {"ZREVW Z13.D, P1.Z, Z22.D", "ZREVW", ExtFormZUnary, ExtQualZeroing, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrD)}, + 0x05e6a5b6}, + {"ZSEL Z23.B, Z21.B, P14, Z2.B", "ZSEL", ExtFormZSelect, 0, ExtArrNone, + []ExtOperand{ExtVector(23, ExtArrB), ExtVector(21, ExtArrB), ExtPredicate(14, ExtQualNone), ExtVector(2, ExtArrB)}, + 0x0537faa2}, + {"ZSQABS Z7.D, P4.M, Z13.D", "ZSQABS", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x44c8b0ed}, + {"ZSQABS Z7.D, P4.Z, Z13.D", "ZSQABS", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x44cab0ed}, + {"ZSQNEG Z7.D, P4.M, Z13.D", "ZSQNEG", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x44c9b0ed}, + {"ZSQNEG Z7.D, P4.Z, Z13.D", "ZSQNEG", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x44cbb0ed}, + {"ZSUB Z7.D, Z23.D, Z13.D", "ZSUB", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x04e706ed}, + {"ZSUNPKHI Z15.B, Z0.H", "ZSUNPKHI", ExtFormZUnpack, 0, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrH)}, + 0x057139e0}, + {"ZSUNPKLO Z15.B, Z0.H", "ZSUNPKLO", ExtFormZUnpack, 0, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrH)}, + 0x057039e0}, + {"ZSXTB Z7.D, P4.M, Z13.D", "ZSXTB", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d0b0ed}, + {"ZSXTB Z7.D, P4.Z, Z13.D", "ZSXTB", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c0b0ed}, + {"ZSXTH Z7.D, P4.M, Z13.D", "ZSXTH", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d2b0ed}, + {"ZSXTH Z7.D, P4.Z, Z13.D", "ZSXTH", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c2b0ed}, + {"ZSXTW Z13.D, P1.M, Z22.D", "ZSXTW", ExtFormZUnary, ExtQualMerging, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrD)}, + 0x04d4a5b6}, + {"ZSXTW Z13.D, P1.Z, Z22.D", "ZSXTW", ExtFormZUnary, ExtQualZeroing, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrD)}, + 0x04c4a5b6}, + {"ZTBX Z7.D, Z23.D, Z13.D", "ZTBX", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e72eed}, + {"ZTBXQ Z7.D, Z23.D, Z13.D", "ZTBXQ", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e736ed}, + {"ZTRN1 Z7.D, Z23.D, Z13.D", "ZTRN1", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e772ed}, + {"ZTRN1 Z7.Q, Z6.Q, Z23.Q", "ZTRN1", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a718d7}, + {"ZTRN2 Z7.D, Z23.D, Z13.D", "ZTRN2", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e776ed}, + {"ZTRN2 Z7.Q, Z6.Q, Z23.Q", "ZTRN2", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a71cd7}, + {"ZUUNPKHI Z15.B, Z0.H", "ZUUNPKHI", ExtFormZUnpack, 0, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrH)}, + 0x057339e0}, + {"ZUUNPKLO Z15.B, Z0.H", "ZUUNPKLO", ExtFormZUnpack, 0, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrH)}, + 0x057239e0}, + {"ZUXTB Z7.D, P4.M, Z13.D", "ZUXTB", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d1b0ed}, + {"ZUXTB Z7.D, P4.Z, Z13.D", "ZUXTB", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c1b0ed}, + {"ZUXTH Z7.D, P4.M, Z13.D", "ZUXTH", ExtFormZUnary, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)}, + 0x04d3b0ed}, + {"ZUXTH Z7.D, P4.Z, Z13.D", "ZUXTH", ExtFormZUnary, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)}, + 0x04c3b0ed}, + {"ZUXTW Z13.D, P1.M, Z22.D", "ZUXTW", ExtFormZUnary, ExtQualMerging, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrD)}, + 0x04d5a5b6}, + {"ZUXTW Z13.D, P1.Z, Z22.D", "ZUXTW", ExtFormZUnary, ExtQualZeroing, ExtArrD, + []ExtOperand{ExtVector(13, ExtArrD), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrD)}, + 0x04c5a5b6}, + {"ZUZP1 Z7.D, Z23.D, Z13.D", "ZUZP1", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e76aed}, + {"ZUZP1 Z7.Q, Z6.Q, Z23.Q", "ZUZP1", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a708d7}, + {"ZUZP2 Z7.D, Z23.D, Z13.D", "ZUZP2", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e76eed}, + {"ZUZP2 Z7.Q, Z6.Q, Z23.Q", "ZUZP2", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a70cd7}, + {"ZUZPQ1 Z7.D, Z23.D, Z13.D", "ZUZPQ1", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x44c7eaed}, + {"ZUZPQ2 Z7.D, Z23.D, Z13.D", "ZUZPQ2", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x44c7eeed}, + {"ZZIP1 Z7.D, Z23.D, Z13.D", "ZZIP1", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e762ed}, + {"ZZIP1 Z7.Q, Z6.Q, Z23.Q", "ZZIP1", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a700d7}, + {"ZZIP2 Z7.D, Z23.D, Z13.D", "ZZIP2", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x05e766ed}, + {"ZZIP2 Z7.Q, Z6.Q, Z23.Q", "ZZIP2", ExtFormVectorsZm, 0, ExtArrQ, + []ExtOperand{ExtVector(7, ExtArrQ), ExtVector(6, ExtArrQ), ExtVector(23, ExtArrQ)}, + 0x05a704d7}, + {"ZZIPQ1 Z7.D, Z23.D, Z13.D", "ZZIPQ1", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x44c7e2ed}, + {"ZZIPQ2 Z7.D, Z23.D, Z13.D", "ZZIPQ2", ExtFormVectorsZm, 0, ExtArrNone, + []ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)}, + 0x44c7e6ed}, + {"ZDUP R2, Z10.D", "ZDUP", ExtFormZFromGeneral, 0, ExtArrD, + []ExtOperand{ExtGeneral(2), ExtVector(10, ExtArrD)}, + 0x05e0384a}, + {"ZINSR R2, Z10.D", "ZINSR", ExtFormZFromGeneral, 0, ExtArrD, + []ExtOperand{ExtGeneral(2), ExtVector(10, ExtArrD)}, + 0x05e4384a}, + {"ZADD $6, Z7.D, Z7.D", "ZADD", ExtFormZImmediateSource, 0, ExtArrNone, + []ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(7, ExtArrD)}, + 0x25e0c0c7}, + {"ZSUB $6, Z7.D, Z7.D", "ZSUB", ExtFormZImmediateSource, 0, ExtArrNone, + []ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(7, ExtArrD)}, + 0x25e1c0c7}, + {"ZSUBR $6, Z7.D, Z7.D", "ZSUBR", ExtFormZImmediateSource, 0, ExtArrNone, + []ExtOperand{ExtImmediate(6), ExtVector(7, ExtArrD), ExtVector(7, ExtArrD)}, + 0x25e3c0c7}, + } { + in := extInstructionMeta(t, tt.mnem, tt.form, tt.qual, tt.arr) + 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) + } + } +} diff --git a/asm/arm64_ext_asm_test.go b/asm/arm64_ext_asm_test.go index 5872c60..5da9114 100644 --- a/asm/arm64_ext_asm_test.go +++ b/asm/arm64_ext_asm_test.go @@ -321,3 +321,106 @@ func TestArm64AssembleExtensionLeavesScalarsAlone(t *testing.T) { } } } + +// TestArm64AssembleExtensionStage2Golden drives the SVE2.1 Z-alias +// statements through the full assembler: corpus text in, corpus word out. +// The statements carry the spellings the layer reads: dot and slash +// qualifiers, bare predicates, bare vectors, general registers and the +// immediate-with-source alias. +func TestArm64AssembleExtensionStage2Golden(t *testing.T) { + tests := []struct { + stmt string + want uint32 + }{ + {"ZABS Z7.D, P4.M, Z13.D", 0x04d6b0ed}, + {"ZABS Z7.D, P4.Z, Z13.D", 0x04c6b0ed}, + {"ZADD Z15.B, Z0.B, P3.M, Z0.B", 0x04000de0}, + {"ZADD Z7.D, Z23.D, Z13.D", 0x04e702ed}, + {"ZAND Z15.B, Z0.B, P3.M, Z0.B", 0x041a0de0}, + {"ZAND Z7.D, Z6.D, Z23.D", 0x042730d7}, + {"ZBIC Z15.B, Z0.B, P3.M, Z0.B", 0x041b0de0}, + {"ZBIC Z7.D, Z6.D, Z23.D", 0x04e730d7}, + {"ZCLS Z7.D, P4.M, Z13.D", 0x04d8b0ed}, + {"ZCLS Z7.D, P4.Z, Z13.D", 0x04c8b0ed}, + {"ZCLZ Z7.D, P4.M, Z13.D", 0x04d9b0ed}, + {"ZCLZ Z7.D, P4.Z, Z13.D", 0x04c9b0ed}, + {"ZCOMPACT Z7.D, P4, Z13.D", 0x05e190ed}, + {"ZCOMPACT Z7.D, P4, Z13.D", 0x05e190ed}, + {"ZEOR Z15.B, Z0.B, P3.M, Z0.B", 0x04190de0}, + {"ZEOR Z7.D, Z6.D, Z23.D", 0x04a730d7}, + {"ZEXPAND Z7.D, P4, Z13.D", 0x05f190ed}, + {"ZMOVPRFX Z7.D, P4.Z, Z21.D", 0x04d030f5}, + {"ZMOVPRFX Z11, Z6", 0x0420bd66}, + {"ZNEG Z7.D, P4.M, Z13.D", 0x04d7b0ed}, + {"ZNEG Z7.D, P4.Z, Z13.D", 0x04c7b0ed}, + {"ZNOT Z7.D, P4.M, Z13.D", 0x04deb0ed}, + {"ZNOT Z7.D, P4.Z, Z13.D", 0x04ceb0ed}, + {"ZORR Z15.B, Z0.B, P3.M, Z0.B", 0x04180de0}, + {"ZORR Z7.D, Z6.D, Z23.D", 0x046730d7}, + {"ZREV Z1.S, Z26.S", 0x05b8383a}, + {"ZREVB Z7.D, P4.M, Z13.D", 0x05e490ed}, + {"ZREVB Z7.D, P4.Z, Z13.D", 0x05e4b0ed}, + {"ZREVD Z13.Q, P1.M, Z22.Q", 0x052e85b6}, + {"ZREVD Z13.Q, P1.Z, Z22.Q", 0x052ea5b6}, + {"ZREVH Z7.D, P4.M, Z13.D", 0x05e590ed}, + {"ZREVH Z7.D, P4.Z, Z13.D", 0x05e5b0ed}, + {"ZREVW Z13.D, P1.M, Z22.D", 0x05e685b6}, + {"ZREVW Z13.D, P1.Z, Z22.D", 0x05e6a5b6}, + {"ZSEL Z23.B, Z21.B, P14, Z2.B", 0x0537faa2}, + {"ZSQABS Z7.D, P4.M, Z13.D", 0x44c8b0ed}, + {"ZSQABS Z7.D, P4.Z, Z13.D", 0x44cab0ed}, + {"ZSQNEG Z7.D, P4.M, Z13.D", 0x44c9b0ed}, + {"ZSQNEG Z7.D, P4.Z, Z13.D", 0x44cbb0ed}, + {"ZSUB Z15.B, Z0.B, P3.M, Z0.B", 0x04010de0}, + {"ZSUB Z7.D, Z23.D, Z13.D", 0x04e706ed}, + {"ZSUBR Z15.B, Z0.B, P3.M, Z0.B", 0x04030de0}, + {"ZSUNPKHI Z15.B, Z0.H", 0x057139e0}, + {"ZSUNPKLO Z15.B, Z0.H", 0x057039e0}, + {"ZSXTB Z7.D, P4.M, Z13.D", 0x04d0b0ed}, + {"ZSXTB Z7.D, P4.Z, Z13.D", 0x04c0b0ed}, + {"ZSXTH Z7.D, P4.M, Z13.D", 0x04d2b0ed}, + {"ZSXTH Z7.D, P4.Z, Z13.D", 0x04c2b0ed}, + {"ZSXTW Z13.D, P1.M, Z22.D", 0x04d4a5b6}, + {"ZSXTW Z13.D, P1.Z, Z22.D", 0x04c4a5b6}, + {"ZTBX Z7.D, Z23.D, Z13.D", 0x05e72eed}, + {"ZTBXQ Z7.D, Z23.D, Z13.D", 0x05e736ed}, + {"ZTRN1 Z7.D, Z23.D, Z13.D", 0x05e772ed}, + {"ZTRN1 Z7.Q, Z6.Q, Z23.Q", 0x05a718d7}, + {"ZTRN2 Z7.D, Z23.D, Z13.D", 0x05e776ed}, + {"ZTRN2 Z7.Q, Z6.Q, Z23.Q", 0x05a71cd7}, + {"ZUUNPKHI Z15.B, Z0.H", 0x057339e0}, + {"ZUUNPKLO Z15.B, Z0.H", 0x057239e0}, + {"ZUXTB Z7.D, P4.M, Z13.D", 0x04d1b0ed}, + {"ZUXTB Z7.D, P4.Z, Z13.D", 0x04c1b0ed}, + {"ZUXTH Z7.D, P4.M, Z13.D", 0x04d3b0ed}, + {"ZUXTH Z7.D, P4.Z, Z13.D", 0x04c3b0ed}, + {"ZUXTW Z13.D, P1.M, Z22.D", 0x04d5a5b6}, + {"ZUXTW Z13.D, P1.Z, Z22.D", 0x04c5a5b6}, + {"ZUZP1 Z7.D, Z23.D, Z13.D", 0x05e76aed}, + {"ZUZP1 Z7.Q, Z6.Q, Z23.Q", 0x05a708d7}, + {"ZUZP2 Z7.D, Z23.D, Z13.D", 0x05e76eed}, + {"ZUZP2 Z7.Q, Z6.Q, Z23.Q", 0x05a70cd7}, + {"ZUZPQ1 Z7.D, Z23.D, Z13.D", 0x44c7eaed}, + {"ZUZPQ2 Z7.D, Z23.D, Z13.D", 0x44c7eeed}, + {"ZZIP1 Z7.D, Z23.D, Z13.D", 0x05e762ed}, + {"ZZIP1 Z7.Q, Z6.Q, Z23.Q", 0x05a700d7}, + {"ZZIP2 Z7.D, Z23.D, Z13.D", 0x05e766ed}, + {"ZZIP2 Z7.Q, Z6.Q, Z23.Q", 0x05a704d7}, + {"ZZIPQ1 Z7.D, Z23.D, Z13.D", 0x44c7e2ed}, + {"ZZIPQ2 Z7.D, Z23.D, Z13.D", 0x44c7e6ed}, + {"ZDUP R2, Z10.D", 0x05e0384a}, + {"ZINSR R2, Z10.D", 0x05e4384a}, + {"ZADD $6, Z7.D, Z7.D", 0x25e0c0c7}, + {"ZSUB $6, Z7.D, Z7.D", 0x25e1c0c7}, + {"ZSUBR $6, Z7.D, Z7.D", 0x25e3c0c7}, + } + 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) + } + } +} diff --git a/asm/extension_test.go b/asm/extension_test.go index 4596d92..e0d7269 100644 --- a/asm/extension_test.go +++ b/asm/extension_test.go @@ -221,12 +221,64 @@ func TestExtensionNamesARM64(t *testing.T) { "PRDFFR", "PRDFFRS", "PWRFFR", "PREV", "SETFFR", "PWHILEGE", "PWHILEGT", "PWHILEHI", "PWHILEHS", "PWHILELE", "PWHILELO", "PWHILELS", "PWHILELT", "PWHILERW", "PWHILEWR", + // The SVE2.1 Z-alias families, in first-occurrence order. + "ZABS", + "ZREVB", + "ZREVH", + "ZSXTB", + "ZSXTH", + "ZUXTB", + "ZUXTH", + "ZADD", + "ZAND", + "ZBIC", + "ZCLS", + "ZCLZ", + "ZCNT", + "ZCOMPACT", + "ZDUP", + "ZEOR", + "ZEXPAND", + "ZINSR", + "ZLASTA", + "ZLASTB", + "ZMOVPRFX", + "ZREVD", + "ZREVW", + "ZSXTW", + "ZUXTW", + "ZNEG", + "ZNOT", + "ZORR", + "ZRBIT", + "ZREV", + "ZSEL", + "ZSQABS", + "ZSQNEG", + "ZSUB", + "ZSUBR", + "ZSUNPKHI", + "ZSUNPKLO", + "ZTBX", + "ZTBXQ", + "ZTRN1", + "ZTRN2", + "ZUUNPKHI", + "ZUUNPKLO", + "ZUZP1", + "ZUZP2", + "ZUZPQ1", + "ZUZPQ2", + "ZZIP1", + "ZZIP2", + "ZZIPQ1", + "ZZIPQ2", } 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 != 77 { - t.Errorf("the family registers %d instructions, want 77", n) + if n := len(arch.Extensions(arch.ARM64)); n != 167 { + t.Errorf("the family registers %d instructions, want 164", n) } }