feat(asm): encode the arm64 SVE gather loads and scatter stores

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:51:10 +02:00
1 parent 6faf850793
commit 104bea036b
5 files changed
+1273 -2

No files matched your search

+828
View File
@@ -41,6 +41,10 @@ const (
ExtGReg // general register R0-R30
ExtPNReg // predicate-as-counter register PN8-PN15
ExtVReg // 128-bit SIMD register V0-V31, the scalar lanes of Z0-Z31
// ExtSveMem is the arm64 gather/scatter memory operand, the parenthesised
// register pair or immediate-offset base the SVE loads and stores address
// through: (R6)(R14), (Z23.D<<1)(R24), (Z4.S.UXTW)(R3), 6(Z7.S).
ExtSveMem
)
// String returns a short label for the kind.
@@ -72,6 +76,8 @@ func (k ExtOperandKind) String() string {
return "predicate-as-counter register"
case ExtVReg:
return "SIMD register"
case ExtSveMem:
return "SVE memory operand"
default:
return "operand"
}
@@ -213,6 +219,16 @@ type ExtOperand struct {
// of this layer accept one spelling or the other, never a plain R31, so
// the marker carries the distinction into the diagnostics.
Reg31 uint8 // 0 = a register 0..30, 1 = ZR, 2 = RSP
// The arm64 gather/scatter memory operand (Kind ExtSveMem) carries its
// addressing in these fields beside Reg, Arr, Imm, Shift and Reg31: the
// first parenthesised register in Reg (general or scalable vector, told
// apart by BaseVec, its element size in Arr), the optional UXTW or SXTW
// extension in Extend, the <<s scale in Shift, the second parenthesised
// register in Off (-1 when the operand carries no second parenthesis)
// and the byte displacement of the immediate-offset spellings in Imm.
BaseVec bool // the first parenthesis spells a Z register
Extend uint8 // 0 = none, 1 = UXTW, 2 = SXTW
Off int // the second parenthesis's register, -1 when absent
}
// ExtVector builds a scalable vector operand, ADD Z1.S style.
@@ -262,6 +278,45 @@ func ExtSIMD(reg int) ExtOperand {
return ExtOperand{Kind: ExtVReg, Reg: reg}
}
// ExtSveMemPair builds the two-general-register gather/scatter memory
// operand, (R21)(R7) style, with the optionals scale Shift the <<s suffix
// spells and RSP the second parenthesis's stack-pointer spelling.
func ExtSveMemPair(base, shift, off int, sp bool) ExtOperand {
op := ExtOperand{Kind: ExtSveMem, Reg: base, Shift: shift, Off: off}
if sp {
op.Off, op.Reg31 = 31, 2
}
return op
}
// ExtSveMemVector builds the vector-register gather/scatter memory operand,
// (Z23.D<<1)(R24) style: the base is a scalable vector of the given element
// size, optionally shifted, with the general offset register in off (-1 when
// the operand carries no second parenthesis).
func ExtSveMemVector(base int, arr ExtArrangement, shift, off int) ExtOperand {
return ExtOperand{Kind: ExtSveMem, Reg: base, Arr: arr, Shift: shift, Off: off, BaseVec: true}
}
// ExtSveMemExtended builds the extended 32-bit-offset gather/scatter memory
// operand, (Z4.S.UXTW<<1)(R3) style: the base is a .S vector whose offsets
// the UXTW or SXTW extension widens, with the general offset register in off.
func ExtSveMemExtended(base int, sxtw bool, shift, off int) ExtOperand {
op := ExtSveMemVector(base, ExtArrS, shift, off)
op.Extend = 1
if sxtw {
op.Extend = 2
}
return op
}
// ExtSveMemImmediate builds the immediate-offset gather/scatter memory
// operand, 6(Z7.S) style: the byte displacement rides Imm, the vector base
// carries the element size, and the encoder scales the displacement by the
// access size into the five-bit immediate field.
func ExtSveMemImmediate(base int, arr ExtArrangement, disp int64) ExtOperand {
return ExtOperand{Kind: ExtSveMem, Reg: base, Arr: arr, Imm: disp, Off: -1, BaseVec: true}
}
// ExtImmediate builds an unshifted immediate operand.
func ExtImmediate(v int64) ExtOperand {
return ExtOperand{Kind: ExtImm, Imm: v}
@@ -572,6 +627,18 @@ const (
// Zn.T, Vd, Pg (bare), Vd, where operands 2 and 4 name the same
// register.
ExtFormReduceReadBack
// ExtFormSveLoad is the gather load: ZLD1B (Z6.D)(R14), P4.Z, [Z13.D].
// Operands: mem (the addressing mode the row's SveMode names), Pg/Z
// (P0-P7, zeroing), Zt.T (the row's locked list arrangement). The first
// parenthesised register or the scaled immediate fills the second-source
// slot, the second parenthesis or the immediate-mode base the first-
// source slot, the predicate the narrow governing field and the list
// register the destination slot.
ExtFormSveLoad
// ExtFormSveStore is the scatter store: ZST1B [Z7.D], P4, (R21)(R7).
// Operands: Zt.T (the row's locked list arrangement), Pg (bare, P0-P7),
// mem. The field layout mirrors the load with the list first.
ExtFormSveStore
)
// Arity returns the operand count the form takes.
@@ -606,6 +673,8 @@ func (f ExtForm) Arity() int {
return 2
case ExtFormReduceReadBack:
return 4
case ExtFormSveLoad, ExtFormSveStore:
return 3
case ExtFormNone:
return 0
default:
@@ -671,6 +740,10 @@ func (f ExtForm) Kinds() []ExtOperandKind {
return []ExtOperandKind{ExtZReg, ExtPReg, ExtVReg}
case ExtFormReduceReadBack:
return []ExtOperandKind{ExtZReg, ExtVReg, ExtPReg, ExtVReg}
case ExtFormSveLoad:
return []ExtOperandKind{ExtSveMem, ExtPReg, ExtZReg}
case ExtFormSveStore:
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
case ExtFormNone:
return nil
default:
@@ -781,6 +854,10 @@ func (f ExtForm) String() string {
return "reduction to a SIMD register"
case ExtFormReduceReadBack:
return "accumulating reduction, destination read back"
case ExtFormSveLoad:
return "gather load"
case ExtFormSveStore:
return "scatter store"
case ExtFormNone:
return "no operands"
default:
@@ -897,8 +974,29 @@ type ExtInstr struct {
// the .Q permutations). ExtArrNone leaves the arrangement to the
// operands and the size field.
Arr ExtArrangement
// The gather/scatter rows (ExtFormSveLoad and ExtFormSveStore) carry
// their addressing mode as metadata: SveMode names the memory operand's
// shape, SveShift the <<s scale the mode requires (for the
// immediate-offset mode it is the access-size shift the displacement
// divides by), and SveBase the element size the vector base must carry
// (.S or .D where the mode takes a vector). The list arrangement rides
// Arr, locked per row: for the gathers it is part of the instruction's
// identity, the offset index size.
SveMode uint8 // extMemNone or one of the extMem* modes below
SveShift int // the required <<s, or the access-size shift
SveBase ExtArrangement // the vector base's element size, where it has one
}
// The arm64 gather/scatter addressing modes, the values SveMode carries.
const (
extMemNone uint8 = iota // the row takes no SVE memory operand
extMemPair // (Rn{<<s})(Rm), two general registers
extMemVecOff // (Zn.T{<<s})(Rm), vector base, general offset
extMemExt32 // (Zn.S.UXTW{<<s})(Rm), extended 32-bit offsets
extMemImm // imm(Zn.T), vector base, immediate offset
extMemVecBase // (Zn.T), the vector base alone
)
// Encode assembles the operands into the 4 little-endian bytes of the
// instruction word. The operand kinds, register ranges, arrangements and
// immediate ranges are validated against the form; an operand the class
@@ -985,6 +1083,10 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
return in.encodeReduce(ops)
case ExtFormReduceReadBack:
return in.encodeReduceReadBack(ops)
case ExtFormSveLoad:
return in.encodeSveLoad(ops)
case ExtFormSveStore:
return in.encodeSveStore(ops)
case ExtFormNone:
if len(ops) != 0 {
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
@@ -2166,6 +2268,198 @@ func (in ExtInstr) encodeReduceReadBack(ops []ExtOperand) ([]byte, error) {
return extWordLE(word), nil
}
// sveMemFill validates one gather/scatter memory operand against the row's
// addressing mode and fills the register slots: the first parenthesised
// register or the scaled immediate goes to the second-source slot, the
// second parenthesis or the immediate-mode base to the first-source slot.
func (in ExtInstr) sveMemFill(word uint32, op ExtOperand, position int) (uint32, error) {
if op.Kind != ExtSveMem {
return 0, fmt.Errorf("%s: operand %d wants an SVE memory operand, got %s",
in.Name, position, op.Kind)
}
switch in.SveMode {
case extMemPair:
if op.BaseVec || op.Extend != 0 || op.Arr != ExtArrNone {
return 0, fmt.Errorf("%s: operand %d wants two general registers, (Rn{<<%d})(Rm)",
in.Name, position, in.SveShift)
}
if op.Shift != in.SveShift {
return 0, fmt.Errorf("%s: operand %d wants the base scaled by <<%d, got <<%d",
in.Name, position, in.SveShift, op.Shift)
}
if op.Reg < 0 || op.Reg > 30 {
return 0, fmt.Errorf("%s: operand %d's base is R%d, outside R0-R30", in.Name, position, op.Reg)
}
word = extSet(word, extFieldRm, uint32(op.Reg))
word, err := in.sveMemOff(word, op, position)
if err != nil {
return 0, err
}
return word, nil
case extMemVecOff, extMemExt32:
if !op.BaseVec {
return 0, fmt.Errorf("%s: operand %d wants a vector base, (Zn.%s{<<%d})(Rm)",
in.Name, position, in.SveBase, in.SveShift)
}
if op.Arr != in.SveBase {
return 0, fmt.Errorf("%s: operand %d's base carries arrangement %s, want %s",
in.Name, position, op.Arr, in.SveBase)
}
if in.SveMode == extMemExt32 && op.Extend != 1 {
return 0, fmt.Errorf("%s: operand %d wants the UXTW extension on the base", in.Name, position)
}
if in.SveMode == extMemVecOff && op.Extend != 0 {
return 0, fmt.Errorf("%s: operand %d takes no extension on the base", in.Name, position)
}
if op.Shift != in.SveShift {
return 0, fmt.Errorf("%s: operand %d wants the base scaled by <<%d, got <<%d",
in.Name, position, in.SveShift, op.Shift)
}
if op.Reg < 0 || op.Reg > 31 {
return 0, fmt.Errorf("%s: operand %d's base is Z%d, outside Z0-Z31", in.Name, position, op.Reg)
}
word = extSet(word, extFieldRm, uint32(op.Reg))
word, err := in.sveMemOff(word, op, position)
if err != nil {
return 0, err
}
return word, nil
case extMemImm:
if !op.BaseVec || op.Extend != 0 || op.Shift != 0 || op.Off != -1 {
return 0, fmt.Errorf("%s: operand %d wants an immediate offset on a vector base, imm(Zn.%s)",
in.Name, position, in.SveBase)
}
if op.Arr != in.SveBase {
return 0, fmt.Errorf("%s: operand %d's base carries arrangement %s, want %s",
in.Name, position, op.Arr, in.SveBase)
}
if op.Reg < 0 || op.Reg > 31 {
return 0, fmt.Errorf("%s: operand %d's base is Z%d, outside Z0-Z31", in.Name, position, op.Reg)
}
esize := int64(1) << uint(in.SveShift)
if op.Imm < 0 || op.Imm%esize != 0 || op.Imm/esize > 31 {
return 0, fmt.Errorf("%s: operand %d's displacement %d is not a multiple of %d up to %d",
in.Name, position, op.Imm, esize, 31*esize)
}
word = extSet(word, extFieldRm, uint32(op.Imm/esize))
word = extSet(word, extFieldRn, uint32(op.Reg))
return word, nil
case extMemVecBase:
if !op.BaseVec || op.Extend != 0 || op.Shift != 0 || op.Off != -1 {
return 0, fmt.Errorf("%s: operand %d wants the vector base alone, (Zn.%s)",
in.Name, position, in.SveBase)
}
if op.Arr != in.SveBase {
return 0, fmt.Errorf("%s: operand %d's base carries arrangement %s, want %s",
in.Name, position, op.Arr, in.SveBase)
}
if op.Reg < 0 || op.Reg > 31 {
return 0, fmt.Errorf("%s: operand %d's base is Z%d, outside Z0-Z31", in.Name, position, op.Reg)
}
return extSet(word, extFieldRn, uint32(op.Reg)), nil
default:
return 0, fmt.Errorf("%s: the row names no addressing mode", in.Name)
}
}
// sveMemOff validates the offset register of the parenthesised memory modes
// and fills the first-source slot: a plain R0-R30, or the stack-pointer
// spelling of the thirty-first slot.
func (in ExtInstr) sveMemOff(word uint32, op ExtOperand, position int) (uint32, error) {
if op.Off < 0 {
return 0, fmt.Errorf("%s: operand %d wants a second register in the memory operand",
in.Name, position)
}
if op.Reg31 == 2 && op.Off == 31 {
return extSet(word, extFieldRn, 31), nil
}
if op.Reg31 != 0 || op.Off < 0 || op.Off > 30 {
return 0, fmt.Errorf("%s: operand %d's offset register is outside R0-R30, with RSP allowed",
in.Name, position)
}
return extSet(word, extFieldRn, uint32(op.Off)), nil
}
// svePredicate validates the governing predicate of a gather or scatter: the
// narrow three-bit field, no arrangement suffix, zeroing on the loads and
// bare on the stores.
func (in ExtInstr) svePredicate(op ExtOperand, position int, zeroing bool) (uint32, error) {
if err := in.predicateOperand(op, position, 0, 7, ExtArrNone); err != nil {
return 0, err
}
if op.Arr != ExtArrNone {
return 0, fmt.Errorf("%s: operand %d carries no arrangement suffix, got %s",
in.Name, position, op.Arr)
}
if zeroing && op.Qual != ExtQualZeroing {
return 0, fmt.Errorf("%s: operand %d wants the zeroing qualifier, got %q",
in.Name, position, op.Qual)
}
if !zeroing && op.Qual != ExtQualNone {
return 0, fmt.Errorf("%s: operand %d takes no qualifier, got %q",
in.Name, position, op.Qual)
}
return uint32(op.Reg), nil
}
// sveList validates the destination or source vector of a gather or scatter
// against the row's locked list arrangement.
func (in ExtInstr) sveList(op ExtOperand, position int) (uint32, error) {
if op.Kind != ExtZReg {
return 0, 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 0, fmt.Errorf("%s: operand %d is Z%d, outside Z0-Z31", in.Name, position, op.Reg)
}
if op.Arr != in.Arr {
return 0, fmt.Errorf("%s: operand %d carries arrangement %s, want %s",
in.Name, position, op.Arr, in.Arr)
}
return uint32(op.Reg), nil
}
// encodeSveLoad fills the gather load: mem, Pg/Z, Zt.T. The addressing mode
// is the row's own, its fixed word carrying the mode and list-size bits, and
// the operands fill the register slots the mode names.
func (in ExtInstr) encodeSveLoad(ops []ExtOperand) ([]byte, error) {
word, err := in.sveMemFill(in.Word, ops[0], 1)
if err != nil {
return nil, err
}
pg, err := in.svePredicate(ops[1], 2, true)
if err != nil {
return nil, err
}
zt, err := in.sveList(ops[2], 3)
if err != nil {
return nil, err
}
word = extSet(word, extFieldPgN, pg)
word = extSet(word, extFieldRd, zt)
return extWordLE(word), nil
}
// encodeSveStore fills the scatter store: Zt.T, Pg, mem, mirroring the load
// with the list first and a bare governing predicate.
func (in ExtInstr) encodeSveStore(ops []ExtOperand) ([]byte, error) {
zt, err := in.sveList(ops[0], 1)
if err != nil {
return nil, err
}
pg, err := in.svePredicate(ops[1], 2, false)
if err != nil {
return nil, err
}
word, err := in.sveMemFill(in.Word, ops[2], 3)
if err != nil {
return nil, err
}
word = extSet(word, extFieldPgN, pg)
word = extSet(word, extFieldRd, zt)
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.
@@ -2983,6 +3277,540 @@ var arm64Extensions = []ExtInstr{
{Name: "ZFADDAD", Summary: "Strict floating-point accumulation of the active doubleword elements",
Word: 0x65d82000, Form: ExtFormReduceReadBack, Arr: ExtArrD, Feature: ExtFeatureSVE,
Ref: "ARM DDI 0487J: FADDA as ZFADDAD; inst_gen.go + arm64sveenc.s"},
// --- the SVE gather loads and scatter stores --------------------------------
//
// The core addressing modes of the gather/scatter family over the plain,
// sign-extended and first-fault loads and the stores: the two-general-
// register pair (Rn{<<s})(Rm), the vector base with a general offset
// (Zn.T{<<s})(Rm), the extended 32-bit offsets (Zn.S.UXTW{<<s})(Rm), the
// immediate offset imm(Zn.T) whose displacement the encoder scales by the
// access size into imm5, and the lone vector base (Zn.T) of the stores.
// Every row is one corpus line with its operand fields masked out; the
// list arrangement is part of the gather's identity (the offset index
// size) and rides Arr locked. The multi-register lists, the
// non-temporal and replicate forms, the prefetches, the VL-scaled
// offsets and the predicate-destination forms stay outside this stage.
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xa4004000, Form: ExtFormSveLoad, Arr: ExtArrB, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xa4204000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xa4404000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xa4604000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xc440c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0x84004000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1D", Summary: "Gather-load doublewords to the active lanes",
Word: 0xa5e04000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 3, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1D", Summary: "Gather-load doublewords to the active lanes",
Word: 0xa5808000, Form: ExtFormSveLoad, Arr: ExtArrQ, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 3, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1D", Summary: "Gather-load doublewords to the active lanes",
Word: 0xc5e0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1D", Summary: "Gather-load doublewords to the active lanes",
Word: 0xc5c0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xa4a04000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xa4c04000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xa4e04000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0x84a04000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xc4e0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xc4c0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0x84804000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0xa5c04000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0xa5a04000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0xa5804000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0xc4408000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0x84000000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0xa5204000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0xa5004000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0x84a00000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0xc4e08000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0xc4c08000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0x84800000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SW", Summary: "Gather-load sign-extended words to the active lanes",
Word: 0xa4804000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SW", Summary: "Gather-load sign-extended words to the active lanes",
Word: 0xc5608000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SW", Summary: "Gather-load sign-extended words to the active lanes",
Word: 0xc5408000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xa5404000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xa5604000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xa5008000, Form: ExtFormSveLoad, Arr: ExtArrQ, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0x85204000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 2, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xc560c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xc540c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0x85004000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xa4006000, Form: ExtFormSveLoad, Arr: ExtArrB, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xa4206000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xa4406000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xa4606000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xc440e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0x84006000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1D", Summary: "First-fault gather-load doublewords to the active lanes",
Word: 0xa5e06000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 3, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1D", Summary: "First-fault gather-load doublewords to the active lanes",
Word: 0xc5e0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1D", Summary: "First-fault gather-load doublewords to the active lanes",
Word: 0xc5c0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xa4a06000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xa4c06000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xa4e06000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0x84a06000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xc4e0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xc4c0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0x84806000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0xa5c06000, Form: ExtFormSveLoad, Arr: ExtArrH, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0xa5a06000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0xa5806000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0xc440a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0x84002000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0xa5206000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0xa5006000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0x84a02000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0xc4e0a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0xc4c0a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0x84802000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SW", Summary: "First-fault gather-load sign-extended words",
Word: 0xa4806000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SW", Summary: "First-fault gather-load sign-extended words",
Word: 0xc560a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SW", Summary: "First-fault gather-load sign-extended words",
Word: 0xc540a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0xa5406000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0xa5606000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0x85206000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 2, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0xc560e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0xc540e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0x85006000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe4604000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 0, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe4008000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe4408000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe400a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5e04000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 3, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5c04000, Form: ExtFormSveStore, Arr: ExtArrQ, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 3, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5a08000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5808000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5a0a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe580a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4e04000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 1, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4e08000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4a08000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4808000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4c08000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4a0a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe480a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5604000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5004000, Form: ExtFormSveStore, Arr: ExtArrQ, Feature: ExtFeatureSVE,
SveMode: extMemPair, SveShift: 2, SveBase: ExtArrNone,
Ref: "ARM DDI 0487J: gather/scatter (two general registers); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5608000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 2, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5208000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5008000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe5408000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemExt32, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (extended 32-bit offsets); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe520a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe500a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecOff, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0x8420c000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1B", Summary: "Gather-load bytes to the active lanes",
Word: 0xc420c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1D", Summary: "Gather-load doublewords to the active lanes",
Word: 0xc5a0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0x84a0c000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1H", Summary: "Gather-load halfwords to the active lanes",
Word: 0xc4a0c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0x84208000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SB", Summary: "Gather-load sign-extended bytes to the active lanes",
Word: 0xc4208000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0x84a08000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SH", Summary: "Gather-load sign-extended halfwords to the active lanes",
Word: 0xc4a08000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1SW", Summary: "Gather-load sign-extended words to the active lanes",
Word: 0xc5208000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0x8520c000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLD1W", Summary: "Gather-load words to the active lanes",
Word: 0xc520c000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0x8420e000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1B", Summary: "First-fault gather-load bytes to the active lanes",
Word: 0xc420e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1D", Summary: "First-fault gather-load doublewords to the active lanes",
Word: 0xc5a0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 3, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0x84a0e000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1H", Summary: "First-fault gather-load halfwords to the active lanes",
Word: 0xc4a0e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0x8420a000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SB", Summary: "First-fault gather-load sign-extended bytes",
Word: 0xc420a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0x84a0a000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SH", Summary: "First-fault gather-load sign-extended halfwords",
Word: 0xc4a0a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1SW", Summary: "First-fault gather-load sign-extended words",
Word: 0xc520a000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0x8520e000, Form: ExtFormSveLoad, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZLDFF1W", Summary: "First-fault gather-load words to the active lanes",
Word: 0xc520e000, Form: ExtFormSveLoad, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 2, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe460a000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1B", Summary: "Scatter-store bytes from the active lanes",
Word: 0xe440a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1D", Summary: "Scatter-store doublewords from the active lanes",
Word: 0xe5c0a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecBase, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base alone); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4e0a000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1H", Summary: "Scatter-store halfwords from the active lanes",
Word: 0xe4c0a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemImm, SveShift: 1, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (immediate offset); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe560a000, Form: ExtFormSveStore, Arr: ExtArrS, Feature: ExtFeatureSVE,
SveMode: extMemVecBase, SveShift: 0, SveBase: ExtArrS,
Ref: "ARM DDI 0487J: gather/scatter (vector base alone); inst_gen.go + arm64sveenc.s"},
{Name: "ZST1W", Summary: "Scatter-store words from the active lanes",
Word: 0xe540a000, Form: ExtFormSveStore, Arr: ExtArrD, Feature: ExtFeatureSVE,
SveMode: extMemVecBase, SveShift: 0, SveBase: ExtArrD,
Ref: "ARM DDI 0487J: gather/scatter (vector base alone); inst_gen.go + arm64sveenc.s"},
}
// Extensions returns the extended-instruction layer registered for a, outside
+84
View File
@@ -1322,3 +1322,87 @@ func TestArm64ExtStage3Golden(t *testing.T) {
}
}
}
// extSveRow finds the gather/scatter row whose mnemonic, addressing mode,
// base size, shift and list arrangement all match.
func extSveRow(t *testing.T, mnem string, mode uint8, shift int, base, arr ExtArrangement) ExtInstr {
t.Helper()
for _, in := range Extensions(ARM64) {
if in.Name == mnem && in.Form.Arity() == 3 && in.SveMode == mode &&
in.SveShift == shift && in.SveBase == base && in.Arr == arr {
return in
}
}
t.Fatalf("no extended %s with mode %d, shift %d, base %s and list %s", mnem, mode, shift, base, arr)
return ExtInstr{}
}
// TestArm64ExtGatherGolden pins the gather/scatter family against the
// toolchain-generated corpus at the metadata layer: one row per addressing
// mode, the want word that corpus line's own encoding. The asm-level
// TestArm64AssembleExtensionGatherGolden pins every corpus line of the
// scope end to end; these rows prove the forms and the operand builders
// the registry exposes.
func TestArm64ExtGatherGolden(t *testing.T) {
for _, tt := range []struct {
name string
mnem string
mode uint8
shift int
base ExtArrangement
arr ExtArrangement
ops []ExtOperand
want uint32
}{
{"ZLD1B (R6)(R14), P4.Z, [Z13.B]", "ZLD1B", extMemPair, 0, ExtArrNone, ExtArrB,
[]ExtOperand{ExtSveMemPair(6, 0, 14, false), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrB)},
0xa40651cd},
{"ZLD1H (R6<<1)(R14), P4.Z, [Z13.H]", "ZLD1H", extMemPair, 1, ExtArrNone, ExtArrH,
[]ExtOperand{ExtSveMemPair(6, 1, 14, false), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrH)},
0xa4a651cd},
{"ZLD1B (Z10.D)(R19), P3.Z, [Z15.D]", "ZLD1B", extMemVecOff, 0, ExtArrD, ExtArrD,
[]ExtOperand{ExtSveMemVector(10, ExtArrD, 0, 19), ExtPredicate(3, ExtQualZeroing), ExtVector(15, ExtArrD)},
0xc44ace6f},
{"ZLD1D (Z23.D<<3)(R24), P1.Z, [Z22.D]", "ZLD1D", extMemVecOff, 3, ExtArrD, ExtArrD,
[]ExtOperand{ExtSveMemVector(23, ExtArrD, 3, 24), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrD)},
0xc5f7c716},
{"ZLD1H (Z4.S.UXTW<<1)(R3), P3.Z, [Z4.S]", "ZLD1H", extMemExt32, 1, ExtArrS, ExtArrS,
[]ExtOperand{ExtSveMemExtended(4, false, 1, 3), ExtPredicate(3, ExtQualZeroing), ExtVector(4, ExtArrS)},
0x84a44c64},
{"ZLD1SB (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", "ZLD1SB", extMemExt32, 0, ExtArrS, ExtArrS,
[]ExtOperand{ExtSveMemExtended(4, false, 0, 3), ExtPredicate(3, ExtQualZeroing), ExtVector(4, ExtArrS)},
0x84040c64},
{"ZLD1B 6(Z7.S), P4.Z, [Z13.S]", "ZLD1B", extMemImm, 0, ExtArrS, ExtArrS,
[]ExtOperand{ExtSveMemImmediate(7, ExtArrS, 6), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrS)},
0x8426d0ed},
{"ZLD1D 8(Z14.D), P6.Z, [Z6.D]", "ZLD1D", extMemImm, 3, ExtArrD, ExtArrD,
[]ExtOperand{ExtSveMemImmediate(14, ExtArrD, 8), ExtPredicate(6, ExtQualZeroing), ExtVector(6, ExtArrD)},
0xc5a1d9c6},
{"ZLDFF1SW 12(Z0.D), P6.Z, [Z25.D]", "ZLDFF1SW", extMemImm, 2, ExtArrD, ExtArrD,
[]ExtOperand{ExtSveMemImmediate(0, ExtArrD, 12), ExtPredicate(6, ExtQualZeroing), ExtVector(25, ExtArrD)},
0xc523b819},
{"ZST1B [Z7.D], P4, (R21)(R7)", "ZST1B", extMemPair, 0, ExtArrNone, ExtArrD,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicateSized(4, ExtArrNone), ExtSveMemPair(21, 0, 7, false)},
0xe47550e7},
{"ZST1D [Z8.D], P3, (Z6.D)(RSP)", "ZST1D", extMemVecOff, 0, ExtArrD, ExtArrD,
[]ExtOperand{ExtVector(8, ExtArrD), ExtPredicateSized(3, ExtArrNone), ExtOperand{Kind: ExtSveMem, Reg: 6, Arr: ExtArrD, Off: 31, Reg31: 2, BaseVec: true}},
0xe586afe8},
{"ZST1W [Z16.D], P2, (Z5.D)", "ZST1W", extMemVecBase, 0, ExtArrD, ExtArrD,
[]ExtOperand{ExtVector(16, ExtArrD), ExtPredicateSized(2, ExtArrNone), ExtSveMemVector(5, ExtArrD, 0, -1)},
0xe540a8b0},
{"ZST1H [Z8.S], P3, 6(Z15.S)", "ZST1H", extMemImm, 1, ExtArrS, ExtArrS,
[]ExtOperand{ExtVector(8, ExtArrS), ExtPredicateSized(3, ExtArrNone), ExtSveMemImmediate(15, ExtArrS, 6)},
0xe4e3ade8},
} {
mode := tt.mode
in := extSveRow(t, tt.mnem, mode, tt.shift, tt.base, 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)
}
}
}
+130
View File
@@ -79,6 +79,20 @@ func arm64ExtStatement(mnem string, ops []*ast.Operand) (extops []arch.ExtOperan
out = append(out, ext)
continue
}
// The gather/scatter destination list, [Z13.B]: one scalable vector
// in brackets, its arrangement part of the instruction's identity.
if strings.HasPrefix(text, "[") && strings.HasSuffix(text, "]") {
if ext, ok := arm64ExtVector(strings.Trim(text, "[]")); ok {
out = append(out, ext)
continue
}
}
// The gather/scatter memory operand: a parenthesised register pair,
// an immediate-offset base or a lone vector base.
if ext, ok := arm64ExtSveMem(text); ok {
out = append(out, ext)
continue
}
if ext, ok := arm64ExtVector(text); ok {
out = append(out, ext)
continue
@@ -285,6 +299,122 @@ func arm64ExtSIMD(text string) (arch.ExtOperand, bool) {
return arch.ExtOperand{Kind: arch.ExtVReg, Reg: reg}, true
}
// arm64ExtSveMem parses the gather/scatter memory operand off a normalised
// operand text: the parenthesised pair (R6)(R14), (Z23.D<<1)(R24) and
// (Z4.S.UXTW)(R3), the immediate-offset base 6(Z7.S), and the lone vector
// base (Z5.D) of the stores. The second parenthesis accepts the
// stack-pointer spelling RSP; the ranges and the mode's own rules are left
// to the encoding, whose diagnostics name them.
func arm64ExtSveMem(text string) (arch.ExtOperand, bool) {
// The immediate-offset spelling: digits straight before the parenthesis.
if i := strings.IndexByte(text, '('); i > 0 && i == strings.LastIndexByte(text, '(') {
disp, err := strconv.ParseUint(text[:i], 10, 32)
if err == nil && strings.HasSuffix(text, ")") {
op, ok := arm64ExtSveMemGroup(text[i+1 : len(text)-1])
if !ok {
return arch.ExtOperand{}, false
}
if !op.BaseVec || op.Extend != 0 || op.Shift != 0 {
return arch.ExtOperand{}, false
}
op.Imm = int64(disp)
return op, true
}
}
// The parenthesised forms: one group or two.
rest, ok := strings.CutPrefix(text, "(")
if !ok || !strings.HasSuffix(text, ")") {
return arch.ExtOperand{}, false
}
rest = rest[:len(rest)-1]
first := rest
op := arch.ExtOperand{Off: -1}
if base, second, found := strings.Cut(rest, ")("); found {
first = base
off, ok := arm64ExtSveMemOffset(second)
if !ok {
return arch.ExtOperand{}, false
}
op = off
}
group, ok := arm64ExtSveMemGroup(first)
if !ok {
return arch.ExtOperand{}, false
}
group.Off = op.Off
group.Reg31 = op.Reg31
return group, true
}
// arm64ExtSveMemGroup parses one parenthesised memory register: R6, R6<<3,
// Z23.D, Z23.D<<1, Z4.S.UXTW or Z7.D.SXTW. The general registers run
// R0-R30 and the scalable vectors Z0-Z31 with an .S or .D element size and
// an optional UXTW or SXTW extension; the ranges are left to the encoding.
func arm64ExtSveMemGroup(text string) (arch.ExtOperand, bool) {
op := arch.ExtOperand{Kind: arch.ExtSveMem, Off: -1}
if base, shift, found := strings.Cut(text, "<<"); found {
n, err := strconv.Atoi(shift)
if err != nil || n < 0 {
return arch.ExtOperand{}, false
}
op.Shift = n
text = base
}
parts := strings.Split(text, ".")
switch parts[0][0] {
case 'R':
reg, err := strconv.Atoi(parts[0][1:])
if err != nil || len(parts) != 1 {
return arch.ExtOperand{}, false
}
op.Reg = reg
case 'Z':
reg, err := strconv.Atoi(parts[0][1:])
if err != nil || len(parts) < 2 || len(parts) > 3 {
return arch.ExtOperand{}, false
}
switch parts[1] {
case "S":
op.Arr = arch.ExtArrS
case "D":
op.Arr = arch.ExtArrD
default:
return arch.ExtOperand{}, false
}
op.Reg = reg
op.BaseVec = true
if len(parts) == 3 {
switch parts[2] {
case "UXTW":
op.Extend = 1
case "SXTW":
op.Extend = 2
default:
return arch.ExtOperand{}, false
}
}
default:
return arch.ExtOperand{}, false
}
return op, true
}
// arm64ExtSveMemOffset parses the second parenthesis of a gather/scatter
// memory operand: a plain R0-R30 or the stack-pointer spelling RSP.
func arm64ExtSveMemOffset(text string) (arch.ExtOperand, bool) {
if text == "RSP" {
return arch.ExtOperand{Off: 31, Reg31: 2}, true
}
if len(text) < 2 || text[0] != 'R' {
return arch.ExtOperand{}, false
}
reg, err := strconv.Atoi(text[1:])
if err != nil {
return arch.ExtOperand{}, false
}
return arch.ExtOperand{Off: reg}, true
}
// arm64ExtRegDigits parses the digits and optional arrangement suffix of a
// register spelling once the letter prefix is gone.
func arm64ExtRegDigits(text string) (reg int, arr arch.ExtArrangement, ok bool) {
+209
View File
@@ -562,3 +562,212 @@ func TestArm64AssembleExtensionStage3Refusals(t *testing.T) {
}
}
}
// TestArm64AssembleExtensionGatherGolden drives the gather/scatter family
// through the full assembler: every corpus line of the scope the layer
// covers, corpus text in, corpus word out. The scope is the plain,
// sign-extended and first-fault loads and the stores over the core
// addressing modes: the two-general-register pair, the vector base with a
// general offset, the extended 32-bit offsets, the immediate offset on a
// vector base and the lone vector base of the stores.
func TestArm64AssembleExtensionGatherGolden(t *testing.T) {
tests := []struct {
stmt string
want uint32
}{
{"ZLD1B (R6)(R14), P4.Z, [Z13.B]", 0xa40651cd},
{"ZLD1B (R6)(R14), P4.Z, [Z13.H]", 0xa42651cd},
{"ZLD1B (R6)(R14), P4.Z, [Z13.S]", 0xa44651cd},
{"ZLD1B (R6)(R14), P4.Z, [Z13.D]", 0xa46651cd},
{"ZLD1B (Z10.D)(R19), P3.Z, [Z15.D]", 0xc44ace6f},
{"ZLD1B (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84044c64},
{"ZLD1B (Z6.D)(R14), P4.Z, [Z13.D]", 0xc446d1cd},
{"ZLD1D (R6<<3)(R14), P4.Z, [Z13.D]", 0xa5e651cd},
{"ZLD1D (R6<<3)(R14), P4.Z, [Z13.Q]", 0xa58691cd},
{"ZLD1D (Z23.D<<3)(R24), P1.Z, [Z22.D]", 0xc5f7c716},
{"ZLD1D (Z10.D)(R19), P3.Z, [Z15.D]", 0xc5cace6f},
{"ZLD1D (Z6.D<<3)(R14), P4.Z, [Z13.D]", 0xc5e6d1cd},
{"ZLD1D (Z6.D)(R14), P4.Z, [Z13.D]", 0xc5c6d1cd},
{"ZLD1H (R6<<1)(R14), P4.Z, [Z13.H]", 0xa4a651cd},
{"ZLD1H (R6<<1)(R14), P4.Z, [Z13.S]", 0xa4c651cd},
{"ZLD1H (R6<<1)(R14), P4.Z, [Z13.D]", 0xa4e651cd},
{"ZLD1H (Z4.S.UXTW<<1)(R3), P3.Z, [Z4.S]", 0x84a44c64},
{"ZLD1H (Z23.D<<1)(R24), P1.Z, [Z22.D]", 0xc4f7c716},
{"ZLD1H (Z10.D)(R19), P3.Z, [Z15.D]", 0xc4cace6f},
{"ZLD1H (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84844c64},
{"ZLD1H (Z6.D<<1)(R14), P4.Z, [Z13.D]", 0xc4e6d1cd},
{"ZLD1H (Z6.D)(R14), P4.Z, [Z13.D]", 0xc4c6d1cd},
{"ZLD1SB (R6)(R14), P4.Z, [Z13.H]", 0xa5c651cd},
{"ZLD1SB (R6)(R14), P4.Z, [Z13.S]", 0xa5a651cd},
{"ZLD1SB (R6)(R14), P4.Z, [Z13.D]", 0xa58651cd},
{"ZLD1SB (Z10.D)(R19), P3.Z, [Z15.D]", 0xc44a8e6f},
{"ZLD1SB (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84040c64},
{"ZLD1SB (Z6.D)(R14), P4.Z, [Z13.D]", 0xc44691cd},
{"ZLD1SH (R6<<1)(R14), P4.Z, [Z13.S]", 0xa52651cd},
{"ZLD1SH (R6<<1)(R14), P4.Z, [Z13.D]", 0xa50651cd},
{"ZLD1SH (Z4.S.UXTW<<1)(R3), P3.Z, [Z4.S]", 0x84a40c64},
{"ZLD1SH (Z23.D<<1)(R24), P1.Z, [Z22.D]", 0xc4f78716},
{"ZLD1SH (Z10.D)(R19), P3.Z, [Z15.D]", 0xc4ca8e6f},
{"ZLD1SH (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84840c64},
{"ZLD1SH (Z6.D<<1)(R14), P4.Z, [Z13.D]", 0xc4e691cd},
{"ZLD1SH (Z6.D)(R14), P4.Z, [Z13.D]", 0xc4c691cd},
{"ZLD1SW (R6<<2)(R14), P4.Z, [Z13.D]", 0xa48651cd},
{"ZLD1SW (Z23.D<<2)(R24), P1.Z, [Z22.D]", 0xc5778716},
{"ZLD1SW (Z10.D)(R19), P3.Z, [Z15.D]", 0xc54a8e6f},
{"ZLD1SW (Z6.D<<2)(R14), P4.Z, [Z13.D]", 0xc56691cd},
{"ZLD1SW (Z6.D)(R14), P4.Z, [Z13.D]", 0xc54691cd},
{"ZLD1W (R6<<2)(R14), P4.Z, [Z13.S]", 0xa54651cd},
{"ZLD1W (R6<<2)(R14), P4.Z, [Z13.D]", 0xa56651cd},
{"ZLD1W (R6<<2)(R14), P4.Z, [Z13.Q]", 0xa50691cd},
{"ZLD1W (Z4.S.UXTW<<2)(R3), P3.Z, [Z4.S]", 0x85244c64},
{"ZLD1W (Z23.D<<2)(R24), P1.Z, [Z22.D]", 0xc577c716},
{"ZLD1W (Z10.D)(R19), P3.Z, [Z15.D]", 0xc54ace6f},
{"ZLD1W (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x85044c64},
{"ZLD1W (Z6.D<<2)(R14), P4.Z, [Z13.D]", 0xc566d1cd},
{"ZLD1W (Z6.D)(R14), P4.Z, [Z13.D]", 0xc546d1cd},
{"ZLDFF1B (R6)(R14), P4.Z, [Z13.B]", 0xa40671cd},
{"ZLDFF1B (R6)(R14), P4.Z, [Z13.H]", 0xa42671cd},
{"ZLDFF1B (R6)(R14), P4.Z, [Z13.S]", 0xa44671cd},
{"ZLDFF1B (R6)(R14), P4.Z, [Z13.D]", 0xa46671cd},
{"ZLDFF1B (Z10.D)(R19), P3.Z, [Z15.D]", 0xc44aee6f},
{"ZLDFF1B (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84046c64},
{"ZLDFF1B (Z6.D)(R14), P4.Z, [Z13.D]", 0xc446f1cd},
{"ZLDFF1D (R6<<3)(R14), P4.Z, [Z13.D]", 0xa5e671cd},
{"ZLDFF1D (Z23.D<<3)(R24), P1.Z, [Z22.D]", 0xc5f7e716},
{"ZLDFF1D (Z10.D)(R19), P3.Z, [Z15.D]", 0xc5caee6f},
{"ZLDFF1D (Z6.D<<3)(R14), P4.Z, [Z13.D]", 0xc5e6f1cd},
{"ZLDFF1D (Z6.D)(R14), P4.Z, [Z13.D]", 0xc5c6f1cd},
{"ZLDFF1H (R6<<1)(R14), P4.Z, [Z13.H]", 0xa4a671cd},
{"ZLDFF1H (R6<<1)(R14), P4.Z, [Z13.S]", 0xa4c671cd},
{"ZLDFF1H (R6<<1)(R14), P4.Z, [Z13.D]", 0xa4e671cd},
{"ZLDFF1H (Z4.S.UXTW<<1)(R3), P3.Z, [Z4.S]", 0x84a46c64},
{"ZLDFF1H (Z23.D<<1)(R24), P1.Z, [Z22.D]", 0xc4f7e716},
{"ZLDFF1H (Z10.D)(R19), P3.Z, [Z15.D]", 0xc4caee6f},
{"ZLDFF1H (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84846c64},
{"ZLDFF1H (Z6.D<<1)(R14), P4.Z, [Z13.D]", 0xc4e6f1cd},
{"ZLDFF1H (Z6.D)(R14), P4.Z, [Z13.D]", 0xc4c6f1cd},
{"ZLDFF1SB (R6)(R14), P4.Z, [Z13.H]", 0xa5c671cd},
{"ZLDFF1SB (R6)(R14), P4.Z, [Z13.S]", 0xa5a671cd},
{"ZLDFF1SB (R6)(R14), P4.Z, [Z13.D]", 0xa58671cd},
{"ZLDFF1SB (Z10.D)(R19), P3.Z, [Z15.D]", 0xc44aae6f},
{"ZLDFF1SB (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84042c64},
{"ZLDFF1SB (Z6.D)(R14), P4.Z, [Z13.D]", 0xc446b1cd},
{"ZLDFF1SH (R6<<1)(R14), P4.Z, [Z13.S]", 0xa52671cd},
{"ZLDFF1SH (R6<<1)(R14), P4.Z, [Z13.D]", 0xa50671cd},
{"ZLDFF1SH (Z4.S.UXTW<<1)(R3), P3.Z, [Z4.S]", 0x84a42c64},
{"ZLDFF1SH (Z23.D<<1)(R24), P1.Z, [Z22.D]", 0xc4f7a716},
{"ZLDFF1SH (Z10.D)(R19), P3.Z, [Z15.D]", 0xc4caae6f},
{"ZLDFF1SH (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x84842c64},
{"ZLDFF1SH (Z6.D<<1)(R14), P4.Z, [Z13.D]", 0xc4e6b1cd},
{"ZLDFF1SH (Z6.D)(R14), P4.Z, [Z13.D]", 0xc4c6b1cd},
{"ZLDFF1SW (R6<<2)(R14), P4.Z, [Z13.D]", 0xa48671cd},
{"ZLDFF1SW (Z23.D<<2)(R24), P1.Z, [Z22.D]", 0xc577a716},
{"ZLDFF1SW (Z10.D)(R19), P3.Z, [Z15.D]", 0xc54aae6f},
{"ZLDFF1SW (Z6.D<<2)(R14), P4.Z, [Z13.D]", 0xc566b1cd},
{"ZLDFF1SW (Z6.D)(R14), P4.Z, [Z13.D]", 0xc546b1cd},
{"ZLDFF1W (R6<<2)(R14), P4.Z, [Z13.S]", 0xa54671cd},
{"ZLDFF1W (R6<<2)(R14), P4.Z, [Z13.D]", 0xa56671cd},
{"ZLDFF1W (Z4.S.UXTW<<2)(R3), P3.Z, [Z4.S]", 0x85246c64},
{"ZLDFF1W (Z23.D<<2)(R24), P1.Z, [Z22.D]", 0xc577e716},
{"ZLDFF1W (Z10.D)(R19), P3.Z, [Z15.D]", 0xc54aee6f},
{"ZLDFF1W (Z4.S.UXTW)(R3), P3.Z, [Z4.S]", 0x85046c64},
{"ZLDFF1W (Z6.D<<2)(R14), P4.Z, [Z13.D]", 0xc566f1cd},
{"ZLDFF1W (Z6.D)(R14), P4.Z, [Z13.D]", 0xc546f1cd},
{"ZST1B [Z7.D], P4, (R21)(R7)", 0xe47550e7},
{"ZST1B [Z6.D], P4, (Z21.D.UXTW)(R7)", 0xe41590e6},
{"ZST1B [Z6.S], P4, (Z21.S.UXTW)(R7)", 0xe45590e6},
{"ZST1B [Z8.D], P3, (Z6.D)(RSP)", 0xe406afe8},
{"ZST1D [Z8.D], P3, (R6<<3)(RSP)", 0xe5e64fe8},
{"ZST1D [Z8.Q], P3, (R6<<3)(RSP)", 0xe5c64fe8},
{"ZST1D [Z6.D], P4, (Z21.D.UXTW<<3)(R7)", 0xe5b590e6},
{"ZST1D [Z6.D], P4, (Z21.D.UXTW)(R7)", 0xe59590e6},
{"ZST1D [Z8.D], P3, (Z6.D<<3)(RSP)", 0xe5a6afe8},
{"ZST1D [Z8.D], P3, (Z6.D)(RSP)", 0xe586afe8},
{"ZST1H [Z7.D], P4, (R21<<1)(R7)", 0xe4f550e7},
{"ZST1H [Z6.S], P4, (Z21.S.UXTW<<1)(R7)", 0xe4f590e6},
{"ZST1H [Z6.D], P4, (Z21.D.UXTW<<1)(R7)", 0xe4b590e6},
{"ZST1H [Z6.D], P4, (Z21.D.UXTW)(R7)", 0xe49590e6},
{"ZST1H [Z6.S], P4, (Z21.S.UXTW)(R7)", 0xe4d590e6},
{"ZST1H [Z8.D], P3, (Z6.D<<1)(RSP)", 0xe4a6afe8},
{"ZST1H [Z8.D], P3, (Z6.D)(RSP)", 0xe486afe8},
{"ZST1W [Z7.D], P4, (R21<<2)(R7)", 0xe57550e7},
{"ZST1W [Z8.Q], P3, (R6<<2)(RSP)", 0xe5064fe8},
{"ZST1W [Z6.S], P4, (Z21.S.UXTW<<2)(R7)", 0xe57590e6},
{"ZST1W [Z6.D], P4, (Z21.D.UXTW<<2)(R7)", 0xe53590e6},
{"ZST1W [Z6.D], P4, (Z21.D.UXTW)(R7)", 0xe51590e6},
{"ZST1W [Z6.S], P4, (Z21.S.UXTW)(R7)", 0xe55590e6},
{"ZST1W [Z8.D], P3, (Z6.D<<2)(RSP)", 0xe526afe8},
{"ZST1W [Z8.D], P3, (Z6.D)(RSP)", 0xe506afe8},
{"ZLD1B 6(Z7.S), P4.Z, [Z13.S]", 0x8426d0ed},
{"ZLD1B 6(Z7.D), P4.Z, [Z13.D]", 0xc426d0ed},
{"ZLD1D 8(Z14.D), P6.Z, [Z6.D]", 0xc5a1d9c6},
{"ZLD1H 6(Z7.S), P4.Z, [Z13.S]", 0x84a3d0ed},
{"ZLD1H 6(Z7.D), P4.Z, [Z13.D]", 0xc4a3d0ed},
{"ZLD1SB 6(Z7.S), P4.Z, [Z13.S]", 0x842690ed},
{"ZLD1SB 6(Z7.D), P4.Z, [Z13.D]", 0xc42690ed},
{"ZLD1SH 6(Z7.S), P4.Z, [Z13.S]", 0x84a390ed},
{"ZLD1SH 6(Z7.D), P4.Z, [Z13.D]", 0xc4a390ed},
{"ZLD1SW 12(Z0.D), P6.Z, [Z25.D]", 0xc5239819},
{"ZLD1W 12(Z0.S), P6.Z, [Z25.S]", 0x8523d819},
{"ZLD1W 12(Z0.D), P6.Z, [Z25.D]", 0xc523d819},
{"ZLDFF1B 6(Z7.S), P4.Z, [Z13.S]", 0x8426f0ed},
{"ZLDFF1B 6(Z7.D), P4.Z, [Z13.D]", 0xc426f0ed},
{"ZLDFF1D 8(Z14.D), P6.Z, [Z6.D]", 0xc5a1f9c6},
{"ZLDFF1H 6(Z7.S), P4.Z, [Z13.S]", 0x84a3f0ed},
{"ZLDFF1H 6(Z7.D), P4.Z, [Z13.D]", 0xc4a3f0ed},
{"ZLDFF1SB 6(Z7.S), P4.Z, [Z13.S]", 0x8426b0ed},
{"ZLDFF1SB 6(Z7.D), P4.Z, [Z13.D]", 0xc426b0ed},
{"ZLDFF1SH 6(Z7.S), P4.Z, [Z13.S]", 0x84a3b0ed},
{"ZLDFF1SH 6(Z7.D), P4.Z, [Z13.D]", 0xc4a3b0ed},
{"ZLDFF1SW 12(Z0.D), P6.Z, [Z25.D]", 0xc523b819},
{"ZLDFF1W 12(Z0.S), P6.Z, [Z25.S]", 0x8523f819},
{"ZLDFF1W 12(Z0.D), P6.Z, [Z25.D]", 0xc523f819},
{"ZST1B [Z8.S], P3, 6(Z15.S)", 0xe466ade8},
{"ZST1B [Z8.D], P3, 6(Z15.D)", 0xe446ade8},
{"ZST1D [Z16.D], P2, (Z5.D)", 0xe5c0a8b0},
{"ZST1H [Z8.S], P3, 6(Z15.S)", 0xe4e3ade8},
{"ZST1H [Z8.D], P3, 6(Z15.D)", 0xe4c3ade8},
{"ZST1W [Z16.S], P2, (Z5.S)", 0xe560a8b0},
{"ZST1W [Z16.D], P2, (Z5.D)", 0xe540a8b0},
}
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)
}
}
}
// TestArm64AssembleExtensionGatherRefusals pins the diagnostics the
// gather/scatter statements get from the layer: the addressing-mode
// mismatches, the locked list arrangements, the zeroing qualifier of the
// loads against the bare predicates of the stores, and the immediate
// scaling.
func TestArm64AssembleExtensionGatherRefusals(t *testing.T) {
tests := []struct {
stmt string
want string
}{
{"ZLD1B (R6<<1)(R14), P4.Z, [Z13.B]", "scaled by <<0"},
{"ZLD1B (Z6.D)(R14), P4.Z, [Z13.B]", "wants two general registers"},
{"ZLD1B (Z6.S)(R14), P4.Z, [Z13.S]", "wants two general registers"},
{"ZLD1B (R6)(R14), P4/M, [Z13.B]", "wants the zeroing qualifier"},
{"ZLD1B (R6)(R14), P9.Z, [Z13.B]", "outside P0-P7"},
{"ZLD1B (R6)(ZR), P4.Z, [Z13.B]", "is not an extended-layer operand"},
{"ZLD1B (RSP)(R14), P4.Z, [Z13.B]", "is not an extended-layer operand"},
{"ZLD1D 12(Z14.D), P6.Z, [Z6.D]", "wants two general registers"},
{"ZLD1D 264(Z14.D), P6.Z, [Z6.D]", "wants two general registers"},
{"ZST1B [Z7.D], P4/Z, (R21)(R7)", "takes no qualifier"},
{"ZST1B [Z7.S], P4, (R21)(R7)", "carries arrangement .S, want .D"},
{"ZST1B [Z7.D], P4, (Z21.S)(R7)", "wants two general registers"},
}
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)
}
}
}
+22 -2
View File
@@ -360,12 +360,32 @@ func TestExtensionNamesARM64(t *testing.T) {
"ZFADDAH",
"ZFADDAS",
"ZFADDAD",
// The gather loads and scatter stores: plain, sign-extended and
// first-fault loads, and the stores, in first-occurrence order.
"ZLD1B",
"ZLD1D",
"ZLD1H",
"ZLD1SB",
"ZLD1SH",
"ZLD1SW",
"ZLD1W",
"ZLDFF1B",
"ZLDFF1D",
"ZLDFF1H",
"ZLDFF1SB",
"ZLDFF1SH",
"ZLDFF1SW",
"ZLDFF1W",
"ZST1B",
"ZST1D",
"ZST1H",
"ZST1W",
}
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 != 251 {
t.Errorf("the family registers %d instructions, want 251", n)
if n := len(arch.Extensions(arch.ARM64)); n != 381 {
t.Errorf("the family registers %d instructions, want 381", n)
}
}