fix(arch): keep Zdn out of the class bits of the predicated Z-alias source

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 20:35:41 +02:00
1 parent 6e49cbd099
commit ee2c6d51b3
3 files changed
+18 -3

No files matched your search

+5 -3
View File
@@ -573,8 +573,9 @@ const (
// ExtFormZPredicatedSource is the Z-alias binary predicated form,
// ZADD Z15.B, Z0.B, P3.M, Z0.B: the destination's source copy is
// spelled and must equal the destination. Operands: Zm.T, Zdn.T,
// Pg/M, Zdn.T. Fields: Zm in the second-source slot, Zdn in the
// first-source slot, Pg narrow, Zdn in the destination.
// Pg/M, Zdn.T. Fields: Zm in the first-source slot at bits 9..5, Pg
// narrow, Zdn in the destination slot; bits 16..20 are class bits no
// operand touches.
ExtFormZPredicatedSource
// ExtFormZImmediateSource is the Z-alias immediate form, ZADD $6,
// Z7.D, Z7.D: the destination's source copy is spelled and must equal
@@ -1787,6 +1788,8 @@ func (in ExtInstr) encodeZUnary(ops []ExtOperand) ([]byte, error) {
// encodeZPredicatedSource fills the Z-alias binary predicated form: Zm.T,
// Zdn.T, Pg/M, Zdn.T, the source copy spelled and equal to the destination.
// Zm rides the first-source slot at bits 9..5 and Zdn the destination slot;
// bits 16..20 carry the class opcode and stay clear of operands.
func (in ExtInstr) encodeZPredicatedSource(ops []ExtOperand) ([]byte, error) {
zm, zdn, pg := ops[0], ops[1], ops[2]
if err := in.zVector(zm, 1); err != nil {
@@ -1819,7 +1822,6 @@ func (in ExtInstr) encodeZPredicatedSource(ops []ExtOperand) ([]byte, error) {
}
word := in.Word
word = extSet(word, extFieldRn, uint32(zm.Reg))
word = extSet(word, extFieldRm, uint32(zdn.Reg))
word = extSet(word, extFieldPgN, uint32(pg.Reg))
word = extSet(word, extFieldRd, uint32(zdn.Reg))
if size != 0 {
+9
View File
@@ -880,6 +880,15 @@ func TestArm64ExtZGolden(t *testing.T) {
{"ZMOVPRFX Z7.D, P4.Z, Z21.D", "ZMOVPRFX", ExtFormZUnary, ExtQualAny, ExtArrNone,
[]ExtOperand{ExtVector(7, ExtArrD), ExtPredicate(4, ExtQualZeroing), ExtVector(21, ExtArrD)},
0x04d030f5},
// The destination read back spells twice and encodes once, in the
// destination slot alone: bits 16..20 are class bits, so a non-zero
// Zdn must not reach them.
{"ZADD Z15.B, Z5.B, P3.M, Z5.B", "ZADD", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
[]ExtOperand{ExtVector(15, ExtArrB), ExtVector(5, ExtArrB), ExtPredicate(3, ExtQualMerging), ExtVector(5, ExtArrB)},
0x04000de5},
{"ZSUB Z20.D, Z13.D, P6.M, Z13.D", "ZSUB", ExtFormZPredicatedSource, ExtQualMerging, ExtArrNone,
[]ExtOperand{ExtVector(20, ExtArrD), ExtVector(13, ExtArrD), ExtPredicate(6, ExtQualMerging), ExtVector(13, ExtArrD)},
0x04c11a8d},
{"ZMOVPRFX Z11, Z6", "ZMOVPRFX", ExtFormZMoveBare, 0, ExtArrNone,
[]ExtOperand{{Kind: ExtZReg, Reg: 11}, {Kind: ExtZReg, Reg: 6}},
0x0420bd66},
+4
View File
@@ -334,6 +334,10 @@ func TestArm64AssembleExtensionStage2Golden(t *testing.T) {
}{
{"ZABS Z7.D, P4.M, Z13.D", 0x04d6b0ed},
{"ZABS Z7.D, P4.Z, Z13.D", 0x04c6b0ed},
// The destination read back encodes once, in the destination slot
// alone: a non-zero Zdn must stay clear of the class bits.
{"ZADD Z15.B, Z5.B, P3.M, Z5.B", 0x04000de5},
{"ZSUB Z20.D, Z13.D, P6.M, Z13.D", 0x04c11a8d},
{"ZADD Z15.B, Z0.B, P3.M, Z0.B", 0x04000de0},
{"ZADD Z7.D, Z23.D, Z13.D", 0x04e702ed},
{"ZAND Z15.B, Z0.B, P3.M, Z0.B", 0x041a0de0},