diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -318,6 +318,37 @@ def MVE_v16p8 : MVEVectorVTInfo; def MVE_v8p16 : MVEVectorVTInfo; + +multiclass MVE_TwoOpPattern { + // Unpredicated + def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), + (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; + + // Predicated + def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)), + PredOperands, + (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))), + (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), + ARMVCCThen, (VTI.Pred VCCR:$mask), + (VTI.Vec MQPR:$inactive)))>; +} + +multiclass MVE_TwoOpPatternDup { + // Unpredicated + def : Pat<(VTI.Vec (Op (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn)))), + (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn))>; + + // Predicated + def : Pat<(VTI.Vec !con((PredInt (VTI.Vec MQPR:$Qm), (VTI.Vec (ARMvdup rGPR:$Rn))), + PredOperands, + (? (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive)))), + (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), rGPR:$Rn, + ARMVCCThen, (VTI.Pred VCCR:$mask), + (VTI.Vec MQPR:$inactive)))>; +} + // --------- Start of base classes for the instructions themselves class MVE_MI pattern=[]> + list pattern=[]> : MVE_comp { let Inst{28} = 0b1; @@ -1231,46 +1262,19 @@ let Predicates = [HasMVEFloat]; } -def MVE_VMAXNMf32 : MVE_VMINMAXNM<"vmaxnm", "f32", 0b0, 0b0>; -def MVE_VMAXNMf16 : MVE_VMINMAXNM<"vmaxnm", "f16", 0b1, 0b0>; +multiclass MVE_VMINMAXNM_m { + def "" : MVE_VMINMAXNM; -let Predicates = [HasMVEFloat] in { - def : Pat<(v4f32 (fmaxnum (v4f32 MQPR:$val1), (v4f32 MQPR:$val2))), - (v4f32 (MVE_VMAXNMf32 (v4f32 MQPR:$val1), (v4f32 MQPR:$val2)))>; - def : Pat<(v8f16 (fmaxnum (v8f16 MQPR:$val1), (v8f16 MQPR:$val2))), - (v8f16 (MVE_VMAXNMf16 (v8f16 MQPR:$val1), (v8f16 MQPR:$val2)))>; - def : Pat<(v4f32 (int_arm_mve_max_predicated (v4f32 MQPR:$val1), (v4f32 MQPR:$val2), (i32 0), - (v4i1 VCCR:$mask), (v4f32 MQPR:$inactive))), - (v4f32 (MVE_VMAXNMf32 (v4f32 MQPR:$val1), (v4f32 MQPR:$val2), - ARMVCCThen, (v4i1 VCCR:$mask), - (v4f32 MQPR:$inactive)))>; - def : Pat<(v8f16 (int_arm_mve_max_predicated (v8f16 MQPR:$val1), (v8f16 MQPR:$val2), (i32 0), - (v8i1 VCCR:$mask), (v8f16 MQPR:$inactive))), - (v8f16 (MVE_VMAXNMf16 (v8f16 MQPR:$val1), (v8f16 MQPR:$val2), - ARMVCCThen, (v8i1 VCCR:$mask), - (v8f16 MQPR:$inactive)))>; -} - -def MVE_VMINNMf32 : MVE_VMINMAXNM<"vminnm", "f32", 0b0, 0b1>; -def MVE_VMINNMf16 : MVE_VMINMAXNM<"vminnm", "f16", 0b1, 0b1>; - -let Predicates = [HasMVEFloat] in { - def : Pat<(v4f32 (fminnum (v4f32 MQPR:$val1), (v4f32 MQPR:$val2))), - (v4f32 (MVE_VMINNMf32 (v4f32 MQPR:$val1), (v4f32 MQPR:$val2)))>; - def : Pat<(v8f16 (fminnum (v8f16 MQPR:$val1), (v8f16 MQPR:$val2))), - (v8f16 (MVE_VMINNMf16 (v8f16 MQPR:$val1), (v8f16 MQPR:$val2)))>; - def : Pat<(v4f32 (int_arm_mve_min_predicated (v4f32 MQPR:$val1), (v4f32 MQPR:$val2), - (i32 0), (v4i1 VCCR:$mask), (v4f32 MQPR:$inactive))), - (v4f32 (MVE_VMINNMf32 (v4f32 MQPR:$val1), (v4f32 MQPR:$val2), - ARMVCCThen, (v4i1 VCCR:$mask), - (v4f32 MQPR:$inactive)))>; - def : Pat<(v8f16 (int_arm_mve_min_predicated (v8f16 MQPR:$val1), (v8f16 MQPR:$val2), - (i32 0), (v8i1 VCCR:$mask), (v8f16 MQPR:$inactive))), - (v8f16 (MVE_VMINNMf16 (v8f16 MQPR:$val1), (v8f16 MQPR:$val2), - ARMVCCThen, (v8i1 VCCR:$mask), - (v8f16 MQPR:$inactive)))>; + let Predicates = [HasMVEFloat] in { + defm : MVE_TwoOpPattern(NAME)>; + } } +defm MVE_VMAXNMf32 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v4f32, fmaxnum, int_arm_mve_max_predicated>; +defm MVE_VMAXNMf16 : MVE_VMINMAXNM_m<"vmaxnm", 0b0, MVE_v8f16, fmaxnum, int_arm_mve_max_predicated>; +defm MVE_VMINNMf32 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v4f32, fminnum, int_arm_mve_min_predicated>; +defm MVE_VMINNMf16 : MVE_VMINMAXNM_m<"vminnm", 0b1, MVE_v8f16, fminnum, int_arm_mve_min_predicated>; + class MVE_VMINMAX size, bit bit_4, list pattern=[]> @@ -1288,22 +1292,11 @@ } multiclass MVE_VMINMAX_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VMINMAX; - defvar Inst = !cast(NAME); let Predicates = [HasMVEInt] in { - // Unpredicated min/max - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - - // Predicated min/max - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (i32 VTI.Unsigned), (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -1476,61 +1469,41 @@ (MVE_VAND MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>; } -multiclass MVE_bit_op { - let Predicates = [HasMVEInt] in { - // Unpredicated operation - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (instruction (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - // Predicated operation - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (instruction - (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; - } -} - -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; - -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; - -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; -defm : MVE_bit_op; - -multiclass MVE_bit_op_with_inv { - let Predicates = [HasMVEInt] in { - // Unpredicated operation - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (vnotq (VTI.Vec MQPR:$Qn)))), - (VTI.Vec (instruction (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - // Predicated operation - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (instruction - (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; - } +let Predicates = [HasMVEInt] in { + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + defm : MVE_TwoOpPattern; + + defm : MVE_TwoOpPattern, + int_arm_mve_bic_predicated, (? ), MVE_VBIC>; + defm : MVE_TwoOpPattern, + int_arm_mve_bic_predicated, (? ), MVE_VBIC>; + defm : MVE_TwoOpPattern, + int_arm_mve_bic_predicated, (? ), MVE_VBIC>; + defm : MVE_TwoOpPattern, + int_arm_mve_bic_predicated, (? ), MVE_VBIC>; + + defm : MVE_TwoOpPattern, + int_arm_mve_orn_predicated, (? ), MVE_VORN>; + defm : MVE_TwoOpPattern, + int_arm_mve_orn_predicated, (? ), MVE_VORN>; + defm : MVE_TwoOpPattern, + int_arm_mve_orn_predicated, (? ), MVE_VORN>; + defm : MVE_TwoOpPattern, + int_arm_mve_orn_predicated, (? ), MVE_VORN>; } -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; - -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; -defm : MVE_bit_op_with_inv; - class MVE_bit_cmode : MVE_p<(outs MQPR:$Qd), inOps, NoItinerary, iname, suffix, "$Qd, $imm", vpred_n, "$Qd = $Qd_src"> { @@ -1775,31 +1748,18 @@ let validForTailPredication = 1; } -multiclass MVE_VMUL_m { - def "" : MVE_VMULt1; - defvar Inst = !cast(NAME); +multiclass MVE_VMUL_m { + def "" : MVE_VMULt1<"vmul", VTI.Suffix, VTI.Size>; let Predicates = [HasMVEInt] in { - // Unpredicated multiply - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - - // Predicated multiply - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } -multiclass MVE_VMUL - : MVE_VMUL_m<"vmul", VTI, mul, int_arm_mve_mul_predicated>; - -defm MVE_VMULi8 : MVE_VMUL; -defm MVE_VMULi16 : MVE_VMUL; -defm MVE_VMULi32 : MVE_VMUL; +defm MVE_VMULi8 : MVE_VMUL_m; +defm MVE_VMULi16 : MVE_VMUL_m; +defm MVE_VMULi32 : MVE_VMUL_m; class MVE_VQxDMULH_Base size, bit rounding, list pattern=[]> @@ -1828,8 +1788,8 @@ def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + ARMVCCThen, (VTI.Pred VCCR:$mask), + (VTI.Vec MQPR:$inactive)))>; } } @@ -1862,21 +1822,12 @@ } multiclass MVE_VADDSUB_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VADDSUB; defvar Inst = !cast(NAME); let Predicates = [HasMVEInt] in { - // Unpredicated add/subtract - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - - // Predicated add/subtract - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -1914,22 +1865,13 @@ : MVE_VQADDSUB<"vqsub", suffix, U, 0b1, size>; multiclass MVE_VQADD_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VQADD_; defvar Inst = !cast(NAME); let Predicates = [HasMVEInt] in { - // Unpredicated saturating add - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - - // Predicated saturating add - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (i32 VTI.Unsigned), (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -1944,22 +1886,13 @@ defm MVE_VQADDu32 : MVE_VQADD; multiclass MVE_VQSUB_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VQSUB_; defvar Inst = !cast(NAME); let Predicates = [HasMVEInt] in { - // Unpredicated saturating subtract - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - - // Predicated saturating subtract - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (i32 VTI.Unsigned), (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -3469,18 +3402,12 @@ } multiclass MVE_VMULT_fp_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VMUL_fp; defvar Inst = !cast(NAME); let Predicates = [HasMVEFloat] in { - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -3591,20 +3518,14 @@ defm MVE_VFMSf16 : MVE_VFMA_fp_multi<"vfms", 1, MVE_v8f16>; multiclass MVE_VADDSUB_fp_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VADDSUBFMA_fp { let validForTailPredication = 1; } defvar Inst = !cast(NAME); let Predicates = [HasMVEFloat] in { - def : Pat<(VTI.Vec (unpred_op (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn)))>; - def : Pat<(VTI.Vec (pred_int (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - (VTI.Pred VCCR:$mask), (VTI.Vec MQPR:$inactive))), - (VTI.Vec (Inst (VTI.Vec MQPR:$Qm), (VTI.Vec MQPR:$Qn), - ARMVCCThen, (VTI.Pred VCCR:$mask), - (VTI.Vec MQPR:$inactive)))>; + defm : MVE_TwoOpPattern(NAME)>; } } @@ -5023,32 +4944,6 @@ } } -// Patterns for vector-scalar instructions with FP operands -multiclass MVE_vec_scalar_fp_pat_m { - let Predicates = [HasMVEFloat] in { - // Unpredicated F16 - def : Pat<(v8f16 (unpred_op (v8f16 MQPR:$Qm), (v8f16 (ARMvdup rGPR:$val)))), - (v8f16 (instr_f16 (v8f16 MQPR:$Qm), (i32 rGPR:$val)))>; - // Unpredicated F32 - def : Pat<(v4f32 (unpred_op (v4f32 MQPR:$Qm), (v4f32 (ARMvdup rGPR:$val)))), - (v4f32 (instr_f32 (v4f32 MQPR:$Qm), (i32 rGPR:$val)))>; - // Predicated F16 - def : Pat<(v8f16 (pred_int (v8f16 MQPR:$Qm), (v8f16 (ARMvdup rGPR:$val)), - (v8i1 VCCR:$mask), (v8f16 MQPR:$inactive))), - (v8f16 (instr_f16 (v8f16 MQPR:$Qm), (i32 rGPR:$val), - ARMVCCThen, (v8i1 VCCR:$mask), - (v8f16 MQPR:$inactive)))>; - // Predicated F32 - def : Pat<(v4f32 (pred_int (v4f32 MQPR:$Qm), (v4f32 (ARMvdup rGPR:$val)), - (v4i1 VCCR:$mask), (v4f32 MQPR:$inactive))), - (v4f32 (instr_f32 (v4f32 MQPR:$Qm), (i32 rGPR:$val), - ARMVCCThen, (v4i1 VCCR:$mask), - (v4f32 MQPR:$inactive)))>; - } -} - class MVE_VADDSUB_qr size, bit bit_5, bit bit_12, bit bit_16, bit bit_28> : MVE_qDest_rSrc { @@ -5064,10 +4959,11 @@ // Vector-scalar add/sub multiclass MVE_VADDSUB_qr_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VADDSUB_qr; - defm : MVE_vec_scalar_int_pat_m(NAME), VTI, - unpred_op, pred_int>; + let Predicates = [HasMVEInt] in { + defm : MVE_TwoOpPatternDup(NAME)>; + } } multiclass MVE_VADD_qr_m @@ -5086,36 +4982,35 @@ // Vector-scalar saturating add/sub multiclass MVE_VQADDSUB_qr_m { + SDNode Op, Intrinsic PredInt> { def "" : MVE_VADDSUB_qr; - defvar unpred_op = !if(VTI.Unsigned, unpred_op_u, unpred_op_s); - defm : MVE_vec_scalar_int_pat_m(NAME), VTI, - unpred_op, pred_int, 0, 1>; + + let Predicates = [HasMVEInt] in { + defm : MVE_TwoOpPatternDup(NAME)>; + } } -multiclass MVE_VQADD_qr_m - : MVE_VQADDSUB_qr_m<"vqadd", VTI, 0b0, saddsat, uaddsat, - int_arm_mve_qadd_predicated>; +multiclass MVE_VQADD_qr_m + : MVE_VQADDSUB_qr_m<"vqadd", VTI, 0b0, Op, int_arm_mve_qadd_predicated>; -multiclass MVE_VQSUB_qr_m - : MVE_VQADDSUB_qr_m<"vqsub", VTI, 0b1, ssubsat, usubsat, - int_arm_mve_qsub_predicated>; +multiclass MVE_VQSUB_qr_m + : MVE_VQADDSUB_qr_m<"vqsub", VTI, 0b1, Op, int_arm_mve_qsub_predicated>; -defm MVE_VQADD_qr_s8 : MVE_VQADD_qr_m; -defm MVE_VQADD_qr_s16 : MVE_VQADD_qr_m; -defm MVE_VQADD_qr_s32 : MVE_VQADD_qr_m; -defm MVE_VQADD_qr_u8 : MVE_VQADD_qr_m; -defm MVE_VQADD_qr_u16 : MVE_VQADD_qr_m; -defm MVE_VQADD_qr_u32 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_s8 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_s16 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_s32 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_u8 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_u16 : MVE_VQADD_qr_m; +defm MVE_VQADD_qr_u32 : MVE_VQADD_qr_m; -defm MVE_VQSUB_qr_s8 : MVE_VQSUB_qr_m; -defm MVE_VQSUB_qr_s16 : MVE_VQSUB_qr_m; -defm MVE_VQSUB_qr_s32 : MVE_VQSUB_qr_m; -defm MVE_VQSUB_qr_u8 : MVE_VQSUB_qr_m; -defm MVE_VQSUB_qr_u16 : MVE_VQSUB_qr_m; -defm MVE_VQSUB_qr_u32 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_s8 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_s16 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_s32 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_u8 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_u16 : MVE_VQSUB_qr_m; +defm MVE_VQSUB_qr_u32 : MVE_VQSUB_qr_m; class MVE_VQDMULL_qr pattern=[]> @@ -5206,19 +5101,25 @@ defm MVE_VHSUB_qr_u16 : MVE_VHSUB_qr_m; defm MVE_VHSUB_qr_u32 : MVE_VHSUB_qr_m; +multiclass MVE_VADDSUB_qr_f { + def "" : MVE_VxADDSUB_qr; + defm : MVE_TwoOpPatternDup(NAME)>; +} + let Predicates = [HasMVEFloat] in { - def MVE_VADD_qr_f32 : MVE_VxADDSUB_qr<"vadd", "f32", 0b0, 0b11, 0b0>; - def MVE_VADD_qr_f16 : MVE_VxADDSUB_qr<"vadd", "f16", 0b1, 0b11, 0b0>; + defm MVE_VADD_qr_f32 : MVE_VADDSUB_qr_f<"vadd", MVE_v4f32, 0b0, fadd, + int_arm_mve_add_predicated>; + defm MVE_VADD_qr_f16 : MVE_VADDSUB_qr_f<"vadd", MVE_v8f16, 0b0, fadd, + int_arm_mve_add_predicated>; - def MVE_VSUB_qr_f32 : MVE_VxADDSUB_qr<"vsub", "f32", 0b0, 0b11, 0b1>; - def MVE_VSUB_qr_f16 : MVE_VxADDSUB_qr<"vsub", "f16", 0b1, 0b11, 0b1>; + defm MVE_VSUB_qr_f32 : MVE_VADDSUB_qr_f<"vsub", MVE_v4f32, 0b1, fsub, + int_arm_mve_sub_predicated>; + defm MVE_VSUB_qr_f16 : MVE_VADDSUB_qr_f<"vsub", MVE_v8f16, 0b1, fsub, + int_arm_mve_sub_predicated>; } -defm : MVE_vec_scalar_fp_pat_m; -defm : MVE_vec_scalar_fp_pat_m; - class MVE_VxSHL_qr size, bit bit_7, bit bit_17, list pattern=[]> : MVE_qDest_single_rSrc { @@ -5346,8 +5247,8 @@ multiclass MVE_VMUL_qr_int_m { def "" : MVE_VMUL_qr_int<"vmul", VTI.Suffix, VTI.Size>; - defm : MVE_vec_scalar_int_pat_m(NAME), VTI, - mul, int_arm_mve_mul_predicated>; + defm : MVE_TwoOpPatternDup(NAME)>; } defm MVE_VMUL_qr_i8 : MVE_VMUL_qr_int_m; @@ -5389,13 +5290,17 @@ defm MVE_VQRDMULH_qr_s16 : MVE_VQRDMULH_qr_m; defm MVE_VQRDMULH_qr_s32 : MVE_VQRDMULH_qr_m; -let Predicates = [HasMVEFloat], validForTailPredication = 1 in { - def MVE_VMUL_qr_f16 : MVE_VxxMUL_qr<"vmul", "f16", 0b1, 0b11>; - def MVE_VMUL_qr_f32 : MVE_VxxMUL_qr<"vmul", "f32", 0b0, 0b11>; +multiclass MVE_VxxMUL_qr_f_m { + let validForTailPredication = 1 in + def "" : MVE_VxxMUL_qr<"vmul", VTI.Suffix, VTI.Size{0}, 0b11>; + defm : MVE_TwoOpPatternDup(NAME)>; } -defm : MVE_vec_scalar_fp_pat_m; +let Predicates = [HasMVEFloat] in { + defm MVE_VMUL_qr_f16 : MVE_VxxMUL_qr_f_m; + defm MVE_VMUL_qr_f32 : MVE_VxxMUL_qr_f_m; +} class MVE_VFMAMLA_qr bits_21_20, bit S,