diff --git a/arch/arm64_ext.go b/arch/arm64_ext.go index bf88ed1..a101da2 100644 --- a/arch/arm64_ext.go +++ b/arch/arm64_ext.go @@ -776,6 +776,8 @@ func (f ExtForm) Arity() int { case ExtFormSveLoad, ExtFormSveStore, ExtFormNarrow, ExtFormQuadReduce, ExtFormShiftWide, ExtFormConvert, ExtFormLongMul: return 3 + case ExtFormVLArith: + return 3 case ExtFormNone: return 0 default: diff --git a/arch/arm64_ext_test.go b/arch/arm64_ext_test.go index 48b2b9c..e27b5e3 100644 --- a/arch/arm64_ext_test.go +++ b/arch/arm64_ext_test.go @@ -1584,6 +1584,57 @@ func TestArm64ExtStage4Golden(t *testing.T) { {"ZST2Q [Z8.Q, Z9.Q], P3, (R6<<4)(RSP)", "ZST2Q", ExtFormSveStore, ExtQualNone, ExtArrQ, []ExtOperand{ExtOperand{Kind: ExtZReg, Reg: 8, Arr: ExtArrQ, List: 2}, ExtPredicateSized(3, ExtArrNone), ExtSveMemPair(6, 4, 31, true)}, 0xe4660fe8}, + // The rest of the BFloat16 wall. + {"ZBFCVT Z13.S, P1.M, Z22.H", "ZBFCVT", ExtFormConvert, ExtQualMerging, ExtArrNone, + []ExtOperand{ExtVector(13, ExtArrS), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrH)}, + 0x658aa5b6}, + {"ZBFCVT Z13.S, P1.Z, Z22.H", "ZBFCVT", ExtFormConvert, ExtQualZeroing, ExtArrNone, + []ExtOperand{ExtVector(13, ExtArrS), ExtPredicate(1, ExtQualZeroing), ExtVector(22, ExtArrH)}, + 0x649ac5b6}, + {"ZBFDOT Z7.H, Z6.H, Z23.S", "ZBFDOT", ExtFormLongMul, ExtQualNone, ExtArrH, + []ExtOperand{ExtVector(7, ExtArrH), ExtVector(6, ExtArrH), ExtVector(23, ExtArrS)}, + 0x646780d7}, + {"ZBFMLA Z23.H, Z13.H, P1.M, Z22.H", "ZBFMLA", ExtFormMulPred, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(23, ExtArrH), ExtVector(13, ExtArrH), ExtPredicate(1, ExtQualMerging), ExtVector(22, ExtArrH)}, + 0x653705b6}, + {"ZBFMLALB Z7.H, Z6.H, Z23.S", "ZBFMLALB", ExtFormLongMul, ExtQualNone, ExtArrH, + []ExtOperand{ExtVector(7, ExtArrH), ExtVector(6, ExtArrH), ExtVector(23, ExtArrS)}, + 0x64e780d7}, + {"ZBFMMLA Z7.H, Z6.H, Z23.S", "ZBFMMLA", ExtFormLongMul, ExtQualNone, ExtArrH, + []ExtOperand{ExtVector(7, ExtArrH), ExtVector(6, ExtArrH), ExtVector(23, ExtArrS)}, + 0x6467e4d7}, + {"ZBFSCALE Z23.H, Z13.H, P1.M, Z13.H", "ZBFSCALE", ExtFormZPredicatedSource, ExtQualMerging, ExtArrH, + []ExtOperand{ExtVector(23, ExtArrH), ExtVector(13, ExtArrH), ExtPredicate(1, ExtQualMerging), ExtVector(13, ExtArrH)}, + 0x650986ed}, + // The last-active vector shape and the compares to a predicate. + {"ZCLASTA Z15.B, Z0.B, P3, Z0.B", "ZCLASTA", ExtFormZPredicatedSource, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicateSized(3, ExtArrNone), ExtVector(0, ExtArrB)}, + 0x05288de0}, + {"ZCLASTB Z15.B, Z0.B, P3, Z0.B", "ZCLASTB", ExtFormZPredicatedSource, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(15, ExtArrB), ExtVector(0, ExtArrB), ExtPredicateSized(3, ExtArrNone), ExtVector(0, ExtArrB)}, + 0x05298de0}, + {"ZCMPEQ Z0.H, Z2.H, P0.Z, P14.H", "ZCMPEQ", ExtFormCompare, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(0, ExtArrH), ExtVector(2, ExtArrH), ExtPredicate(0, ExtQualZeroing), ExtPredicateSized(14, ExtArrH)}, + 0x2440a04e}, + {"ZCMPEQ Z0.D, Z12.S, P0.Z, P14.S", "ZCMPEQ", ExtFormCompareWide, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(0, ExtArrD), ExtVector(12, ExtArrS), ExtPredicate(0, ExtQualZeroing), ExtPredicateSized(14, ExtArrS)}, + 0x2480218e}, + {"ZCMPHS Z0.H, Z2.H, P0.Z, P14.H", "ZCMPHS", ExtFormCompare, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(0, ExtArrH), ExtVector(2, ExtArrH), ExtPredicate(0, ExtQualZeroing), ExtPredicateSized(14, ExtArrH)}, + 0x2440004e}, + {"ZCMPNE Z0.D, Z12.S, P0.Z, P14.S", "ZCMPNE", ExtFormCompareWide, ExtQualNone, ExtArrNone, + []ExtOperand{ExtVector(0, ExtArrD), ExtVector(12, ExtArrS), ExtPredicate(0, ExtQualZeroing), ExtPredicateSized(14, ExtArrS)}, + 0x2480219e}, + // The vector-length arithmetic. + {"ADDPL $9, R11, RSP", "ADDPL", ExtFormVLArith, ExtQualNone, ExtArrNone, + []ExtOperand{ExtImmediate(9), ExtGeneral(11), ExtStackPointer()}, + 0x046b513f}, + {"ADDVL $9, R11, RSP", "ADDVL", ExtFormVLArith, ExtQualNone, ExtArrNone, + []ExtOperand{ExtImmediate(9), ExtGeneral(11), ExtStackPointer()}, + 0x042b513f}, + {"RDVL $1, R27", "RDVL", ExtFormVLRead, ExtQualNone, ExtArrNone, + []ExtOperand{ExtImmediate(1), ExtGeneral(27)}, + 0x04bf503b}, } { in := extInstructionMeta(t, tt.mnem, tt.form, tt.qual, tt.arr) got, err := in.Encode(tt.ops) diff --git a/asm/arm64_ext_asm_test.go b/asm/arm64_ext_asm_test.go index bf93922..9f8d684 100644 --- a/asm/arm64_ext_asm_test.go +++ b/asm/arm64_ext_asm_test.go @@ -846,6 +846,30 @@ func TestArm64AssembleExtensionStage4Golden(t *testing.T) { {"ZST2Q [Z8.Q, Z9.Q], P3, (R6<<4)(RSP)", 0xe4660fe8}, {"ZST3D [Z8.D, Z9.D, Z10.D], P3, (R6<<3)(RSP)", 0xe5c66fe8}, {"ZST4Q [Z8.Q, Z9.Q, Z10.Q, Z11.Q], P3, (R6<<4)(RSP)", 0xe4e60fe8}, + // The rest of the BFloat16 wall. + {"ZBFCVT Z13.S, P1.M, Z22.H", 0x658aa5b6}, + {"ZBFCVT Z13.S, P1.Z, Z22.H", 0x649ac5b6}, + {"ZBFCVTNT Z13.S, P1.M, Z22.H", 0x648aa5b6}, + {"ZBFDOT Z7.H, Z6.H, Z23.S", 0x646780d7}, + {"ZBFMLA Z23.H, Z13.H, P1.M, Z22.H", 0x653705b6}, + {"ZBFMLALB Z7.H, Z6.H, Z23.S", 0x64e780d7}, + {"ZBFMLALT Z7.H, Z6.H, Z23.S", 0x64e784d7}, + {"ZBFMLS Z23.H, Z13.H, P1.M, Z22.H", 0x653725b6}, + {"ZBFMLSLB Z7.H, Z6.H, Z23.S", 0x64e7a0d7}, + {"ZBFMLSLT Z7.H, Z6.H, Z23.S", 0x64e7a4d7}, + {"ZBFMMLA Z7.H, Z6.H, Z23.S", 0x6467e4d7}, + {"ZBFSCALE Z23.H, Z13.H, P1.M, Z13.H", 0x650986ed}, + // The last-active vector shape and the compares to a predicate. + {"ZCLASTA Z15.B, Z0.B, P3, Z0.B", 0x05288de0}, + {"ZCLASTB Z15.B, Z0.B, P3, Z0.B", 0x05298de0}, + {"ZCMPEQ Z0.H, Z2.H, P0.Z, P14.H", 0x2440a04e}, + {"ZCMPEQ Z0.D, Z12.S, P0.Z, P14.S", 0x2480218e}, + {"ZCMPHS Z0.H, Z2.H, P0.Z, P14.H", 0x2440004e}, + {"ZCMPNE Z0.D, Z12.S, P0.Z, P14.S", 0x2480219e}, + // The vector-length arithmetic. + {"ADDPL $9, R11, RSP", 0x046b513f}, + {"ADDVL $9, R11, RSP", 0x042b513f}, + {"RDVL $1, R27", 0x04bf503b}, } for _, tt := range tests { words := assembleArm64Words(t, arm64ExtProbeHead+"\t"+tt.stmt+"\n\tRET\n")