aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCMacroFusion.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCMacroFusion.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp b/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
index bdff5109c1e1..9d5206f8fd43 100644
--- a/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMacroFusion.cpp
@@ -149,6 +149,79 @@ static bool checkOpConstraints(FusionFeature::FusionKind Kd,
case FusionFeature::FK_SldiAdd:
return (matchingImmOps(FirstMI, 2, 3) && matchingImmOps(FirstMI, 3, 60)) ||
(matchingImmOps(FirstMI, 2, 6) && matchingImmOps(FirstMI, 3, 57));
+
+ // rldicl rx, ra, 1, 0 - xor
+ case FusionFeature::FK_RotateLeftXor:
+ return matchingImmOps(FirstMI, 2, 1) && matchingImmOps(FirstMI, 3, 0);
+
+ // rldicr rx, ra, 1, 63 - xor
+ case FusionFeature::FK_RotateRightXor:
+ return matchingImmOps(FirstMI, 2, 1) && matchingImmOps(FirstMI, 3, 63);
+
+ // We actually use CMPW* and CMPD*, 'l' doesn't exist as an operand in instr.
+
+ // { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpi 0,1,rx,{ 0,1,-1 }
+ // { lbz,lbzx,lhz,lhzx,lwz,lwzx } - cmpli 0,L,rx,{ 0,1 }
+ case FusionFeature::FK_LoadCmp1:
+ // { ld,ldx } - cmpi 0,1,rx,{ 0,1,-1 }
+ // { ld,ldx } - cmpli 0,1,rx,{ 0,1 }
+ case FusionFeature::FK_LoadCmp2: {
+ const MachineOperand &BT = SecondMI.getOperand(0);
+ if (!BT.isReg() ||
+ (!Register::isVirtualRegister(BT.getReg()) && BT.getReg() != PPC::CR0))
+ return false;
+ if (SecondMI.getOpcode() == PPC::CMPDI &&
+ matchingImmOps(SecondMI, 2, -1, 16))
+ return true;
+ return matchingImmOps(SecondMI, 2, 0) || matchingImmOps(SecondMI, 2, 1);
+ }
+
+ // { lha,lhax,lwa,lwax } - cmpi 0,L,rx,{ 0,1,-1 }
+ case FusionFeature::FK_LoadCmp3: {
+ const MachineOperand &BT = SecondMI.getOperand(0);
+ if (!BT.isReg() ||
+ (!Register::isVirtualRegister(BT.getReg()) && BT.getReg() != PPC::CR0))
+ return false;
+ return matchingImmOps(SecondMI, 2, 0) || matchingImmOps(SecondMI, 2, 1) ||
+ matchingImmOps(SecondMI, 2, -1, 16);
+ }
+
+ // mtctr - { bcctr,bcctrl }
+ case FusionFeature::FK_ZeroMoveCTR:
+ // ( mtctr rx ) is alias of ( mtspr 9, rx )
+ return (FirstMI.getOpcode() != PPC::MTSPR &&
+ FirstMI.getOpcode() != PPC::MTSPR8) ||
+ matchingImmOps(FirstMI, 0, 9);
+
+ // mtlr - { bclr,bclrl }
+ case FusionFeature::FK_ZeroMoveLR:
+ // ( mtlr rx ) is alias of ( mtspr 8, rx )
+ return (FirstMI.getOpcode() != PPC::MTSPR &&
+ FirstMI.getOpcode() != PPC::MTSPR8) ||
+ matchingImmOps(FirstMI, 0, 8);
+
+ // addis rx,ra,si - addi rt,rx,SI, SI >= 0
+ case FusionFeature::FK_AddisAddi: {
+ const MachineOperand &RA = FirstMI.getOperand(1);
+ const MachineOperand &SI = SecondMI.getOperand(2);
+ if (!SI.isImm() || !RA.isReg())
+ return false;
+ if (RA.getReg() == PPC::ZERO || RA.getReg() == PPC::ZERO8)
+ return false;
+ return SignExtend64(SI.getImm(), 16) >= 0;
+ }
+
+ // addi rx,ra,si - addis rt,rx,SI, ra > 0, SI >= 2
+ case FusionFeature::FK_AddiAddis: {
+ const MachineOperand &RA = FirstMI.getOperand(1);
+ const MachineOperand &SI = FirstMI.getOperand(2);
+ if (!SI.isImm() || !RA.isReg())
+ return false;
+ if (RA.getReg() == PPC::ZERO || RA.getReg() == PPC::ZERO8)
+ return false;
+ int64_t ExtendedSI = SignExtend64(SI.getImm(), 16);
+ return ExtendedSI >= 2;
+ }
}
llvm_unreachable("All the cases should have been handled");