feat(arch): the SVE2 shift-by-vector family
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
b93fccc075
commit
bd80499c74
4 files changed
+135
-4
No files matched your search
+85
-2
@@ -679,6 +679,11 @@ const (
|
||||
// the predicate in the narrow governing field and the vector in the
|
||||
// destination slot, the reduction class's own layout.
|
||||
ExtFormQuadReduce
|
||||
// ExtFormShiftWide is the wide-vector shift, ZASR Z7.D, Z6.H, Z13.H:
|
||||
// the shift amounts ride a double-width vector locked to .D while the
|
||||
// shifted data shares one narrower arrangement, which feeds the size
|
||||
// field. Operands: Zm.D, Zn.T, Zd.T.
|
||||
ExtFormShiftWide
|
||||
)
|
||||
|
||||
// Arity returns the operand count the form takes.
|
||||
@@ -716,7 +721,7 @@ func (f ExtForm) Arity() int {
|
||||
return 2
|
||||
case ExtFormReduceReadBack:
|
||||
return 4
|
||||
case ExtFormSveLoad, ExtFormSveStore, ExtFormNarrow, ExtFormQuadReduce:
|
||||
case ExtFormSveLoad, ExtFormSveStore, ExtFormNarrow, ExtFormQuadReduce, ExtFormShiftWide:
|
||||
return 3
|
||||
case ExtFormNone:
|
||||
return 0
|
||||
@@ -787,7 +792,7 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
||||
return []ExtOperandKind{ExtSveMem, ExtPReg, ExtZReg}
|
||||
case ExtFormSveStore:
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
||||
case ExtFormNarrow:
|
||||
case ExtFormNarrow, ExtFormShiftWide:
|
||||
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
||||
case ExtFormQuadReduce:
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtVReg}
|
||||
@@ -917,6 +922,8 @@ func (f ExtForm) String() string {
|
||||
return "narrowing two-to-one"
|
||||
case ExtFormQuadReduce:
|
||||
return "quadword reduction"
|
||||
case ExtFormShiftWide:
|
||||
return "wide shift"
|
||||
case ExtFormNone:
|
||||
return "no operands"
|
||||
default:
|
||||
@@ -1173,6 +1180,8 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeNarrow(ops)
|
||||
case ExtFormQuadReduce:
|
||||
return in.encodeQuadReduce(ops)
|
||||
case ExtFormShiftWide:
|
||||
return in.encodeShiftWide(ops)
|
||||
case ExtFormNone:
|
||||
if len(ops) != 0 {
|
||||
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
||||
@@ -2629,6 +2638,42 @@ func (in ExtInstr) encodeQuadReduce(ops []ExtOperand) ([]byte, error) {
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeShiftWide fills the wide-vector shift: Zm.D, Zn.T, Zd.T. The shift
|
||||
// amounts ride a double-width vector locked to .D while the shifted data
|
||||
// carries one shared narrower arrangement, which feeds the size field.
|
||||
func (in ExtInstr) encodeShiftWide(ops []ExtOperand) ([]byte, error) {
|
||||
zm, zn, zd := ops[0], ops[1], ops[2]
|
||||
if err := in.zVector(zm, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zm.Arr != ExtArrD {
|
||||
return nil, fmt.Errorf("%s: operand 1 carries arrangement %s, want .D",
|
||||
in.Name, zm.Arr)
|
||||
}
|
||||
if err := in.zVector(zn, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.zVector(zd, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if zn.Arr != zd.Arr {
|
||||
return nil, fmt.Errorf("%s: operands 2 and 3 carry arrangements %s and %s, they must match",
|
||||
in.Name, zn.Arr, zd.Arr)
|
||||
}
|
||||
size, err := in.zSize(zn.Arr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
word := in.Word
|
||||
word = extSet(word, extFieldRm, uint32(zm.Reg))
|
||||
word = extSet(word, extFieldRn, uint32(zn.Reg))
|
||||
word = extSet(word, extFieldRd, uint32(zd.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.
|
||||
@@ -3259,6 +3304,44 @@ var arm64Extensions = []ExtInstr{
|
||||
Word: 0x040f2000, Form: ExtFormQuadReduce, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
|
||||
Ref: "ARM DDI 0487J SVE2.1: ZUMINQV; inst_gen.go + arm64sveenc.s"},
|
||||
|
||||
// --- the SVE2 shift-by-vector family --------------------------------------
|
||||
//
|
||||
// The arithmetic, logical and rounding shift steps over a vector of
|
||||
// shift amounts: the predicated-source shapes share one arrangement,
|
||||
// and the wide three-vector shape takes its amounts from a double-width
|
||||
// vector locked to .D. The shift-by-immediate shapes of the same
|
||||
// mnemonics (the tsz:imm3 class) are not wired yet. Provenance as
|
||||
// above: the toolchain encoding table and its generated corpus, both
|
||||
// produced from Arm's official ISA description, and the golden test
|
||||
// pins every corpus line of the covered shapes.
|
||||
{Name: "ZASR", Summary: "Shift right arithmetic by a vector, merging",
|
||||
Word: 0x04108000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZASR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZASR", Summary: "Shift right arithmetic by a wide vector, unpredicated",
|
||||
Word: 0x04208000, Form: ExtFormShiftWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZASR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZASRR", Summary: "Shift right arithmetic by a vector with rounding, merging",
|
||||
Word: 0x04148000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZASRR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSL", Summary: "Shift left by a vector, merging",
|
||||
Word: 0x04138000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSL; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSL", Summary: "Shift left by a wide vector, unpredicated",
|
||||
Word: 0x04208c00, Form: ExtFormShiftWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSL; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSLR", Summary: "Shift left by a vector with rounding, merging",
|
||||
Word: 0x04178000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSLR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSR", Summary: "Shift right logical by a vector, merging",
|
||||
Word: 0x04118000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSR", Summary: "Shift right logical by a wide vector, unpredicated",
|
||||
Word: 0x04208400, Form: ExtFormShiftWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSR; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZLSRR", Summary: "Shift right logical by a vector with rounding, merging",
|
||||
Word: 0x04158000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSRR; inst_gen.go + arm64sveenc.s"},
|
||||
|
||||
// --- the SVE2 crypto family ----------------------------------------------
|
||||
//
|
||||
// The multi-precision carry steps (ADCLB, ADCLT, SBCLB, SBCLT), the SHA3
|
||||
|
||||
@@ -1440,6 +1440,37 @@ func TestArm64ExtStage4Golden(t *testing.T) {
|
||||
{"ZFMINQV Z25.S, P3, V5.S4", "ZFMINQV", ExtFormQuadReduce, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(25, ExtArrS), ExtPredicateSized(3, ExtArrNone), ExtOperand{Kind: ExtVReg, Reg: 5, Arr: ExtArrS}},
|
||||
0x6497af25},
|
||||
// The shift-by-vector family.
|
||||
{"ZASR Z15.B, Z0.B, P3.M, Z0.B", "ZASR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(0, ExtArrB)},
|
||||
0x04108de0},
|
||||
{"ZASR Z2.D, Z10.D, P3.M, Z10.D", "ZASR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(2, ExtArrD), ExtVector(10, ExtArrD), ExtPredicate(3, ExtQualMerging), ExtVector(10, ExtArrD)},
|
||||
0x04d08c4a},
|
||||
{"ZASR Z7.D, Z6.H, Z13.H", "ZASR", ExtFormShiftWide, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrH), ExtVector(13, ExtArrH)},
|
||||
0x046780cd},
|
||||
{"ZASRR Z15.B, Z0.B, P3.M, Z0.B", "ZASRR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(0, ExtArrB)},
|
||||
0x04148de0},
|
||||
{"ZLSL Z2.D, Z10.D, P3.M, Z10.D", "ZLSL", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(2, ExtArrD), ExtVector(10, ExtArrD), ExtPredicate(3, ExtQualMerging), ExtVector(10, ExtArrD)},
|
||||
0x04d38c4a},
|
||||
{"ZLSL Z7.D, Z6.H, Z13.H", "ZLSL", ExtFormShiftWide, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrH), ExtVector(13, ExtArrH)},
|
||||
0x04678ccd},
|
||||
{"ZLSLR Z15.B, Z0.B, P3.M, Z0.B", "ZLSLR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(0, ExtArrB)},
|
||||
0x04178de0},
|
||||
{"ZLSR Z15.B, Z0.B, P3.M, Z0.B", "ZLSR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(0, ExtArrB)},
|
||||
0x04118de0},
|
||||
{"ZLSR Z7.D, Z6.H, Z13.H", "ZLSR", ExtFormShiftWide, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(6, ExtArrH), ExtVector(13, ExtArrH)},
|
||||
0x046784cd},
|
||||
{"ZLSRR Z15.B, Z0.B, P3.M, Z0.B", "ZLSRR", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(0, ExtArrB)},
|
||||
0x04158de0},
|
||||
} {
|
||||
in := extInstructionMeta(t, tt.mnem, tt.form, tt.qual, tt.arr)
|
||||
got, err := in.Encode(tt.ops)
|
||||
|
||||
@@ -783,6 +783,17 @@ func TestArm64AssembleExtensionStage4Golden(t *testing.T) {
|
||||
{"ZFMAXQV Z25.S, P3, V5.S4", 0x6496af25},
|
||||
{"ZFMINNMQV Z25.S, P3, V5.S4", 0x6495af25},
|
||||
{"ZFMINQV Z25.S, P3, V5.S4", 0x6497af25},
|
||||
// The shift-by-vector family.
|
||||
{"ZASR Z15.B, Z0.B, P3.M, Z0.B", 0x04108de0},
|
||||
{"ZASR Z2.D, Z10.D, P3.M, Z10.D", 0x04d08c4a},
|
||||
{"ZASR Z7.D, Z6.H, Z13.H", 0x046780cd},
|
||||
{"ZASRR Z15.B, Z0.B, P3.M, Z0.B", 0x04148de0},
|
||||
{"ZLSL Z2.D, Z10.D, P3.M, Z10.D", 0x04d38c4a},
|
||||
{"ZLSL Z7.D, Z6.H, Z13.H", 0x04678ccd},
|
||||
{"ZLSLR Z15.B, Z0.B, P3.M, Z0.B", 0x04178de0},
|
||||
{"ZLSR Z15.B, Z0.B, P3.M, Z0.B", 0x04118de0},
|
||||
{"ZLSR Z7.D, Z6.H, Z13.H", 0x046784cd},
|
||||
{"ZLSRR Z15.B, Z0.B, P3.M, Z0.B", 0x04158de0},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||
|
||||
@@ -298,6 +298,12 @@ func TestExtensionNamesARM64(t *testing.T) {
|
||||
"ZSMINQV",
|
||||
"ZUMAXQV",
|
||||
"ZUMINQV",
|
||||
"ZASR",
|
||||
"ZASRR",
|
||||
"ZLSL",
|
||||
"ZLSLR",
|
||||
"ZLSR",
|
||||
"ZLSRR",
|
||||
// The stage-three families: the SVE2 crypto group, the predicate
|
||||
// counters and loop terminators with the 32-bit while compares, and
|
||||
// the reductions into a SIMD register.
|
||||
@@ -410,7 +416,7 @@ func TestExtensionNamesARM64(t *testing.T) {
|
||||
if strings.Join(got, ",") != strings.Join(want, ",") {
|
||||
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
||||
}
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 405 {
|
||||
t.Errorf("the family registers %d instructions, want 405", n)
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 414 {
|
||||
t.Errorf("the family registers %d instructions, want 414", n)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user