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
|
extFieldPm = ExtField{16, 3} // predicate source P0-P7
|
||||||
extFieldPnc = ExtField{0, 3} // predicate-as-counter destination PN8-PN15, field holds reg-8
|
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)
|
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
|
// 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
|
// 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.
|
// first-source slot, Pg narrow, Zda in the destination slot.
|
||||||
ExtFormMulPred
|
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,
|
// ExtFormCompare is the SVE2 compare to a predicate destination,
|
||||||
// ZCMPEQ Z0.H, Z2.H, P0.Z, P14.H: the comparison writes the zeroing
|
// 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,
|
// predicate P0-P7 spelled with its zeroing qualifier. Operands: Zm.T,
|
||||||
@@ -760,7 +769,7 @@ func (f ExtForm) Arity() int {
|
|||||||
return 1
|
return 1
|
||||||
case ExtFormZReadBack, ExtFormCountP, ExtFormCountPnW, ExtFormReduce, ExtFormZLastReg:
|
case ExtFormZReadBack, ExtFormCountP, ExtFormCountPnW, ExtFormReduce, ExtFormZLastReg:
|
||||||
return 3
|
return 3
|
||||||
case ExtFormZSameReg, ExtFormCountPn, ExtFormCTerm:
|
case ExtFormZSameReg, ExtFormCountPn, ExtFormCTerm, ExtFormVLRead:
|
||||||
return 2
|
return 2
|
||||||
case ExtFormReduceReadBack:
|
case ExtFormReduceReadBack:
|
||||||
return 4
|
return 4
|
||||||
@@ -838,6 +847,10 @@ func (f ExtForm) Kinds() []ExtOperandKind {
|
|||||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
return []ExtOperandKind{ExtZReg, ExtPReg, ExtSveMem}
|
||||||
case ExtFormNarrow, ExtFormShiftWide, ExtFormLongMul:
|
case ExtFormNarrow, ExtFormShiftWide, ExtFormLongMul:
|
||||||
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
return []ExtOperandKind{ExtZReg, ExtZReg, ExtZReg}
|
||||||
|
case ExtFormVLArith:
|
||||||
|
return []ExtOperandKind{ExtImm, ExtGReg, ExtGReg}
|
||||||
|
case ExtFormVLRead:
|
||||||
|
return []ExtOperandKind{ExtImm, ExtGReg}
|
||||||
case ExtFormConvert:
|
case ExtFormConvert:
|
||||||
return []ExtOperandKind{ExtZReg, ExtPReg, ExtZReg}
|
return []ExtOperandKind{ExtZReg, ExtPReg, ExtZReg}
|
||||||
case ExtFormThreeSource, ExtFormMulPred, ExtFormCompare, ExtFormCompareWide:
|
case ExtFormThreeSource, ExtFormMulPred, ExtFormCompare, ExtFormCompareWide:
|
||||||
@@ -984,6 +997,10 @@ func (f ExtForm) String() string {
|
|||||||
return "compare to a predicate"
|
return "compare to a predicate"
|
||||||
case ExtFormCompareWide:
|
case ExtFormCompareWide:
|
||||||
return "wide compare to a predicate"
|
return "wide compare to a predicate"
|
||||||
|
case ExtFormVLArith:
|
||||||
|
return "vector-length arithmetic"
|
||||||
|
case ExtFormVLRead:
|
||||||
|
return "vector-length read"
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
return "no operands"
|
return "no operands"
|
||||||
default:
|
default:
|
||||||
@@ -1254,6 +1271,10 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
|
|||||||
return in.encodeCompare(ops)
|
return in.encodeCompare(ops)
|
||||||
case ExtFormCompareWide:
|
case ExtFormCompareWide:
|
||||||
return in.encodeCompare(ops)
|
return in.encodeCompare(ops)
|
||||||
|
case ExtFormVLArith:
|
||||||
|
return in.encodeVLArith(ops)
|
||||||
|
case ExtFormVLRead:
|
||||||
|
return in.encodeVLRead(ops)
|
||||||
case ExtFormNone:
|
case ExtFormNone:
|
||||||
if len(ops) != 0 {
|
if len(ops) != 0 {
|
||||||
return nil, fmt.Errorf("%s: the %s form takes no operands, got %d",
|
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,
|
// 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
|
// Zm.S, the two halfword vectors under the row's Arr and the wide source
|
||||||
// one step above it.
|
// 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
|
// encodeCompare fills the SVE2 compare forms, the shared-arrangement and
|
||||||
// the wide shape alike: Zm, Zn, Pg/Z, Pd. The comparison writes the
|
// 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
|
// 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",
|
{Name: "ZCMPNE", Summary: "Compare not equal against wide magnitudes, writing a zeroing predicate",
|
||||||
Word: 0x24002010, Form: ExtFormCompareWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
Word: 0x24002010, Form: ExtFormCompareWide, Size: extSizeBHSD, Feature: ExtFeatureSVE2,
|
||||||
Ref: "ARM DDI 0487J SVE2: ZCMPNE; inst_gen.go + arm64sveenc.s"},
|
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 SVE multiple-structure loads and stores --------------------------
|
||||||
//
|
//
|
||||||
// The two-, three- and four-register list loads and stores over the
|
// The two-, three- and four-register list loads and stores over the
|
||||||
|
|||||||
@@ -346,6 +346,9 @@ func TestExtensionNamesARM64(t *testing.T) {
|
|||||||
"ZCMPHI",
|
"ZCMPHI",
|
||||||
"ZCMPHS",
|
"ZCMPHS",
|
||||||
"ZCMPNE",
|
"ZCMPNE",
|
||||||
|
"ADDPL",
|
||||||
|
"ADDVL",
|
||||||
|
"RDVL",
|
||||||
"ZLD2B",
|
"ZLD2B",
|
||||||
"ZLD2D",
|
"ZLD2D",
|
||||||
"ZLD2H",
|
"ZLD2H",
|
||||||
@@ -488,7 +491,7 @@ func TestExtensionNamesARM64(t *testing.T) {
|
|||||||
if strings.Join(got, ",") != strings.Join(want, ",") {
|
if strings.Join(got, ",") != strings.Join(want, ",") {
|
||||||
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
t.Errorf("ExtensionNames(ARM64) = %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
if n := len(arch.Extensions(arch.ARM64)); n != 497 {
|
if n := len(arch.Extensions(arch.ARM64)); n != 500 {
|
||||||
t.Errorf("the family registers %d instructions, want 497", n)
|
t.Errorf("the family registers %d instructions, want 500", n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user