diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index a3049d4aeaf..ade4674d31a 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -67,9 +67,14 @@ def HI48_64 : SDNodeXForm, Requires<[In64BitMode]>; + + def BCCTR8 : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond), + "b${cond:cc}ctr ${cond:reg}", BrB, []>, + Requires<[In64BitMode]>; + } } let Defs = [LR8] in @@ -125,6 +130,9 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR8] in { def BCTRL8 : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins), "bctrl", BrB, [(PPCbctrl)]>, Requires<[In64BitMode]>; + def BCCTRL8 : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond), + "b${cond:cc}ctrl ${cond:reg}", BrB, []>, + Requires<[In64BitMode]>; } } diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 51bc4f23cce..773b62326fb 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -882,6 +882,10 @@ bool PPCInstrInfo::isPredicated(const MachineInstr *MI) const { default: return false; case PPC::BCC: + case PPC::BCCTR: + case PPC::BCCTR8: + case PPC::BCCTRL: + case PPC::BCCTRL8: case PPC::BCLR: case PPC::BDZLR: case PPC::BDZLR8: @@ -938,6 +942,19 @@ bool PPCInstrInfo::PredicateInstruction( } return true; + } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || + OpC == PPC::BCTRL || OpC == PPC::BCTRL8) { + if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) + llvm_unreachable("Cannot predicate bctr[l] on the ctr register"); + + bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8; + bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); + MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) : + (setLR ? PPC::BCCTRL : PPC::BCCTR))); + MachineInstrBuilder(*MI->getParent()->getParent(), MI) + .addImm(Pred[0].getImm()) + .addReg(Pred[1].getReg()); + return true; } return false; @@ -1009,6 +1026,10 @@ bool PPCInstrInfo::isPredicable(MachineInstr *MI) const { return false; case PPC::B: case PPC::BLR: + case PPC::BCTR: + case PPC::BCTR8: + case PPC::BCTRL: + case PPC::BCTRL8: return true; } } diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 11969fed85b..6c12f68c1d0 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -493,8 +493,12 @@ let isTerminator = 1, isBarrier = 1, PPC970_Unit = 7 in { let isReturn = 1, Uses = [LR, RM] in def BLR : XLForm_2_ext<19, 16, 20, 0, 0, (outs), (ins), "blr", BrB, [(retflag)]>; - let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in + let isBranch = 1, isIndirectBranch = 1, Uses = [CTR] in { def BCTR : XLForm_2_ext<19, 528, 20, 0, 0, (outs), (ins), "bctr", BrB, []>; + + def BCCTR : XLForm_2_br<19, 528, 0, (outs), (ins pred:$cond), + "b${cond:cc}ctr ${cond:reg}", BrB, []>; + } } let Defs = [LR] in @@ -555,6 +559,8 @@ let isCall = 1, PPC970_Unit = 7, Defs = [LR] in { def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins), "bctrl", BrB, [(PPCbctrl)]>, Requires<[In32BitMode]>; + def BCCTRL : XLForm_2_br<19, 528, 1, (outs), (ins pred:$cond), + "b${cond:cc}ctrl ${cond:reg}", BrB, []>; } }