def ExtensionHVX128B: SubtargetFeature<"hvx-length128b", "UseHVX128BOps",
"true", "Hexagon HVX 128B instructions", [ExtensionHVX]>;
+def FeatureCompound: SubtargetFeature<"compound", "UseCompound", "true",
+ "Use compound instructions">;
def FeaturePackets: SubtargetFeature<"packets", "UsePackets", "true",
"Support for instruction packets">;
def FeatureLongCalls: SubtargetFeature<"long-calls", "UseLongCalls", "true",
AssemblerPredicate<"ExtensionHVXV66">;
def UseZReg : Predicate<"HST->useZRegOps()">,
AssemblerPredicate<"ExtensionZReg">;
+def UseCompound : Predicate<"HST->useCompound()">;
def Hvx64: HwMode<"+hvx-length64b">;
def Hvx128: HwMode<"+hvx-length128b">;
def : Proc<"generic", HexagonModelV60,
[ArchV5, ArchV55, ArchV60,
- FeatureDuplex, FeatureMemops, FeatureNVJ, FeatureNVS,
- FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemops, FeatureNVJ,
+ FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv5", HexagonModelV5,
[ArchV5,
- FeatureDuplex, FeatureMemops, FeatureNVJ, FeatureNVS,
- FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemops, FeatureNVJ,
+ FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv55", HexagonModelV55,
[ArchV5, ArchV55,
- FeatureDuplex, FeatureMemops, FeatureNVJ, FeatureNVS,
- FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemops, FeatureNVJ,
+ FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv60", HexagonModelV60,
[ArchV5, ArchV55, ArchV60,
- FeatureDuplex, FeatureMemops, FeatureNVJ, FeatureNVS,
- FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemops, FeatureNVJ,
+ FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv62", HexagonModelV62,
[ArchV5, ArchV55, ArchV60, ArchV62,
- FeatureDuplex, FeatureMemops, FeatureNVJ, FeatureNVS,
- FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemops, FeatureNVJ,
+ FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv65", HexagonModelV65,
[ArchV5, ArchV55, ArchV60, ArchV62, ArchV65,
- FeatureDuplex, FeatureMemNoShuf, FeatureMemops, FeatureNVJ,
- FeatureNVS, FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemNoShuf, FeatureMemops,
+ FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
def : Proc<"hexagonv66", HexagonModelV66,
[ArchV5, ArchV55, ArchV60, ArchV62, ArchV65, ArchV66,
- FeatureDuplex, FeatureMemNoShuf, FeatureMemops, FeatureNVJ,
- FeatureNVS, FeaturePackets, FeatureSmallData]>;
+ FeatureCompound, FeatureDuplex, FeatureMemNoShuf, FeatureMemops,
+ FeatureNVJ, FeatureNVS, FeaturePackets, FeatureSmallData]>;
//===----------------------------------------------------------------------===//
// Declare the target which we are implementing
using AssignmentMap = std::map<ExtenderInit, IndexList>;
using LocDefList = std::vector<std::pair<Loc, IndexList>>;
+ const HexagonSubtarget *HST = nullptr;
const HexagonInstrInfo *HII = nullptr;
const HexagonRegisterInfo *HRI = nullptr;
MachineDominatorTree *MDT = nullptr;
.add(ExtOp);
}
} else {
- unsigned NewOpc = Ex.Neg ? Hexagon::S4_subi_asl_ri
- : Hexagon::S4_addi_asl_ri;
- // DefR = add(##EV,asl(Rb,S))
- InitI = BuildMI(MBB, At, dl, HII->get(NewOpc), DefR)
- .add(ExtOp)
- .add(MachineOperand(Ex.Rs))
- .addImm(Ex.S);
+ if (HST->useCompound()) {
+ unsigned NewOpc = Ex.Neg ? Hexagon::S4_subi_asl_ri
+ : Hexagon::S4_addi_asl_ri;
+ // DefR = add(##EV,asl(Rb,S))
+ InitI = BuildMI(MBB, At, dl, HII->get(NewOpc), DefR)
+ .add(ExtOp)
+ .add(MachineOperand(Ex.Rs))
+ .addImm(Ex.S);
+ } else {
+ // No compounds are available. It is not clear whether we should
+ // even process such extenders where the initializer cannot be
+ // a single instruction, but do it for now.
+ unsigned TmpR = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
+ BuildMI(MBB, At, dl, HII->get(Hexagon::S2_asl_i_r), TmpR)
+ .add(MachineOperand(Ex.Rs))
+ .addImm(Ex.S);
+ if (Ex.Neg)
+ InitI = BuildMI(MBB, At, dl, HII->get(Hexagon::A2_subri), DefR)
+ .add(ExtOp)
+ .add(MachineOperand(Register(TmpR, 0)));
+ else
+ InitI = BuildMI(MBB, At, dl, HII->get(Hexagon::A2_addi), DefR)
+ .add(MachineOperand(Register(TmpR, 0)))
+ .add(ExtOp);
+ }
}
}
}
LLVM_DEBUG(MF.print(dbgs() << "Before " << getPassName() << '\n', nullptr));
- HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
- HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
+ HST = &MF.getSubtarget<HexagonSubtarget>();
+ HII = HST->getInstrInfo();
+ HRI = HST->getRegisterInfo();
MDT = &getAnalysis<MachineDominatorTree>();
MRI = &MF.getRegInfo();
AssignmentMap IMap;
(outs IntRegs:$Rd32),
(ins u32_0Imm:$Ii, IntRegs:$Rs32, u6_0Imm:$II),
"$Rd32 = add(#$Ii,mpyi($Rs32,#$II))",
-tc_05d3a09b, TypeALU64>, Enc_322e1b, ImmRegRel {
+tc_05d3a09b, TypeALU64>, Enc_322e1b, Requires<[UseCompound]>, ImmRegRel {
let Inst{31-24} = 0b11011000;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rd32),
(ins IntRegs:$Ru32, IntRegs:$Rs32, u32_0Imm:$Ii),
"$Rd32 = add($Ru32,mpyi($Rs32,#$Ii))",
-tc_05d3a09b, TypeALU64>, Enc_420cf3, ImmRegRel {
+tc_05d3a09b, TypeALU64>, Enc_420cf3, Requires<[UseCompound]>, ImmRegRel {
let Inst{31-23} = 0b110111111;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rd32),
(ins IntRegs:$Ru32, u6_2Imm:$Ii, IntRegs:$Rs32),
"$Rd32 = add($Ru32,mpyi(#$Ii,$Rs32))",
-tc_1a2fd869, TypeALU64>, Enc_277737 {
+tc_1a2fd869, TypeALU64>, Enc_277737, Requires<[UseCompound]> {
let Inst{31-23} = 0b110111110;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rd32),
(ins u32_0Imm:$Ii, IntRegs:$Rs32, IntRegs:$Rt32),
"$Rd32 = add(#$Ii,mpyi($Rs32,$Rt32))",
-tc_d773585a, TypeALU64>, Enc_a7b8e8, ImmRegRel {
+tc_d773585a, TypeALU64>, Enc_a7b8e8, Requires<[UseCompound]>, ImmRegRel {
let Inst{31-23} = 0b110101110;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Ry32),
(ins IntRegs:$Ru32, IntRegs:$Ry32in, IntRegs:$Rs32),
"$Ry32 = add($Ru32,mpyi($Ry32in,$Rs32))",
-tc_d773585a, TypeM>, Enc_7f1a05, ImmRegRel {
+tc_d773585a, TypeM>, Enc_7f1a05, Requires<[UseCompound]>, ImmRegRel {
let Inst{7-5} = 0b000;
let Inst{13-13} = 0b0;
let Inst{31-21} = 0b11100011000;
(outs IntRegs:$Rd32),
(ins IntRegs:$Rs32, IntRegs:$Ru32, s32_0Imm:$Ii),
"$Rd32 = add($Rs32,add($Ru32,#$Ii))",
-tc_f675fee8, TypeALU64>, Enc_8b8d61 {
+tc_f675fee8, TypeALU64>, Enc_8b8d61, Requires<[UseCompound]> {
let Inst{31-23} = 0b110110110;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = add(#$Ii,asl($Rx32in,#$II))",
-tc_f675fee8, TypeALU64>, Enc_c31910 {
+tc_f675fee8, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b100;
let Inst{4-4} = 0b0;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = add(#$Ii,lsr($Rx32in,#$II))",
-tc_f675fee8, TypeALU64>, Enc_c31910 {
+tc_f675fee8, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b100;
let Inst{4-4} = 0b1;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = and(#$Ii,asl($Rx32in,#$II))",
-tc_f429765c, TypeALU64>, Enc_c31910 {
+tc_f429765c, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b000;
let Inst{4-4} = 0b0;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = and(#$Ii,lsr($Rx32in,#$II))",
-tc_f429765c, TypeALU64>, Enc_c31910 {
+tc_f429765c, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b000;
let Inst{4-4} = 0b1;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins IntRegs:$Ru32, IntRegs:$Rx32in, s32_0Imm:$Ii),
"$Rx32 = or($Ru32,and($Rx32in,#$Ii))",
-tc_f429765c, TypeALU64>, Enc_b4e6cf {
+tc_f429765c, TypeALU64>, Enc_b4e6cf, Requires<[UseCompound]> {
let Inst{31-22} = 0b1101101001;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = or(#$Ii,asl($Rx32in,#$II))",
-tc_f429765c, TypeALU64>, Enc_c31910 {
+tc_f429765c, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b010;
let Inst{4-4} = 0b0;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = or(#$Ii,lsr($Rx32in,#$II))",
-tc_f429765c, TypeALU64>, Enc_c31910 {
+tc_f429765c, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b010;
let Inst{4-4} = 0b1;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rd32),
(ins IntRegs:$Rs32, s32_0Imm:$Ii, IntRegs:$Ru32),
"$Rd32 = add($Rs32,sub(#$Ii,$Ru32))",
-tc_f675fee8, TypeALU64>, Enc_8b8d61 {
+tc_f675fee8, TypeALU64>, Enc_8b8d61, Requires<[UseCompound]> {
let Inst{31-23} = 0b110110111;
let hasNewValue = 1;
let opNewValue = 0;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = sub(#$Ii,asl($Rx32in,#$II))",
-tc_f675fee8, TypeALU64>, Enc_c31910 {
+tc_f675fee8, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b110;
let Inst{4-4} = 0b0;
let Inst{31-24} = 0b11011110;
(outs IntRegs:$Rx32),
(ins u32_0Imm:$Ii, IntRegs:$Rx32in, u5_0Imm:$II),
"$Rx32 = sub(#$Ii,lsr($Rx32in,#$II))",
-tc_f675fee8, TypeALU64>, Enc_c31910 {
+tc_f675fee8, TypeALU64>, Enc_c31910, Requires<[UseCompound]> {
let Inst{2-0} = 0b110;
let Inst{4-4} = 0b1;
let Inst{31-24} = 0b11011110;
def: Pat<(int_hexagon_S2_asl_i_r_acc IntRegs:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
(S2_asl_i_r_acc IntRegs:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_subi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_subi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_subi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S2_vzxthw IntRegs:$src1),
(S2_vzxthw IntRegs:$src1)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_F2_sfadd IntRegs:$src1, IntRegs:$src2),
def: Pat<(int_hexagon_M4_or_and IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M4_or_and IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M4_mpyrr_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, IntRegs:$src3),
- (M4_mpyrr_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
+ (M4_mpyrr_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S4_or_andi IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3),
(S4_or_andi IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpy_sat_hl_s0 IntRegs:$src1, IntRegs:$src2),
def: Pat<(int_hexagon_M2_mpy_sat_hl_s1 IntRegs:$src1, IntRegs:$src2),
(M2_mpy_sat_hl_s1 IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M4_mpyrr_addr IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- (M4_mpyrr_addr IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
+ (M4_mpyrr_addr IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mmachs_rs0 DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
(M2_mmachs_rs0 DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mmachs_rs1 DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
def: Pat<(int_hexagon_M2_cnacsc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M2_cnacsc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_subaddi IntRegs:$src1, s32_0ImmPred_timm:$src2, IntRegs:$src3),
- (S4_subaddi IntRegs:$src1, s32_0ImmPred_timm:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
+ (S4_subaddi IntRegs:$src1, s32_0ImmPred_timm:$src2, IntRegs:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mpyud_nac_hl_s1 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M2_mpyud_nac_hl_s1 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpyud_nac_hl_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
def: Pat<(int_hexagon_M2_vmpy2s_s0pack IntRegs:$src1, IntRegs:$src2),
(M2_vmpy2s_s0pack IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_addaddi IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3),
- (S4_addaddi IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_addaddi IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mpyd_acc_ll_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M2_mpyd_acc_ll_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpy_acc_sat_hl_s1 IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
def: Pat<(int_hexagon_S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
(S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_ori_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_ori_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_ori_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_C4_nbitsset IntRegs:$src1, IntRegs:$src2),
(C4_nbitsset IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpyu_acc_hh_s1 IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
def: Pat<(int_hexagon_A2_minp DoubleRegs:$src1, DoubleRegs:$src2),
(A2_minp DoubleRegs:$src1, DoubleRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_or_andix IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3),
- (S4_or_andix IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_or_andix IntRegs:$src1, IntRegs:$src2, s32_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mpy_rnd_lh_s0 IntRegs:$src1, IntRegs:$src2),
(M2_mpy_rnd_lh_s0 IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpy_rnd_lh_s1 IntRegs:$src1, IntRegs:$src2),
def: Pat<(int_hexagon_C4_cmplteui IntRegs:$src1, u32_0ImmPred_timm:$src2),
(C4_cmplteui IntRegs:$src1, u32_0ImmPred_timm:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_addi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_addi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_addi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_A4_tfrcpp CtrRegs64:$src1),
(A4_tfrcpp CtrRegs64:$src1)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S2_asr_i_svw_trun DoubleRegs:$src1, u5_0ImmPred_timm:$src2),
def: Pat<(int_hexagon_A2_vnavghcr DoubleRegs:$src1, DoubleRegs:$src2),
(A2_vnavghcr DoubleRegs:$src1, DoubleRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_subi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_subi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_subi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S2_lsl_r_vh DoubleRegs:$src1, IntRegs:$src2),
(S2_lsl_r_vh DoubleRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpy_hh_s0 IntRegs:$src1, IntRegs:$src2),
def: Pat<(int_hexagon_C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2),
(C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M4_mpyri_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, u6_0ImmPred_timm:$src3),
- (M4_mpyri_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, u6_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (M4_mpyri_addi u32_0ImmPred_timm:$src1, IntRegs:$src2, u6_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S4_andi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_andi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_andi_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_macsip IntRegs:$src1, IntRegs:$src2, u32_0ImmPred_timm:$src3),
(M2_macsip IntRegs:$src1, IntRegs:$src2, u32_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_A2_tfrcrr CtrRegs:$src1),
def: Pat<(int_hexagon_S2_vsxthw IntRegs:$src1),
(S2_vsxthw IntRegs:$src1)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_andi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_andi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_andi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$src2, u6_0ImmPred_timm:$src3),
(S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$src2, u6_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S2_lsl_r_p_xor DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
def: Pat<(int_hexagon_M2_vcmpy_s1_sat_r DoubleRegs:$src1, DoubleRegs:$src2),
(M2_vcmpy_s1_sat_r DoubleRegs:$src1, DoubleRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M4_mpyri_addr_u2 IntRegs:$src1, u6_2ImmPred_timm:$src2, IntRegs:$src3),
- (M4_mpyri_addr_u2 IntRegs:$src1, u6_2ImmPred_timm:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
+ (M4_mpyri_addr_u2 IntRegs:$src1, u6_2ImmPred_timm:$src2, IntRegs:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_vcmpy_s1_sat_i DoubleRegs:$src1, DoubleRegs:$src2),
(M2_vcmpy_s1_sat_i DoubleRegs:$src1, DoubleRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S2_lsl_r_p_nac DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
def: Pat<(int_hexagon_A2_tfril IntRegs:$src1, u16_0ImmPred_timm:$src2),
(A2_tfril IntRegs:$src1, u16_0ImmPred_timm:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M4_mpyri_addr IntRegs:$src1, IntRegs:$src2, u32_0ImmPred_timm:$src3),
- (M4_mpyri_addr IntRegs:$src1, IntRegs:$src2, u32_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (M4_mpyri_addr IntRegs:$src1, IntRegs:$src2, u32_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_S2_vtrunehb DoubleRegs:$src1),
(S2_vtrunehb DoubleRegs:$src1)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_A2_vabsw DoubleRegs:$src1),
def: Pat<(int_hexagon_A2_svaddhs IntRegs:$src1, IntRegs:$src2),
(A2_svaddhs IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_ori_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_ori_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_ori_lsr_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mpy_sat_rnd_ll_s1 IntRegs:$src1, IntRegs:$src2),
(M2_mpy_sat_rnd_ll_s1 IntRegs:$src1, IntRegs:$src2)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpy_sat_rnd_ll_s0 IntRegs:$src1, IntRegs:$src2),
def: Pat<(int_hexagon_M2_mpy_acc_hh_s0 IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M2_mpy_acc_hh_s0 IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_S4_addi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3),
- (S4_addi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[HasV5]>;
+ (S4_addi_asl_ri u32_0ImmPred_timm:$src1, IntRegs:$src2, u5_0ImmPred_timm:$src3)>, Requires<[UseCompound, HasV5]>;
def: Pat<(int_hexagon_M2_mpyd_nac_hh_s1 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
(M2_mpyd_nac_hh_s1 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>, Requires<[HasV5]>;
def: Pat<(int_hexagon_M2_mpyd_nac_hh_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
MVT::i64, Ops);
// Shift right by "(Addr & 0x3) * 8" bytes.
+ SDNode *C;
SDValue M0 = CurDAG->getTargetConstant(0x18, dl, MVT::i32);
SDValue M1 = CurDAG->getTargetConstant(0x03, dl, MVT::i32);
- SDNode *C = CurDAG->getMachineNode(Hexagon::S4_andi_asl_ri, dl, MVT::i32,
- M0, N->getOperand(2), M1);
+ if (HST->useCompound()) {
+ C = CurDAG->getMachineNode(Hexagon::S4_andi_asl_ri, dl, MVT::i32,
+ M0, N->getOperand(2), M1);
+ } else {
+ SDNode *T = CurDAG->getMachineNode(Hexagon::S2_asl_i_r, dl, MVT::i32,
+ N->getOperand(2), M1);
+ C = CurDAG->getMachineNode(Hexagon::A2_andir, dl, MVT::i32,
+ SDValue(T, 0), M0);
+ }
SDNode *S = CurDAG->getMachineNode(Hexagon::S2_lsr_r_p, dl, MVT::i64,
SDValue(R, 0), SDValue(C, 0));
SDValue E = CurDAG->getTargetExtractSubreg(Hexagon::isub_lo, dl, ResTy,
: Pat<(Op anyimm:$u8, (ShOp RegPred:$Rs, ImmPred:$U5)),
(MI anyimm:$u8, RegPred:$Rs, imm:$U5)>;
-let AddedComplexity = 200 in {
+let AddedComplexity = 200, Predicates = [UseCompound] in {
def: OpshIRI_pat<S4_addi_asl_ri, Add, Su<Shl>, I32, u5_0ImmPred>;
def: OpshIRI_pat<S4_addi_lsr_ri, Add, Su<Srl>, I32, u5_0ImmPred>;
def: OpshIRI_pat<S4_subi_asl_ri, Sub, Su<Shl>, I32, u5_0ImmPred>;
// S4_addaddi and S4_subaddi don't have tied operands, so give them
// a bit of preference.
-let AddedComplexity = 30 in {
+let AddedComplexity = 30, Predicates = [UseCompound] in {
def: Pat<(add I32:$Rs, (Su<Add> I32:$Ru, anyimm:$s6)),
(S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>;
def: Pat<(add anyimm:$s6, (Su<Add> I32:$Rs, I32:$Ru)),
(S4_subaddi IntRegs:$Rs, imm:$s6, IntRegs:$Ru)>;
}
+let Predicates = [UseCompound] in
def: Pat<(or I32:$Ru, (Su<And> I32:$Rx, anyimm:$s10)),
(S4_or_andix IntRegs:$Ru, IntRegs:$Rx, imm:$s10)>;
+
def: Pat<(or I32:$Rx, (Su<And> I32:$Rs, anyimm:$s10)),
(S4_or_andi IntRegs:$Rx, IntRegs:$Rs, imm:$s10)>;
def: Pat<(or I32:$Rx, (Su<Or> I32:$Rs, anyimm:$s10)),
// will put the immediate addend into a register, while these instructions will
// use it directly. Such a construct does not appear in the middle of a gep,
// where M2_macsip would be preferable.
-let AddedComplexity = 20 in {
+let AddedComplexity = 20, Predicates = [UseCompound] in {
def: Pat<(add (Su<Mul> I32:$Rs, u6_0ImmPred:$U6), anyimm:$u6),
(M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>;
def: Pat<(add (Su<Mul> I32:$Rs, I32:$Rt), anyimm:$u6),
(M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>;
}
-// Keep these instructions less preferable to M2_macsip/M2_macsin.
-def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, u6_2ImmPred:$u6_2)),
- (M4_mpyri_addr_u2 IntRegs:$Ru, imm:$u6_2, IntRegs:$Rs)>;
-def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, anyimm:$u6)),
- (M4_mpyri_addr IntRegs:$Ru, IntRegs:$Rs, imm:$u6)>;
-def: Pat<(add I32:$Ru, (Su<Mul> I32:$Ry, I32:$Rs)),
- (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$Ry, IntRegs:$Rs)>;
-
+let Predicates = [UseCompound] in {
+ // Keep these instructions less preferable to M2_macsip/M2_macsin.
+ def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, u6_2ImmPred:$u6_2)),
+ (M4_mpyri_addr_u2 IntRegs:$Ru, imm:$u6_2, IntRegs:$Rs)>;
+ def: Pat<(add I32:$Ru, (Su<Mul> I32:$Rs, anyimm:$u6)),
+ (M4_mpyri_addr IntRegs:$Ru, IntRegs:$Rs, imm:$u6)>;
+ def: Pat<(add I32:$Ru, (Su<Mul> I32:$Ry, I32:$Rs)),
+ (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$Ry, IntRegs:$Rs)>;
+}
def: Pat<(fma F32:$Rs, F32:$Rt, F32:$Rx),
(F2_sffma F32:$Rx, F32:$Rs, F32:$Rt)>;
bool UseHVX64BOps = false;
bool UseHVX128BOps = false;
+ bool UseCompound = false;
bool UseLongCalls = false;
bool UseMemops = false;
bool UsePackets = false;
return getHexagonArchVersion() == Hexagon::ArchEnum::V66;
}
+ bool useCompound() const { return UseCompound; }
bool useLongCalls() const { return UseLongCalls; }
bool useMemops() const { return UseMemops; }
bool usePackets() const { return UsePackets; }
--- /dev/null
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; CHECK-LABEL: t0
+; CHECK: r0 = add(r1,add(r0,#23))
+define i32 @t0(i32 %a0, i32 %a1) #0 {
+ %v0 = add i32 %a1, 23
+ %v1 = add i32 %a0, %v0
+ ret i32 %v1
+}
+
+; CHECK-LABEL: t1
+; CHECK: r[[R:[0-9]+]] = add(r1,r0)
+; CHECK: r0 = add(r[[R]],#23)
+define i32 @t1(i32 %a0, i32 %a1) #1 {
+ %v0 = add i32 %a1, 23
+ %v1 = add i32 %a0, %v0
+ ret i32 %v1
+}
+
+attributes #0 = { nounwind readnone "target-cpu"="hexagonv62" "target-features"="+compound" }
+attributes #1 = { nounwind readnone "target-cpu"="hexagonv62" "target-features"="-compound" }