feat(arch): the SVE2 three-source and bitwise combine families
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
bd80499c74
commit
0760cc91af
4 files changed
+144
-3
No files matched your search
+85
-1
@@ -684,6 +684,12 @@ const (
|
||||
// shifted data shares one narrower arrangement, which feeds the size
|
||||
// field. Operands: Zm.D, Zn.T, Zd.T.
|
||||
ExtFormShiftWide
|
||||
// ExtFormThreeSource is the SVE2 three-source bitwise form, ZBCAX
|
||||
// Z23.D, Z13.D, Z21.D, Z21.D: two sources combine with the destination
|
||||
// under the class's own operation, locked to quadwords. Operands:
|
||||
// Za.D, Zm.D, Zdn.D, Zdn.D, the last two naming the same register,
|
||||
// which the encoding carries once in the destination slot.
|
||||
ExtFormThreeSource
|
||||
)
|
||||
|
||||
// Arity returns the operand count the form takes.
|
||||
@@ -695,7 +701,7 @@ func (f ExtForm) Arity() int {
|
||||
ExtFormZUnary, ExtFormZGov, ExtFormVectorsZm, ExtFormZImmediateSource:
|
||||
return 3
|
||||
case ExtFormPredicateLogical, ExtFormPredicateSelect, ExtFormPredicateLogicalDest,
|
||||
ExtFormZPredicatedSource, ExtFormZSelect:
|
||||
ExtFormZPredicatedSource, ExtFormZSelect, ExtFormThreeSource:
|
||||
return 4
|
||||
case ExtFormImmediate, ExtFormSignedImmediate, ExtFormPredicateFFRRead,
|
||||
ExtFormPredicateMove, ExtFormPredicateUnpack, ExtFormPredicateTest,
|
||||
@@ -794,6 +800,8 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
||||
case ExtFormNarrow, ExtFormShiftWide:
|
||||
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
||||
case ExtFormThreeSource:
|
||||
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg, ExtZReg}
|
||||
case ExtFormQuadReduce:
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtVReg}
|
||||
case ExtFormNone:
|
||||
@@ -924,6 +932,8 @@ func (f ExtForm) String() string {
|
||||
return "quadword reduction"
|
||||
case ExtFormShiftWide:
|
||||
return "wide shift"
|
||||
case ExtFormThreeSource:
|
||||
return "three-source bitwise"
|
||||
case ExtFormNone:
|
||||
return "no operands"
|
||||
default:
|
||||
@@ -1182,6 +1192,8 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeQuadReduce(ops)
|
||||
case ExtFormShiftWide:
|
||||
return in.encodeShiftWide(ops)
|
||||
case ExtFormThreeSource:
|
||||
return in.encodeThreeSource(ops)
|
||||
case ExtFormNone:
|
||||
if len(ops) != 0 {
|
||||
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
||||
@@ -2674,6 +2686,35 @@ func (in ExtInstr) encodeShiftWide(ops []ExtOperand) ([]byte, error) {
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeThreeSource fills the SVE2 three-source bitwise form: Za.D, Zm.D,
|
||||
// Zdn.D, Zdn.D, the destination read back, the whole class locked to
|
||||
// quadwords. Operands 3 and 4 name the same register and the encoding
|
||||
// carries it once, in the destination slot.
|
||||
func (in ExtInstr) encodeThreeSource(ops []ExtOperand) ([]byte, error) {
|
||||
za, zm, zdn := ops[0], ops[1], ops[2]
|
||||
if err := in.zVector(za, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.zVector(zm, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.zVector(zdn, 3); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.zVector(ops[3], 4); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ops[3].Reg != zdn.Reg || ops[3].Arr != zdn.Arr {
|
||||
return nil, fmt.Errorf("%s: operands 3 and 4 are the same register Zdn, got Z%d and Z%d",
|
||||
in.Name, zdn.Reg, ops[3].Reg)
|
||||
}
|
||||
word := in.Word
|
||||
word = extSet(word, extFieldRn, uint32(za.Reg))
|
||||
word = extSet(word, extFieldRm, uint32(zm.Reg))
|
||||
word = extSet(word, extFieldRd, uint32(zdn.Reg))
|
||||
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.
|
||||
@@ -3342,6 +3383,49 @@ var arm64Extensions = []ExtInstr{
|
||||
Word: 0x04158000, Form: ExtFormZPredicatedSource, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZLSRR; inst_gen.go + arm64sveenc.s"},
|
||||
|
||||
// --- the SVE2 three-source and bitwise combine families -------------------
|
||||
//
|
||||
// The three-source bitwise operations (EOR3, BCAX, BSL and its
|
||||
// complements, NBSL) locked to quadwords, and the two-vector combines
|
||||
// over a free arrangement (BDEP, BEXT, BGRP, EORBT, EORTB). Provenance
|
||||
// as above: the toolchain encoding table and its generated corpus, both
|
||||
// produced from Arm's official ISA description, and the golden test
|
||||
// pins every corpus line of the family. The XAR rotate rides the
|
||||
// tsz:imm3 immediate class, unwired with the other shift immediates.
|
||||
{Name: "ZBCAX", Summary: "Broadcast-complement and exclusive-or three sources, .D locked",
|
||||
Word: 0x04603800, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBCAX; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBDEP", Summary: "Deposite bit particles from adjacent pairs",
|
||||
Word: 0x4500b400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBDEP; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBEXT", Summary: "Extract bit particles from adjacent pairs",
|
||||
Word: 0x4500b000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBEXT; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBGRP", Summary: "Group bit particles from adjacent pairs",
|
||||
Word: 0x4500b800, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBGRP; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBSL", Summary: "Bitwise select three sources, .D locked",
|
||||
Word: 0x04203c00, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBSL; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBSL1N", Summary: "Bitwise select with first source inverted, .D locked",
|
||||
Word: 0x04603c00, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBSL1N; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZBSL2N", Summary: "Bitwise select with second source inverted, .D locked",
|
||||
Word: 0x04a03c00, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZBSL2N; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZEOR3", Summary: "Exclusive-or three sources, .D locked",
|
||||
Word: 0x04203800, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZEOR3; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZEORBT", Summary: "Exclusive-or bottom of one source with top of the other",
|
||||
Word: 0x45009000, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZEORBT; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZEORTB", Summary: "Exclusive-or top of one source with bottom of the other",
|
||||
Word: 0x45009400, Form: ExtFormVectorsZm, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZEORTB; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ZNBSL", Summary: "Bitwise select with negated result, .D locked",
|
||||
Word: 0x04e03c00, Form: ExtFormThreeSource, Arr: ExtArrD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZNBSL; inst_gen.go + arm64sveenc.s"},
|
||||
|
||||
// --- the SVE2 crypto family ----------------------------------------------
|
||||
//
|
||||
// The multi-precision carry steps (ADCLB, ADCLT, SBCLB, SBCLT), the SHA3
|
||||
|
||||
@@ -1471,6 +1471,40 @@ func TestArm64ExtStage4Golden(t *testing.T) {
|
||||
{"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},
|
||||
// The three-source and bitwise combine families.
|
||||
{"ZBCAX Z23.D, Z13.D, Z21.D, Z21.D", "ZBCAX", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x046d3af5},
|
||||
{"ZEOR3 Z23.D, Z13.D, Z21.D, Z21.D", "ZEOR3", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x042d3af5},
|
||||
{"ZBSL Z23.D, Z13.D, Z21.D, Z21.D", "ZBSL", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x042d3ef5},
|
||||
{"ZBSL1N Z23.D, Z13.D, Z21.D, Z21.D", "ZBSL1N", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x046d3ef5},
|
||||
{"ZBSL2N Z23.D, Z13.D, Z21.D, Z21.D", "ZBSL2N", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x04ad3ef5},
|
||||
{"ZNBSL Z23.D, Z13.D, Z21.D, Z21.D", "ZNBSL", ExtFormThreeSource, ExtQualNone, ExtArrD,
|
||||
[]ExtOperand{ExtVector(23, ExtArrD), ExtVector(13, ExtArrD), ExtVector(21, ExtArrD), ExtVector(21, ExtArrD)},
|
||||
0x04ed3ef5},
|
||||
{"ZBDEP Z7.D, Z23.D, Z13.D", "ZBDEP", ExtFormVectorsZm, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)},
|
||||
0x45c7b6ed},
|
||||
{"ZBEXT Z7.D, Z23.D, Z13.D", "ZBEXT", ExtFormVectorsZm, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)},
|
||||
0x45c7b2ed},
|
||||
{"ZBGRP Z7.D, Z23.D, Z13.D", "ZBGRP", ExtFormVectorsZm, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)},
|
||||
0x45c7baed},
|
||||
{"ZEORBT Z7.D, Z23.D, Z13.D", "ZEORBT", ExtFormVectorsZm, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)},
|
||||
0x45c792ed},
|
||||
{"ZEORTB Z7.D, Z23.D, Z13.D", "ZEORTB", ExtFormVectorsZm, ExtQualNone, ExtArrNone,
|
||||
[]ExtOperand{ExtVector(7, ExtArrD), ExtVector(23, ExtArrD), ExtVector(13, ExtArrD)},
|
||||
0x45c796ed},
|
||||
} {
|
||||
in := extInstructionMeta(t, tt.mnem, tt.form, tt.qual, tt.arr)
|
||||
got, err := in.Encode(tt.ops)
|
||||
|
||||
@@ -794,6 +794,18 @@ func TestArm64AssembleExtensionStage4Golden(t *testing.T) {
|
||||
{"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},
|
||||
// The three-source and bitwise combine families.
|
||||
{"ZBCAX Z23.D, Z13.D, Z21.D, Z21.D", 0x046d3af5},
|
||||
{"ZEOR3 Z23.D, Z13.D, Z21.D, Z21.D", 0x042d3af5},
|
||||
{"ZBSL Z23.D, Z13.D, Z21.D, Z21.D", 0x042d3ef5},
|
||||
{"ZBSL1N Z23.D, Z13.D, Z21.D, Z21.D", 0x046d3ef5},
|
||||
{"ZBSL2N Z23.D, Z13.D, Z21.D, Z21.D", 0x04ad3ef5},
|
||||
{"ZNBSL Z23.D, Z13.D, Z21.D, Z21.D", 0x04ed3ef5},
|
||||
{"ZBDEP Z7.D, Z23.D, Z13.D", 0x45c7b6ed},
|
||||
{"ZBEXT Z7.D, Z23.D, Z13.D", 0x45c7b2ed},
|
||||
{"ZBGRP Z7.D, Z23.D, Z13.D", 0x45c7baed},
|
||||
{"ZEORBT Z7.D, Z23.D, Z13.D", 0x45c792ed},
|
||||
{"ZEORTB Z7.D, Z23.D, Z13.D", 0x45c796ed},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")
|
||||
|
||||
+13
-2
@@ -304,6 +304,17 @@ func TestExtensionNamesARM64(t *testing.T) {
|
||||
"ZLSLR",
|
||||
"ZLSR",
|
||||
"ZLSRR",
|
||||
"ZBCAX",
|
||||
"ZBDEP",
|
||||
"ZBEXT",
|
||||
"ZBGRP",
|
||||
"ZBSL",
|
||||
"ZBSL1N",
|
||||
"ZBSL2N",
|
||||
"ZEOR3",
|
||||
"ZEORBT",
|
||||
"ZEORTB",
|
||||
"ZNBSL",
|
||||
// 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.
|
||||
@@ -416,7 +427,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 != 414 {
|
||||
t.Errorf("the family registers %d instructions, want 414", n)
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 425 {
|
||||
t.Errorf("the family registers %d instructions, want 425", n)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user