feat(arch): the vector-length arithmetic pseudo group
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
bd85f8838d
commit
aeb109a64c
2 files changed
+86
-3
No files matched your search
+81
-1
@@ -406,6 +406,7 @@ var (
|
||||
extFieldPm = ExtField{16, 3} // predicate source P0-P7
|
||||
extFieldPnc = ExtField{0, 3} // predicate-as-counter destination PN8-PN15, field holds reg-8
|
||||
extFieldPn4 = ExtField{5, 4} // predicate source P0-P15 at bits 8..5 (counter family)
|
||||
extFieldImm6 = ExtField{5, 6} // the signed imm6 of the vector-length arithmetic
|
||||
)
|
||||
|
||||
// ExtForm enumerates the operand shapes the extension layer defines, in Plan
|
||||
@@ -701,6 +702,14 @@ const (
|
||||
// Zm.H, Zn.H, Pg/M, Zda.H. Fields: Zm at bits 16..20, Zn in the
|
||||
// first-source slot, Pg narrow, Zda in the destination slot.
|
||||
ExtFormMulPred
|
||||
// ExtFormVLArith is the vector-length arithmetic, ADDVL $9, R11, RSP:
|
||||
// a signed imm6 multiple of the vector length added to a general
|
||||
// register, either slot spelled RSP. Operands: imm, Rn|SP, Rd|SP.
|
||||
// Fields: the imm6 at bits 10..5, Rn at bits 20..16, Rd at bits 4..0.
|
||||
ExtFormVLArith
|
||||
// ExtFormVLRead is the vector-length read, RDVL $1, R27. Operands:
|
||||
// imm, Rd (R0-R30). Fields: the imm6 at bits 10..5, Rd at bits 4..0.
|
||||
ExtFormVLRead
|
||||
// ExtFormCompare is the SVE2 compare to a predicate destination,
|
||||
// ZCMPEQ Z0.H, Z2.H, P0.Z, P14.H: the comparison writes the zeroing
|
||||
// predicate P0-P7 spelled with its zeroing qualifier. Operands: Zm.T,
|
||||
@@ -760,7 +769,7 @@ func (f ExtForm) Arity() int {
|
||||
return 1
|
||||
case ExtFormZReadBack, ExtFormCountP, ExtFormCountPnW, ExtFormReduce, ExtFormZLastReg:
|
||||
return 3
|
||||
case ExtFormZSameReg, ExtFormCountPn, ExtFormCTerm:
|
||||
case ExtFormZSameReg, ExtFormCountPn, ExtFormCTerm, ExtFormVLRead:
|
||||
return 2
|
||||
case ExtFormReduceReadBack:
|
||||
return 4
|
||||
@@ -838,6 +847,10 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
||||
case ExtFormNarrow, ExtFormShiftWide, ExtFormLongMul:
|
||||
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
||||
case ExtFormVLArith:
|
||||
return []ExtOperandKind{ExtImm, ExtGReg, ExtGReg}
|
||||
case ExtFormVLRead:
|
||||
return []ExtOperandKind{ExtImm, ExtGReg}
|
||||
case ExtFormConvert:
|
||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtZReg}
|
||||
case ExtFormThreeSource, ExtFormMulPred, ExtFormCompare, ExtFormCompareWide:
|
||||
@@ -984,6 +997,10 @@ func (f ExtForm) String() string {
|
||||
return "compare to a predicate"
|
||||
case ExtFormCompareWide:
|
||||
return "wide compare to a predicate"
|
||||
case ExtFormVLArith:
|
||||
return "vector-length arithmetic"
|
||||
case ExtFormVLRead:
|
||||
return "vector-length read"
|
||||
case ExtFormNone:
|
||||
return "no operands"
|
||||
default:
|
||||
@@ -1254,6 +1271,10 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
||||
return in.encodeCompare(ops)
|
||||
case ExtFormCompareWide:
|
||||
return in.encodeCompare(ops)
|
||||
case ExtFormVLArith:
|
||||
return in.encodeVLArith(ops)
|
||||
case ExtFormVLRead:
|
||||
return in.encodeVLRead(ops)
|
||||
case ExtFormNone:
|
||||
if len(ops) != 0 {
|
||||
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
||||
@@ -2853,6 +2874,48 @@ func (in ExtInstr) encodeMulPred(ops []ExtOperand) ([]byte, error) {
|
||||
// encodeLongMul fills the SVE2 BFloat16 lengthened multiply: Za.H, Zn.H,
|
||||
// Zm.S, the two halfword vectors under the row's Arr and the wide source
|
||||
// one step above it.
|
||||
// encodeVLArith fills the vector-length arithmetic: imm, Rn|SP, Rd|SP.
|
||||
// The signed imm6 counts multiples of the vector length; the register
|
||||
// slots spell RSP, never a plain R31.
|
||||
func (in ExtInstr) encodeVLArith(ops []ExtOperand) ([]byte, error) {
|
||||
imm, rn, rd := ops[0], ops[1], ops[2]
|
||||
if imm.Kind != ExtImm {
|
||||
return nil, fmt.Errorf("%s: operand 1 wants an immediate, got %s", in.Name, imm.Kind)
|
||||
}
|
||||
if imm.Imm < -32 || imm.Imm > 31 {
|
||||
return nil, fmt.Errorf("%s: immediate %d is outside the signed 6-bit range -32..31", in.Name, imm.Imm)
|
||||
}
|
||||
if err := in.generalOperand(rn, 2, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := in.generalOperand(rd, 3, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
word := in.Word
|
||||
word = extSet(word, extFieldImm6, uint32(imm.Imm))
|
||||
word = extSet(word, extFieldRm, uint32(rn.Reg))
|
||||
word = extSet(word, extFieldRd, uint32(rd.Reg))
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeVLRead fills the vector-length read: imm, Rd (R0-R30).
|
||||
func (in ExtInstr) encodeVLRead(ops []ExtOperand) ([]byte, error) {
|
||||
imm, rd := ops[0], ops[1]
|
||||
if imm.Kind != ExtImm {
|
||||
return nil, fmt.Errorf("%s: operand 1 wants an immediate, got %s", in.Name, imm.Kind)
|
||||
}
|
||||
if imm.Imm < -32 || imm.Imm > 31 {
|
||||
return nil, fmt.Errorf("%s: immediate %d is outside the signed 6-bit range -32..31", in.Name, imm.Imm)
|
||||
}
|
||||
if err := in.generalOperand(rd, 2, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
word := in.Word
|
||||
word = extSet(word, extFieldImm6, uint32(imm.Imm))
|
||||
word = extSet(word, extFieldRd, uint32(rd.Reg))
|
||||
return extWordLE(word), nil
|
||||
}
|
||||
|
||||
// encodeCompare fills the SVE2 compare forms, the shared-arrangement and
|
||||
// the wide shape alike: Zm, Zn, Pg/Z, Pd. The comparison writes the
|
||||
// zeroing predicate P0-P7; under the wide shape the magnitudes ride the
|
||||
@@ -3797,6 +3860,23 @@ var arm64Extensions = []ExtInstr{
|
||||
{Name: "ZCMPNE", Summary: "Compare not equal against wide magnitudes, writing a zeroing predicate",
|
||||
Word: 0x24002010, Form: ExtFormCompareWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||
Ref: "ARM DDI 0487J SVE2: ZCMPNE; inst_gen.go + arm64sveenc.s"},
|
||||
|
||||
// --- the vector-length arithmetic pseudo group ----------------------------
|
||||
//
|
||||
// ADDVL, ADDPL and RDVL over the signed imm6 multiple of the vector
|
||||
// length or the parameter register. Provenance as above: the toolchain
|
||||
// encoding table and its generated corpus, both produced from Arm's
|
||||
// official ISA description, and the golden test pins every corpus line
|
||||
// of the family.
|
||||
{Name: "ADDPL", Summary: "Add a signed multiple of the parameter register count to a register",
|
||||
Word: 0x04605000, Form: ExtFormVLArith, Feature: ExtFeatureSVE,
|
||||
Ref: "ARM DDI 0487J: ADDPL; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "ADDVL", Summary: "Add a signed multiple of the vector length to a register",
|
||||
Word: 0x04205000, Form: ExtFormVLArith, Feature: ExtFeatureSVE,
|
||||
Ref: "ARM DDI 0487J: ADDVL; inst_gen.go + arm64sveenc.s"},
|
||||
{Name: "RDVL", Summary: "Read the vector length multiplied by a signed immediate",
|
||||
Word: 0x04bf5000, Form: ExtFormVLRead, Feature: ExtFeatureSVE,
|
||||
Ref: "ARM DDI 0487J: RDVL; inst_gen.go + arm64sveenc.s"},
|
||||
// --- the SVE multiple-structure loads and stores --------------------------
|
||||
//
|
||||
// The two-, three- and four-register list loads and stores over the
|
||||
|
||||
@@ -346,6 +346,9 @@ func TestExtensionNamesARM64(t *testing.T) {
|
||||
"ZCMPHI",
|
||||
"ZCMPHS",
|
||||
"ZCMPNE",
|
||||
"ADDPL",
|
||||
"ADDVL",
|
||||
"RDVL",
|
||||
"ZLD2B",
|
||||
"ZLD2D",
|
||||
"ZLD2H",
|
||||
@@ -488,7 +491,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 != 497 {
|
||||
t.Errorf("the family registers %d instructions, want 497", n)
|
||||
if n := len(arch.Extensions(arch.ARM64)); n != 500 {
|
||||
t.Errorf("the family registers %d instructions, want 500", n)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user