@@ -76,6 +76,12 @@ def VSxth: OutPatFrag<(ops node:$Vs), (V6_vunpackh $Vs)>;
7676def VZxtb: OutPatFrag<(ops node:$Vs), (V6_vunpackub $Vs)>;
7777def VZxth: OutPatFrag<(ops node:$Vs), (V6_vunpackuh $Vs)>;
7878
79+ def VShuff: OutPatFrag<(ops node:$Vs, node:$S),
80+ (V6_vshuffvdd (HiVec $Vs), (LoVec $Vs), (A2_tfrsi $S))>;
81+
82+ def VDeal: OutPatFrag<(ops node:$Vs, node:$S),
83+ (V6_vdealvdd (HiVec $Vs), (LoVec $Vs), (A2_tfrsi $S))>;
84+
7985class VSubi<InstHexagon VSub, InstHexagon VSplati>:
8086 OutPatFrag<(ops node:$Imm, node:$Vs), (VSub (VSplati (i32 $Imm)), $Vs)>;
8187
@@ -402,6 +408,64 @@ class Vneg1<ValueType VecTy>
402408class Vnot<ValueType VecTy>
403409 : PatFrag<(ops node:$Vs), (xor $Vs, Vneg1<VecTy>)>;
404410
411+ class ExtOp_pat<InstHexagon MI, PatFrag Op, PatFrag Ext, ValueType ResType,
412+ PatFrag VPred, int Shuff>
413+ : Pat<(ResType (Op (Ext VPred:$Vs), (Ext VPred:$Vt))),
414+ (VShuff (MI VPred:$Vs, VPred:$Vt), Shuff)>;
415+
416+ class VOpAcc_pat<InstHexagon MI, PatFrag Op, PatFrag Ext, ValueType ResType,
417+ PatFrag VxPred, PatFrag VsPred, int Shuff>
418+ : Pat<(ResType (add VxPred:$Vx, (Op (Ext VsPred:$Vs), (Ext VsPred:$Vt)))),
419+ (VShuff (MI (VDeal $Vx, Shuff), VsPred:$Vs, VsPred:$Vt), Shuff)>;
420+
421+ let Predicates = [UseHVX] in {
422+ let AddedComplexity = 200 in {
423+ def : ExtOp_pat<V6_vaddubh, Add, Zext, VecPI16, HVI8, -2>;
424+ def : ExtOp_pat<V6_vadduhw, Add, Zext, VecPI32, HVI16, -4>;
425+ def : ExtOp_pat<V6_vaddhw, Add, Sext, VecPI32, HVI16, -4>;
426+
427+ def : ExtOp_pat<V6_vsububh, Sub, Zext, VecPI16, HVI8, -2>;
428+ def : ExtOp_pat<V6_vsubuhw, Sub, Zext, VecPI32, HVI16, -4>;
429+ def : ExtOp_pat<V6_vsubhw, Sub, Sext, VecPI32, HVI16, -4>;
430+
431+ def : ExtOp_pat<V6_vmpybv, Mul, Sext, VecPI16, HVI8, -2>;
432+ def : ExtOp_pat<V6_vmpyhv, Mul, Sext, VecPI32, HVI16, -4>;
433+ def : ExtOp_pat<V6_vmpyubv, Mul, Zext, VecPI16, HVI8, -2>;
434+ def : ExtOp_pat<V6_vmpyuhv, Mul, Zext, VecPI32, HVI16, -4>;
435+
436+ // The first operand in V6_vmpybusv is unsigned.
437+ def : Pat<(VecPI16 (mul (VecPI16 (zext HVI8:$Vs)),
438+ (VecPI16 (sext HVI8:$Vv)))),
439+ (VShuff (V6_vmpybusv HVI8:$Vs, HVI8:$Vv), -2)>;
440+
441+ // The second operand in V6_vmpyhus is unsigned.
442+ def : Pat<(VecPI32 (mul (VecPI32 (sext HVI16:$Vs)),
443+ (VecPI32 (zext HVI16:$Vv)))),
444+ (VShuff (V6_vmpyhus HVI16:$Vs, HVI16:$Vv), -4)>;
445+
446+ def : VOpAcc_pat<V6_vaddubh_acc, Add, Zext, VecPI16, HWI16, HVI8, -2>;
447+ def : VOpAcc_pat<V6_vadduhw_acc, Add, Zext, VecPI32, HWI32, HVI16, -4>;
448+ def : VOpAcc_pat<V6_vaddhw_acc, Add, Sext, VecPI32, HWI32, HVI16, -4>;
449+
450+ def : VOpAcc_pat<V6_vmpybv_acc, Mul, Sext, VecPI16, HWI16, HVI8, -2>;
451+ def : VOpAcc_pat<V6_vmpyubv_acc, Mul, Zext, VecPI16, HWI16, HVI8, -2>;
452+ def : VOpAcc_pat<V6_vmpyhv_acc, Mul, Sext, VecPI32, HWI32, HVI16, -4>;
453+ def : VOpAcc_pat<V6_vmpyuhv_acc, Mul, Zext, VecPI32, HWI32, HVI16, -4>;
454+
455+ // The second operand in V6_vmpybusv_acc is unsigned.
456+ def : Pat<(VecPI16 (add HWI16:$Vx , (mul (VecPI16 (zext HVI8:$Vs)),
457+ (VecPI16 (sext HVI8:$Vt))))),
458+ (VShuff (V6_vmpybusv_acc (VDeal $Vx, -2),
459+ HVI8:$Vs, HVI8:$Vt), -2)>;
460+
461+ // The third operand in V6_vmpyhus_acc is unsigned.
462+ def : Pat<(add HWI32:$Vx, (mul (VecPI32 (sext HVI16:$Vs)),
463+ (VecPI32 (zext HVI16:$Vt)))),
464+ (VShuff (V6_vmpyhus_acc (VDeal $Vx, -4),
465+ HVI16:$Vs, HVI16:$Vt), -4)>;
466+ }
467+ }
468+
405469let Predicates = [UseHVX] in {
406470 let AddedComplexity = 200 in {
407471 def: Pat<(Vnot<VecI8> HVI8:$Vs), (V6_vnot HvxVR:$Vs)>;
0 commit comments