feat(arch): the ZCNOT unary pair and the vector counter step

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 21:39:45 +02:00
1 parent 4066396226
commit 107ca512b2
4 files changed
+63 -2

No files matched your search

+47
View File
@@ -735,6 +735,13 @@ const (
// 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
// ExtFormCountPnVec is the predicate-counter step whose result stays a
// vector, ZDECP P14.S, Z26.S: the vector is decremented in place by the
// predicate's active element count. Operands: Pm.T, Zdn.T; the
// predicate occupies the four-bit field at bits 8..5, the vector the
// destination slot, and the predicate's arrangement feeds the size
// field.
ExtFormCountPnVec
)
// Arity returns the operand count the form takes.
@@ -771,6 +778,8 @@ func (f ExtForm) Arity() int {
return 3
case ExtFormZSameReg, ExtFormCountPn, ExtFormCTerm, ExtFormVLRead:
return 2
case ExtFormCountPnVec:
return 2
case ExtFormReduceReadBack:
return 4
case ExtFormSveLoad, ExtFormSveStore, ExtFormNarrow, ExtFormQuadReduce, ExtFormShiftWide,
@@ -837,6 +846,8 @@ func (f ExtForm) Kinds() []ExtOperandKind {
return []ExtOperandKind{ExtPReg, ExtPReg, ExtGReg}
case ExtFormCountPn:
return []ExtOperandKind{ExtPReg, ExtGReg}
case ExtFormCountPnVec:
return []ExtOperandKind{ExtPReg, ExtZReg}
case ExtFormCountPnW:
return []ExtOperandKind{ExtGReg, ExtPReg, ExtGReg}
case ExtFormReduce:
@@ -971,6 +982,8 @@ func (f ExtForm) String() string {
return "count to a register"
case ExtFormCountPn:
return "counter step, result dropped"
case ExtFormCountPnVec:
return "counter step on a vector"
case ExtFormCountPnW:
return "counter step to a register"
case ExtFormReduce:
@@ -1245,6 +1258,8 @@ func (in ExtInstr) Encode(ops []ExtOperand) ([]byte, error) {
return in.encodeCountP(ops)
case ExtFormCountPn:
return in.encodeCountPn(ops)
case ExtFormCountPnVec:
return in.encodeCountPnVec(ops)
case ExtFormCountPnW:
return in.encodeCountPnW(ops)
case ExtFormReduce:
@@ -2353,6 +2368,31 @@ func (in ExtInstr) encodeCountPn(ops []ExtOperand) ([]byte, error) {
return extWordLE(word), nil
}
// encodeCountPnVec fills the predicate-counter step on a vector: Pm.T,
// Zdn.T, the vector decremented in place by the predicate's active element
// count. The predicate occupies the four-bit field at bits 8..5, the
// vector the destination slot, and the predicate's arrangement feeds the
// size field.
func (in ExtInstr) encodeCountPnVec(ops []ExtOperand) ([]byte, error) {
pm, zdn := ops[0], ops[1]
if err := in.predicateOperand(pm, 1, 0, 15, ExtArrNone); err != nil {
return nil, err
}
if err := in.zVector(zdn, 2); err != nil {
return nil, err
}
size, ok := pm.Arr.sizeBits()
if !ok {
return nil, fmt.Errorf("%s: arrangement %s has no size encoding in this class",
in.Name, pm.Arr)
}
word := in.Word
word = extSet(word, extFieldPn4, uint32(pm.Reg))
word = extSet(word, extFieldRd, uint32(zdn.Reg))
word = extSet(word, in.Size, size)
return extWordLE(word), nil
}
// encodeCountPnW fills the predicate-counter step with a scalar result:
// Rd, Pn.T, Rd, the destination spelled twice. The predicate occupies the
// four-bit field at bits 8..5 and its arrangement feeds the size field.
@@ -3410,12 +3450,19 @@ var arm64Extensions = []ExtInstr{
Word: 0x0419a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLZ; inst_gen.go + arm64sveenc.s"},
{Name: "ZCLZ", Summary: "Z-alias of the predicated form, over a governing predicate",
Word: 0x0409a000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCLZ; inst_gen.go + arm64sveenc.s"},
{Name: "ZCNOT", Summary: "Z-alias of the predicated form, over a governing predicate",
Word: 0x041ba000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNOT; inst_gen.go + arm64sveenc.s"},
{Name: "ZCNOT", Summary: "Z-alias of the predicated form, over a governing predicate",
Word: 0x040ba000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNOT; inst_gen.go + arm64sveenc.s"},
{Name: "ZCNT", Summary: "Z-alias of the predicated form, over a governing predicate",
Word: 0x041aa000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualMerging, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNT; inst_gen.go + arm64sveenc.s"},
{Name: "ZCNT", Summary: "Z-alias of the predicated form, over a governing predicate",
Word: 0x040aa000, Form: ExtFormZUnary, Size: extSizeBHSD, PgQual: ExtQualZeroing, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCNT; inst_gen.go + arm64sveenc.s"},
{Name: "ZCOMPACT", Summary: "Compact or expand over a governing predicate",
Word: 0x05218000, Form: ExtFormZGov, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZCOMPACT; inst_gen.go + arm64sveenc.s"},
{Name: "ZDECP", Summary: "Decrement a vector by a predicate's active elements",
Word: 0x252d8000, Form: ExtFormCountPnVec, Size: extSizeBHSD, Feature: ExtFeatureSVE2p1,
Ref: "ARM DDI 0487J SVE2.1: DECP (vector) as ZDECP; inst_gen.go + arm64sveenc.s"},
{Name: "ZDUP", Summary: "Copy or insert a general register, .D locked",
Word: 0x05e03800, Form: ExtFormZFromGeneral, Arr: ExtArrD, Feature: ExtFeatureSVE2p1, Ref: "ARM DDI 0487J SVE2.1: ZDUP; inst_gen.go + arm64sveenc.s"},
{Name: "ZEOR", Summary: "Z-alias of the unpredicated three-vector form, locked to .D",
+9
View File
@@ -866,6 +866,12 @@ func TestArm64ExtZGolden(t *testing.T) {
{"ZCLZ Z7.D, P4.Z, Z13.D", "ZCLZ", ExtFormZUnary, ExtQualZeroing, ExtArrNone,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)},
0x04c9b0ed},
{"ZCNOT Z7.D, P4.M, Z13.D", "ZCNOT", ExtFormZUnary, ExtQualMerging, ExtArrNone,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualMerging), ExtVector(13, ExtArrD)},
0x04dbb0ed},
{"ZCNOT Z7.D, P4.Z, Z13.D", "ZCNOT", ExtFormZUnary, ExtQualZeroing, ExtArrNone,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(13, ExtArrD)},
0x04cbb0ed},
{"ZCOMPACT Z7.D, P4, Z13.D", "ZCOMPACT", ExtFormZGov, 0, ExtArrNone,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualNone), ExtVector(13, ExtArrD)},
0x05e190ed},
@@ -1166,6 +1172,9 @@ func TestArm64ExtStage3Golden(t *testing.T) {
{"PDECP P14.S, ZR", "PDECP", ExtFormCountPn, ExtArrNone,
[]ExtOperand{ExtPredicateSized(14, ExtArrS), ExtZeroRegister()},
0x25ad89df},
{"ZDECP P14.S, Z26.S", "ZDECP", ExtFormCountPnVec, ExtArrNone,
[]ExtOperand{ExtPredicateSized(14, ExtArrS), ExtVector(26, ExtArrS)},
0x25ad81da},
{"PINCP P14.S, ZR", "PINCP", ExtFormCountPn, ExtArrNone,
[]ExtOperand{ExtPredicateSized(14, ExtArrS), ExtZeroRegister()},
0x25ac89df},
+3
View File
@@ -348,6 +348,8 @@ func TestArm64AssembleExtensionStage2Golden(t *testing.T) {
{"ZCLS Z7.D, P4.Z, Z13.D", 0x04c8b0ed},
{"ZCLZ Z7.D, P4.M, Z13.D", 0x04d9b0ed},
{"ZCLZ Z7.D, P4.Z, Z13.D", 0x04c9b0ed},
{"ZCNOT Z7.D, P4.M, Z13.D", 0x04dbb0ed},
{"ZCNOT Z7.D, P4.Z, Z13.D", 0x04cbb0ed},
{"ZCOMPACT Z7.D, P4, Z13.D", 0x05e190ed},
{"ZCOMPACT Z7.D, P4, Z13.D", 0x05e190ed},
{"ZEOR Z15.B, Z0.B, P3.M, Z0.B", 0x04190de0},
@@ -461,6 +463,7 @@ func TestArm64AssembleExtensionStage3Golden(t *testing.T) {
{"PFIRSTP P2.B, P14, R2", 0x2521b842},
{"PLASTP P2.B, P14, R2", 0x2522b842},
{"PDECP P14.S, ZR", 0x25ad89df},
{"ZDECP P14.S, Z26.S", 0x25ad81da},
{"PINCP P14.S, ZR", 0x25ac89df},
{"PSQDECP P14.S, ZR", 0x25aa8ddf},
{"PSQINCP P14.S, ZR", 0x25a88ddf},
+4 -2
View File
@@ -234,8 +234,10 @@ func TestExtensionNamesARM64(t *testing.T) {
"ZBIC",
"ZCLS",
"ZCLZ",
"ZCNOT",
"ZCNT",
"ZCOMPACT",
"ZDECP",
"ZDUP",
"ZEOR",
"ZEXPAND",
@@ -491,7 +493,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 != 500 {
t.Errorf("the family registers %d instructions, want 500", n)
if n := len(arch.Extensions(arch.ARM64)); n != 503 {
t.Errorf("the family registers %d instructions, want 503", n)
}
}