1dff0c46cSDimitry Andric //===-- PPCInstrInfo.cpp - PowerPC Instruction Information ----------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file contains the PowerPC implementation of the TargetInstrInfo class.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "PPCInstrInfo.h"
15139f7f9bSDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
1617a519f9SDimitry Andric #include "PPC.h"
17139f7f9bSDimitry Andric #include "PPCHazardRecognizers.h"
18f22ef01cSRoman Divacky #include "PPCInstrBuilder.h"
19f22ef01cSRoman Divacky #include "PPCMachineFunctionInfo.h"
20f22ef01cSRoman Divacky #include "PPCTargetMachine.h"
21139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
2291bc56edSDimitry Andric #include "llvm/ADT/Statistic.h"
232cab237bSDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
24e580952dSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
25284c1978SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
26f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstrBuilder.h"
27e580952dSDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
28f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
29e580952dSDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
3091bc56edSDimitry Andric #include "llvm/CodeGen/ScheduleDAG.h"
3191bc56edSDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
3239d628a0SDimitry Andric #include "llvm/CodeGen/StackMaps.h"
3317a519f9SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
34ff0cc061SDimitry Andric #include "llvm/MC/MCInst.h"
35f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
3691bc56edSDimitry Andric #include "llvm/Support/Debug.h"
37f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h"
386122f3e6SDimitry Andric #include "llvm/Support/TargetRegistry.h"
39f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
4017a519f9SDimitry Andric 
4191bc56edSDimitry Andric using namespace llvm;
4291bc56edSDimitry Andric 
4391bc56edSDimitry Andric #define DEBUG_TYPE "ppc-instr-info"
4491bc56edSDimitry Andric 
45284c1978SDimitry Andric #define GET_INSTRMAP_INFO
46f785676fSDimitry Andric #define GET_INSTRINFO_CTOR_DTOR
4717a519f9SDimitry Andric #include "PPCGenInstrInfo.inc"
48f22ef01cSRoman Divacky 
492cab237bSDimitry Andric STATISTIC(NumStoreSPILLVSRRCAsVec,
502cab237bSDimitry Andric           "Number of spillvsrrc spilled to stack as vec");
512cab237bSDimitry Andric STATISTIC(NumStoreSPILLVSRRCAsGpr,
522cab237bSDimitry Andric           "Number of spillvsrrc spilled to stack as gpr");
532cab237bSDimitry Andric STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
542cab237bSDimitry Andric STATISTIC(CmpIselsConverted,
552cab237bSDimitry Andric           "Number of ISELs that depend on comparison of constants converted");
562cab237bSDimitry Andric STATISTIC(MissedConvertibleImmediateInstrs,
572cab237bSDimitry Andric           "Number of compare-immediate instructions fed by constants");
584ba319b5SDimitry Andric STATISTIC(NumRcRotatesConvertedToRcAnd,
594ba319b5SDimitry Andric           "Number of record-form rotates converted to record-form andi");
602cab237bSDimitry Andric 
617ae0e2c9SDimitry Andric static cl::
627ae0e2c9SDimitry Andric opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
637ae0e2c9SDimitry Andric             cl::desc("Disable analysis for CTR loops"));
647ae0e2c9SDimitry Andric 
65284c1978SDimitry Andric static cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt",
66284c1978SDimitry Andric cl::desc("Disable compare instruction optimization"), cl::Hidden);
67284c1978SDimitry Andric 
6891bc56edSDimitry Andric static cl::opt<bool> VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy",
6991bc56edSDimitry Andric cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),
7091bc56edSDimitry Andric cl::Hidden);
7191bc56edSDimitry Andric 
72875ed548SDimitry Andric static cl::opt<bool>
73875ed548SDimitry Andric UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
74875ed548SDimitry Andric   cl::desc("Use the old (incorrect) instruction latency calculation"));
75875ed548SDimitry Andric 
764ba319b5SDimitry Andric // Index into the OpcodesForSpill array.
774ba319b5SDimitry Andric enum SpillOpcodeKey {
784ba319b5SDimitry Andric   SOK_Int4Spill,
794ba319b5SDimitry Andric   SOK_Int8Spill,
804ba319b5SDimitry Andric   SOK_Float8Spill,
814ba319b5SDimitry Andric   SOK_Float4Spill,
824ba319b5SDimitry Andric   SOK_CRSpill,
834ba319b5SDimitry Andric   SOK_CRBitSpill,
844ba319b5SDimitry Andric   SOK_VRVectorSpill,
854ba319b5SDimitry Andric   SOK_VSXVectorSpill,
864ba319b5SDimitry Andric   SOK_VectorFloat8Spill,
874ba319b5SDimitry Andric   SOK_VectorFloat4Spill,
884ba319b5SDimitry Andric   SOK_VRSaveSpill,
894ba319b5SDimitry Andric   SOK_QuadFloat8Spill,
904ba319b5SDimitry Andric   SOK_QuadFloat4Spill,
914ba319b5SDimitry Andric   SOK_QuadBitSpill,
924ba319b5SDimitry Andric   SOK_SpillToVSR,
934ba319b5SDimitry Andric   SOK_SPESpill,
944ba319b5SDimitry Andric   SOK_SPE4Spill,
954ba319b5SDimitry Andric   SOK_LastOpcodeSpill  // This must be last on the enum.
964ba319b5SDimitry Andric };
974ba319b5SDimitry Andric 
98f785676fSDimitry Andric // Pin the vtable to this file.
anchor()99f785676fSDimitry Andric void PPCInstrInfo::anchor() {}
100f785676fSDimitry Andric 
PPCInstrInfo(PPCSubtarget & STI)10191bc56edSDimitry Andric PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
1027a7e6055SDimitry Andric     : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP,
1037a7e6055SDimitry Andric                       /* CatchRetOpcode */ -1,
1047a7e6055SDimitry Andric                       STI.isPPC64() ? PPC::BLR8 : PPC::BLR),
105ff0cc061SDimitry Andric       Subtarget(STI), RI(STI.getTargetMachine()) {}
106f22ef01cSRoman Divacky 
1072754fe60SDimitry Andric /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
1082754fe60SDimitry Andric /// this target when scheduling the DAG.
10991bc56edSDimitry Andric ScheduleHazardRecognizer *
CreateTargetHazardRecognizer(const TargetSubtargetInfo * STI,const ScheduleDAG * DAG) const11091bc56edSDimitry Andric PPCInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
1112754fe60SDimitry Andric                                            const ScheduleDAG *DAG) const {
11291bc56edSDimitry Andric   unsigned Directive =
11391bc56edSDimitry Andric       static_cast<const PPCSubtarget *>(STI)->getDarwinDirective();
1143861d79fSDimitry Andric   if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 ||
1153861d79fSDimitry Andric       Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) {
11691bc56edSDimitry Andric     const InstrItineraryData *II =
11739d628a0SDimitry Andric         static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData();
11891bc56edSDimitry Andric     return new ScoreboardHazardRecognizer(II, DAG);
119dff0c46cSDimitry Andric   }
120dff0c46cSDimitry Andric 
12191bc56edSDimitry Andric   return TargetInstrInfo::CreateTargetHazardRecognizer(STI, DAG);
122dff0c46cSDimitry Andric }
123dff0c46cSDimitry Andric 
124dff0c46cSDimitry Andric /// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer
125dff0c46cSDimitry Andric /// to use for this target when scheduling the DAG.
126ff0cc061SDimitry Andric ScheduleHazardRecognizer *
CreateTargetPostRAHazardRecognizer(const InstrItineraryData * II,const ScheduleDAG * DAG) const127ff0cc061SDimitry Andric PPCInstrInfo::CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
128dff0c46cSDimitry Andric                                                  const ScheduleDAG *DAG) const {
12991bc56edSDimitry Andric   unsigned Directive =
130ff0cc061SDimitry Andric       DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
13191bc56edSDimitry Andric 
1323ca95b02SDimitry Andric   // FIXME: Leaving this as-is until we have POWER9 scheduling info
13391bc56edSDimitry Andric   if (Directive == PPC::DIR_PWR7 || Directive == PPC::DIR_PWR8)
13491bc56edSDimitry Andric     return new PPCDispatchGroupSBHazardRecognizer(II, DAG);
135dff0c46cSDimitry Andric 
136dff0c46cSDimitry Andric   // Most subtargets use a PPC970 recognizer.
1373861d79fSDimitry Andric   if (Directive != PPC::DIR_440 && Directive != PPC::DIR_A2 &&
1383861d79fSDimitry Andric       Directive != PPC::DIR_E500mc && Directive != PPC::DIR_E5500) {
13991bc56edSDimitry Andric     assert(DAG->TII && "No InstrInfo?");
140dff0c46cSDimitry Andric 
14191bc56edSDimitry Andric     return new PPCHazardRecognizer970(*DAG);
1422754fe60SDimitry Andric   }
1432754fe60SDimitry Andric 
14491bc56edSDimitry Andric   return new ScoreboardHazardRecognizer(II, DAG);
14591bc56edSDimitry Andric }
14691bc56edSDimitry Andric 
getInstrLatency(const InstrItineraryData * ItinData,const MachineInstr & MI,unsigned * PredCost) const147875ed548SDimitry Andric unsigned PPCInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1483ca95b02SDimitry Andric                                        const MachineInstr &MI,
149875ed548SDimitry Andric                                        unsigned *PredCost) const {
150875ed548SDimitry Andric   if (!ItinData || UseOldLatencyCalc)
151875ed548SDimitry Andric     return PPCGenInstrInfo::getInstrLatency(ItinData, MI, PredCost);
152875ed548SDimitry Andric 
153875ed548SDimitry Andric   // The default implementation of getInstrLatency calls getStageLatency, but
154875ed548SDimitry Andric   // getStageLatency does not do the right thing for us. While we have
155875ed548SDimitry Andric   // itinerary, most cores are fully pipelined, and so the itineraries only
156875ed548SDimitry Andric   // express the first part of the pipeline, not every stage. Instead, we need
157875ed548SDimitry Andric   // to use the listed output operand cycle number (using operand 0 here, which
158875ed548SDimitry Andric   // is an output).
159875ed548SDimitry Andric 
160875ed548SDimitry Andric   unsigned Latency = 1;
1613ca95b02SDimitry Andric   unsigned DefClass = MI.getDesc().getSchedClass();
1623ca95b02SDimitry Andric   for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
1633ca95b02SDimitry Andric     const MachineOperand &MO = MI.getOperand(i);
164875ed548SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
165875ed548SDimitry Andric       continue;
166875ed548SDimitry Andric 
167875ed548SDimitry Andric     int Cycle = ItinData->getOperandCycle(DefClass, i);
168875ed548SDimitry Andric     if (Cycle < 0)
169875ed548SDimitry Andric       continue;
170875ed548SDimitry Andric 
171875ed548SDimitry Andric     Latency = std::max(Latency, (unsigned) Cycle);
172875ed548SDimitry Andric   }
173875ed548SDimitry Andric 
174875ed548SDimitry Andric   return Latency;
175875ed548SDimitry Andric }
17691bc56edSDimitry Andric 
getOperandLatency(const InstrItineraryData * ItinData,const MachineInstr & DefMI,unsigned DefIdx,const MachineInstr & UseMI,unsigned UseIdx) const17791bc56edSDimitry Andric int PPCInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
1783ca95b02SDimitry Andric                                     const MachineInstr &DefMI, unsigned DefIdx,
1793ca95b02SDimitry Andric                                     const MachineInstr &UseMI,
18091bc56edSDimitry Andric                                     unsigned UseIdx) const {
18191bc56edSDimitry Andric   int Latency = PPCGenInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
18291bc56edSDimitry Andric                                                    UseMI, UseIdx);
18391bc56edSDimitry Andric 
1843ca95b02SDimitry Andric   if (!DefMI.getParent())
1857d523365SDimitry Andric     return Latency;
1867d523365SDimitry Andric 
1873ca95b02SDimitry Andric   const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
18891bc56edSDimitry Andric   unsigned Reg = DefMO.getReg();
18991bc56edSDimitry Andric 
19091bc56edSDimitry Andric   bool IsRegCR;
191ff0cc061SDimitry Andric   if (TargetRegisterInfo::isVirtualRegister(Reg)) {
19291bc56edSDimitry Andric     const MachineRegisterInfo *MRI =
1933ca95b02SDimitry Andric         &DefMI.getParent()->getParent()->getRegInfo();
19491bc56edSDimitry Andric     IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
19591bc56edSDimitry Andric               MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
19691bc56edSDimitry Andric   } else {
19791bc56edSDimitry Andric     IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
19891bc56edSDimitry Andric               PPC::CRBITRCRegClass.contains(Reg);
19991bc56edSDimitry Andric   }
20091bc56edSDimitry Andric 
2013ca95b02SDimitry Andric   if (UseMI.isBranch() && IsRegCR) {
20291bc56edSDimitry Andric     if (Latency < 0)
20391bc56edSDimitry Andric       Latency = getInstrLatency(ItinData, DefMI);
20491bc56edSDimitry Andric 
20591bc56edSDimitry Andric     // On some cores, there is an additional delay between writing to a condition
20691bc56edSDimitry Andric     // register, and using it from a branch.
20791bc56edSDimitry Andric     unsigned Directive = Subtarget.getDarwinDirective();
20891bc56edSDimitry Andric     switch (Directive) {
20991bc56edSDimitry Andric     default: break;
21091bc56edSDimitry Andric     case PPC::DIR_7400:
21191bc56edSDimitry Andric     case PPC::DIR_750:
21291bc56edSDimitry Andric     case PPC::DIR_970:
21391bc56edSDimitry Andric     case PPC::DIR_E5500:
21491bc56edSDimitry Andric     case PPC::DIR_PWR4:
21591bc56edSDimitry Andric     case PPC::DIR_PWR5:
21691bc56edSDimitry Andric     case PPC::DIR_PWR5X:
21791bc56edSDimitry Andric     case PPC::DIR_PWR6:
21891bc56edSDimitry Andric     case PPC::DIR_PWR6X:
21991bc56edSDimitry Andric     case PPC::DIR_PWR7:
22091bc56edSDimitry Andric     case PPC::DIR_PWR8:
2213ca95b02SDimitry Andric     // FIXME: Is this needed for POWER9?
22291bc56edSDimitry Andric       Latency += 2;
22391bc56edSDimitry Andric       break;
22491bc56edSDimitry Andric     }
22591bc56edSDimitry Andric   }
22691bc56edSDimitry Andric 
22791bc56edSDimitry Andric   return Latency;
228dff0c46cSDimitry Andric }
2297ae0e2c9SDimitry Andric 
2307d523365SDimitry Andric // This function does not list all associative and commutative operations, but
2317d523365SDimitry Andric // only those worth feeding through the machine combiner in an attempt to
2327d523365SDimitry Andric // reduce the critical path. Mostly, this means floating-point operations,
2337d523365SDimitry Andric // because they have high latencies (compared to other operations, such and
2347d523365SDimitry Andric // and/or, which are also associative and commutative, but have low latencies).
isAssociativeAndCommutative(const MachineInstr & Inst) const2357d523365SDimitry Andric bool PPCInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const {
2367d523365SDimitry Andric   switch (Inst.getOpcode()) {
2377d523365SDimitry Andric   // FP Add:
2387d523365SDimitry Andric   case PPC::FADD:
2397d523365SDimitry Andric   case PPC::FADDS:
2407d523365SDimitry Andric   // FP Multiply:
2417d523365SDimitry Andric   case PPC::FMUL:
2427d523365SDimitry Andric   case PPC::FMULS:
2437d523365SDimitry Andric   // Altivec Add:
2447d523365SDimitry Andric   case PPC::VADDFP:
2457d523365SDimitry Andric   // VSX Add:
2467d523365SDimitry Andric   case PPC::XSADDDP:
2477d523365SDimitry Andric   case PPC::XVADDDP:
2487d523365SDimitry Andric   case PPC::XVADDSP:
2497d523365SDimitry Andric   case PPC::XSADDSP:
2507d523365SDimitry Andric   // VSX Multiply:
2517d523365SDimitry Andric   case PPC::XSMULDP:
2527d523365SDimitry Andric   case PPC::XVMULDP:
2537d523365SDimitry Andric   case PPC::XVMULSP:
2547d523365SDimitry Andric   case PPC::XSMULSP:
2557d523365SDimitry Andric   // QPX Add:
2567d523365SDimitry Andric   case PPC::QVFADD:
2577d523365SDimitry Andric   case PPC::QVFADDS:
2587d523365SDimitry Andric   case PPC::QVFADDSs:
2597d523365SDimitry Andric   // QPX Multiply:
2607d523365SDimitry Andric   case PPC::QVFMUL:
2617d523365SDimitry Andric   case PPC::QVFMULS:
2627d523365SDimitry Andric   case PPC::QVFMULSs:
2637d523365SDimitry Andric     return true;
2647d523365SDimitry Andric   default:
2657d523365SDimitry Andric     return false;
2667d523365SDimitry Andric   }
2677d523365SDimitry Andric }
2687d523365SDimitry Andric 
getMachineCombinerPatterns(MachineInstr & Root,SmallVectorImpl<MachineCombinerPattern> & Patterns) const2697d523365SDimitry Andric bool PPCInstrInfo::getMachineCombinerPatterns(
2707d523365SDimitry Andric     MachineInstr &Root,
2717d523365SDimitry Andric     SmallVectorImpl<MachineCombinerPattern> &Patterns) const {
2727d523365SDimitry Andric   // Using the machine combiner in this way is potentially expensive, so
2737d523365SDimitry Andric   // restrict to when aggressive optimizations are desired.
2747d523365SDimitry Andric   if (Subtarget.getTargetMachine().getOptLevel() != CodeGenOpt::Aggressive)
2757d523365SDimitry Andric     return false;
2767d523365SDimitry Andric 
2777d523365SDimitry Andric   // FP reassociation is only legal when we don't need strict IEEE semantics.
2787d523365SDimitry Andric   if (!Root.getParent()->getParent()->getTarget().Options.UnsafeFPMath)
2797d523365SDimitry Andric     return false;
2807d523365SDimitry Andric 
2817d523365SDimitry Andric   return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns);
2827d523365SDimitry Andric }
2837d523365SDimitry Andric 
2847ae0e2c9SDimitry Andric // Detect 32 -> 64-bit extensions where we may reuse the low sub-register.
isCoalescableExtInstr(const MachineInstr & MI,unsigned & SrcReg,unsigned & DstReg,unsigned & SubIdx) const2857ae0e2c9SDimitry Andric bool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
2867ae0e2c9SDimitry Andric                                          unsigned &SrcReg, unsigned &DstReg,
2877ae0e2c9SDimitry Andric                                          unsigned &SubIdx) const {
2887ae0e2c9SDimitry Andric   switch (MI.getOpcode()) {
2897ae0e2c9SDimitry Andric   default: return false;
2907ae0e2c9SDimitry Andric   case PPC::EXTSW:
2912cab237bSDimitry Andric   case PPC::EXTSW_32:
2927ae0e2c9SDimitry Andric   case PPC::EXTSW_32_64:
2937ae0e2c9SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
2947ae0e2c9SDimitry Andric     DstReg = MI.getOperand(0).getReg();
2957ae0e2c9SDimitry Andric     SubIdx = PPC::sub_32;
2967ae0e2c9SDimitry Andric     return true;
2977ae0e2c9SDimitry Andric   }
2987ae0e2c9SDimitry Andric }
2997ae0e2c9SDimitry Andric 
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const3003ca95b02SDimitry Andric unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
301f22ef01cSRoman Divacky                                            int &FrameIndex) const {
3024ba319b5SDimitry Andric   unsigned Opcode = MI.getOpcode();
3034ba319b5SDimitry Andric   const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray();
3044ba319b5SDimitry Andric   const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill;
3054ba319b5SDimitry Andric 
3064ba319b5SDimitry Andric   if (End != std::find(OpcodesForSpill, End, Opcode)) {
307139f7f9bSDimitry Andric     // Check for the operands added by addFrameReference (the immediate is the
308139f7f9bSDimitry Andric     // offset which defaults to 0).
3093ca95b02SDimitry Andric     if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
3103ca95b02SDimitry Andric         MI.getOperand(2).isFI()) {
3113ca95b02SDimitry Andric       FrameIndex = MI.getOperand(2).getIndex();
3123ca95b02SDimitry Andric       return MI.getOperand(0).getReg();
313f22ef01cSRoman Divacky     }
314f22ef01cSRoman Divacky   }
315f22ef01cSRoman Divacky   return 0;
316f22ef01cSRoman Divacky }
317f22ef01cSRoman Divacky 
318edd7eaddSDimitry Andric // For opcodes with the ReMaterializable flag set, this function is called to
319edd7eaddSDimitry Andric // verify the instruction is really rematable.
isReallyTriviallyReMaterializable(const MachineInstr & MI,AliasAnalysis * AA) const320edd7eaddSDimitry Andric bool PPCInstrInfo::isReallyTriviallyReMaterializable(const MachineInstr &MI,
321edd7eaddSDimitry Andric                                                      AliasAnalysis *AA) const {
322edd7eaddSDimitry Andric   switch (MI.getOpcode()) {
323edd7eaddSDimitry Andric   default:
324edd7eaddSDimitry Andric     // This function should only be called for opcodes with the ReMaterializable
325edd7eaddSDimitry Andric     // flag set.
326edd7eaddSDimitry Andric     llvm_unreachable("Unknown rematerializable operation!");
327edd7eaddSDimitry Andric     break;
328edd7eaddSDimitry Andric   case PPC::LI:
329edd7eaddSDimitry Andric   case PPC::LI8:
330edd7eaddSDimitry Andric   case PPC::LIS:
331edd7eaddSDimitry Andric   case PPC::LIS8:
332edd7eaddSDimitry Andric   case PPC::QVGPCI:
333edd7eaddSDimitry Andric   case PPC::ADDIStocHA:
334edd7eaddSDimitry Andric   case PPC::ADDItocL:
335edd7eaddSDimitry Andric   case PPC::LOAD_STACK_GUARD:
336edd7eaddSDimitry Andric     return true;
337edd7eaddSDimitry Andric   }
338edd7eaddSDimitry Andric   return false;
339edd7eaddSDimitry Andric }
340edd7eaddSDimitry Andric 
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const3413ca95b02SDimitry Andric unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
342f22ef01cSRoman Divacky                                           int &FrameIndex) const {
3434ba319b5SDimitry Andric   unsigned Opcode = MI.getOpcode();
3444ba319b5SDimitry Andric   const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray();
3454ba319b5SDimitry Andric   const unsigned *End = OpcodesForSpill + SOK_LastOpcodeSpill;
3464ba319b5SDimitry Andric 
3474ba319b5SDimitry Andric   if (End != std::find(OpcodesForSpill, End, Opcode)) {
3483ca95b02SDimitry Andric     if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
3493ca95b02SDimitry Andric         MI.getOperand(2).isFI()) {
3503ca95b02SDimitry Andric       FrameIndex = MI.getOperand(2).getIndex();
3513ca95b02SDimitry Andric       return MI.getOperand(0).getReg();
352f22ef01cSRoman Divacky     }
353f22ef01cSRoman Divacky   }
354f22ef01cSRoman Divacky   return 0;
355f22ef01cSRoman Divacky }
356f22ef01cSRoman Divacky 
commuteInstructionImpl(MachineInstr & MI,bool NewMI,unsigned OpIdx1,unsigned OpIdx2) const3573ca95b02SDimitry Andric MachineInstr *PPCInstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
3587d523365SDimitry Andric                                                    unsigned OpIdx1,
3597d523365SDimitry Andric                                                    unsigned OpIdx2) const {
3603ca95b02SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
361f22ef01cSRoman Divacky 
362f22ef01cSRoman Divacky   // Normal instructions can be commuted the obvious way.
3633ca95b02SDimitry Andric   if (MI.getOpcode() != PPC::RLWIMI && MI.getOpcode() != PPC::RLWIMIo)
3647d523365SDimitry Andric     return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
36539d628a0SDimitry Andric   // Note that RLWIMI can be commuted as a 32-bit instruction, but not as a
36639d628a0SDimitry Andric   // 64-bit instruction (so we don't handle PPC::RLWIMI8 here), because
36739d628a0SDimitry Andric   // changing the relative order of the mask operands might change what happens
36839d628a0SDimitry Andric   // to the high-bits of the mask (and, thus, the result).
369f22ef01cSRoman Divacky 
370f22ef01cSRoman Divacky   // Cannot commute if it has a non-zero rotate count.
3713ca95b02SDimitry Andric   if (MI.getOperand(3).getImm() != 0)
37291bc56edSDimitry Andric     return nullptr;
373f22ef01cSRoman Divacky 
374f22ef01cSRoman Divacky   // If we have a zero rotate count, we have:
375f22ef01cSRoman Divacky   //   M = mask(MB,ME)
376f22ef01cSRoman Divacky   //   Op0 = (Op1 & ~M) | (Op2 & M)
377f22ef01cSRoman Divacky   // Change this to:
378f22ef01cSRoman Divacky   //   M = mask((ME+1)&31, (MB-1)&31)
379f22ef01cSRoman Divacky   //   Op0 = (Op2 & ~M) | (Op1 & M)
380f22ef01cSRoman Divacky 
381f22ef01cSRoman Divacky   // Swap op1/op2
3827d523365SDimitry Andric   assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
3837d523365SDimitry Andric          "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMIo.");
3843ca95b02SDimitry Andric   unsigned Reg0 = MI.getOperand(0).getReg();
3853ca95b02SDimitry Andric   unsigned Reg1 = MI.getOperand(1).getReg();
3863ca95b02SDimitry Andric   unsigned Reg2 = MI.getOperand(2).getReg();
3873ca95b02SDimitry Andric   unsigned SubReg1 = MI.getOperand(1).getSubReg();
3883ca95b02SDimitry Andric   unsigned SubReg2 = MI.getOperand(2).getSubReg();
3893ca95b02SDimitry Andric   bool Reg1IsKill = MI.getOperand(1).isKill();
3903ca95b02SDimitry Andric   bool Reg2IsKill = MI.getOperand(2).isKill();
391f22ef01cSRoman Divacky   bool ChangeReg0 = false;
392f22ef01cSRoman Divacky   // If machine instrs are no longer in two-address forms, update
393f22ef01cSRoman Divacky   // destination register as well.
394f22ef01cSRoman Divacky   if (Reg0 == Reg1) {
395f22ef01cSRoman Divacky     // Must be two address instruction!
3963ca95b02SDimitry Andric     assert(MI.getDesc().getOperandConstraint(0, MCOI::TIED_TO) &&
397f22ef01cSRoman Divacky            "Expecting a two-address instruction!");
3983ca95b02SDimitry Andric     assert(MI.getOperand(0).getSubReg() == SubReg1 && "Tied subreg mismatch");
399f22ef01cSRoman Divacky     Reg2IsKill = false;
400f22ef01cSRoman Divacky     ChangeReg0 = true;
401f22ef01cSRoman Divacky   }
402f22ef01cSRoman Divacky 
403f22ef01cSRoman Divacky   // Masks.
4043ca95b02SDimitry Andric   unsigned MB = MI.getOperand(4).getImm();
4053ca95b02SDimitry Andric   unsigned ME = MI.getOperand(5).getImm();
406f22ef01cSRoman Divacky 
4079a4b3118SDimitry Andric   // We can't commute a trivial mask (there is no way to represent an all-zero
4089a4b3118SDimitry Andric   // mask).
4099a4b3118SDimitry Andric   if (MB == 0 && ME == 31)
4109a4b3118SDimitry Andric     return nullptr;
4119a4b3118SDimitry Andric 
412f22ef01cSRoman Divacky   if (NewMI) {
413f22ef01cSRoman Divacky     // Create a new instruction.
4143ca95b02SDimitry Andric     unsigned Reg0 = ChangeReg0 ? Reg2 : MI.getOperand(0).getReg();
4153ca95b02SDimitry Andric     bool Reg0IsDead = MI.getOperand(0).isDead();
4163ca95b02SDimitry Andric     return BuildMI(MF, MI.getDebugLoc(), MI.getDesc())
417f22ef01cSRoman Divacky         .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead))
418f22ef01cSRoman Divacky         .addReg(Reg2, getKillRegState(Reg2IsKill))
419f22ef01cSRoman Divacky         .addReg(Reg1, getKillRegState(Reg1IsKill))
420f22ef01cSRoman Divacky         .addImm((ME + 1) & 31)
421f22ef01cSRoman Divacky         .addImm((MB - 1) & 31);
422f22ef01cSRoman Divacky   }
423f22ef01cSRoman Divacky 
42491bc56edSDimitry Andric   if (ChangeReg0) {
4253ca95b02SDimitry Andric     MI.getOperand(0).setReg(Reg2);
4263ca95b02SDimitry Andric     MI.getOperand(0).setSubReg(SubReg2);
42791bc56edSDimitry Andric   }
4283ca95b02SDimitry Andric   MI.getOperand(2).setReg(Reg1);
4293ca95b02SDimitry Andric   MI.getOperand(1).setReg(Reg2);
4303ca95b02SDimitry Andric   MI.getOperand(2).setSubReg(SubReg1);
4313ca95b02SDimitry Andric   MI.getOperand(1).setSubReg(SubReg2);
4323ca95b02SDimitry Andric   MI.getOperand(2).setIsKill(Reg1IsKill);
4333ca95b02SDimitry Andric   MI.getOperand(1).setIsKill(Reg2IsKill);
434f22ef01cSRoman Divacky 
435f22ef01cSRoman Divacky   // Swap the mask around.
4363ca95b02SDimitry Andric   MI.getOperand(4).setImm((ME + 1) & 31);
4373ca95b02SDimitry Andric   MI.getOperand(5).setImm((MB - 1) & 31);
4383ca95b02SDimitry Andric   return &MI;
439f22ef01cSRoman Divacky }
440f22ef01cSRoman Divacky 
findCommutedOpIndices(MachineInstr & MI,unsigned & SrcOpIdx1,unsigned & SrcOpIdx2) const4413ca95b02SDimitry Andric bool PPCInstrInfo::findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
44291bc56edSDimitry Andric                                          unsigned &SrcOpIdx2) const {
44391bc56edSDimitry Andric   // For VSX A-Type FMA instructions, it is the first two operands that can be
44491bc56edSDimitry Andric   // commuted, however, because the non-encoded tied input operand is listed
44591bc56edSDimitry Andric   // first, the operands to swap are actually the second and third.
44691bc56edSDimitry Andric 
4473ca95b02SDimitry Andric   int AltOpc = PPC::getAltVSXFMAOpcode(MI.getOpcode());
44891bc56edSDimitry Andric   if (AltOpc == -1)
44991bc56edSDimitry Andric     return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
45091bc56edSDimitry Andric 
4517d523365SDimitry Andric   // The commutable operand indices are 2 and 3. Return them in SrcOpIdx1
4527d523365SDimitry Andric   // and SrcOpIdx2.
4537d523365SDimitry Andric   return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
454f22ef01cSRoman Divacky }
455f22ef01cSRoman Divacky 
insertNoop(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI) const45691bc56edSDimitry Andric void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
45791bc56edSDimitry Andric                               MachineBasicBlock::iterator MI) const {
45891bc56edSDimitry Andric   // This function is used for scheduling, and the nop wanted here is the type
45991bc56edSDimitry Andric   // that terminates dispatch groups on the POWER cores.
46091bc56edSDimitry Andric   unsigned Directive = Subtarget.getDarwinDirective();
46191bc56edSDimitry Andric   unsigned Opcode;
46291bc56edSDimitry Andric   switch (Directive) {
46391bc56edSDimitry Andric   default:            Opcode = PPC::NOP; break;
46491bc56edSDimitry Andric   case PPC::DIR_PWR6: Opcode = PPC::NOP_GT_PWR6; break;
46591bc56edSDimitry Andric   case PPC::DIR_PWR7: Opcode = PPC::NOP_GT_PWR7; break;
46691bc56edSDimitry Andric   case PPC::DIR_PWR8: Opcode = PPC::NOP_GT_PWR7; break; /* FIXME: Update when P8 InstrScheduling model is ready */
4673ca95b02SDimitry Andric   // FIXME: Update when POWER9 scheduling model is ready.
4683ca95b02SDimitry Andric   case PPC::DIR_PWR9: Opcode = PPC::NOP_GT_PWR7; break;
46991bc56edSDimitry Andric   }
47091bc56edSDimitry Andric 
47191bc56edSDimitry Andric   DebugLoc DL;
47291bc56edSDimitry Andric   BuildMI(MBB, MI, DL, get(Opcode));
47391bc56edSDimitry Andric }
474f22ef01cSRoman Divacky 
47551690af2SDimitry Andric /// Return the noop instruction to use for a noop.
getNoop(MCInst & NopInst) const47651690af2SDimitry Andric void PPCInstrInfo::getNoop(MCInst &NopInst) const {
47739d628a0SDimitry Andric   NopInst.setOpcode(PPC::NOP);
47839d628a0SDimitry Andric }
47939d628a0SDimitry Andric 
480f22ef01cSRoman Divacky // Branch analysis.
4817ae0e2c9SDimitry Andric // Note: If the condition register is set to CTR or CTR8 then this is a
4827ae0e2c9SDimitry Andric // BDNZ (imm == 1) or BDZ (imm == 0) branch.
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const4833ca95b02SDimitry Andric bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
4843ca95b02SDimitry Andric                                  MachineBasicBlock *&TBB,
485f22ef01cSRoman Divacky                                  MachineBasicBlock *&FBB,
486f22ef01cSRoman Divacky                                  SmallVectorImpl<MachineOperand> &Cond,
487f22ef01cSRoman Divacky                                  bool AllowModify) const {
48891bc56edSDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
4897ae0e2c9SDimitry Andric 
490f22ef01cSRoman Divacky   // If the block has no terminators, it just falls into the block after it.
4913dac3a9bSDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
4923dac3a9bSDimitry Andric   if (I == MBB.end())
493f22ef01cSRoman Divacky     return false;
4943dac3a9bSDimitry Andric 
4953ca95b02SDimitry Andric   if (!isUnpredicatedTerminator(*I))
496f22ef01cSRoman Divacky     return false;
497f22ef01cSRoman Divacky 
4982cab237bSDimitry Andric   if (AllowModify) {
4992cab237bSDimitry Andric     // If the BB ends with an unconditional branch to the fallthrough BB,
5002cab237bSDimitry Andric     // we eliminate the branch instruction.
5012cab237bSDimitry Andric     if (I->getOpcode() == PPC::B &&
5022cab237bSDimitry Andric         MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
5032cab237bSDimitry Andric       I->eraseFromParent();
5042cab237bSDimitry Andric 
5052cab237bSDimitry Andric       // We update iterator after deleting the last branch.
5062cab237bSDimitry Andric       I = MBB.getLastNonDebugInstr();
5072cab237bSDimitry Andric       if (I == MBB.end() || !isUnpredicatedTerminator(*I))
5082cab237bSDimitry Andric         return false;
5092cab237bSDimitry Andric     }
5102cab237bSDimitry Andric   }
5112cab237bSDimitry Andric 
512f22ef01cSRoman Divacky   // Get the last instruction in the block.
513d88c1a5aSDimitry Andric   MachineInstr &LastInst = *I;
514f22ef01cSRoman Divacky 
515f22ef01cSRoman Divacky   // If there is only one terminator instruction, process it.
5163ca95b02SDimitry Andric   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
517d88c1a5aSDimitry Andric     if (LastInst.getOpcode() == PPC::B) {
518d88c1a5aSDimitry Andric       if (!LastInst.getOperand(0).isMBB())
519f22ef01cSRoman Divacky         return true;
520d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
521f22ef01cSRoman Divacky       return false;
522d88c1a5aSDimitry Andric     } else if (LastInst.getOpcode() == PPC::BCC) {
523d88c1a5aSDimitry Andric       if (!LastInst.getOperand(2).isMBB())
524f22ef01cSRoman Divacky         return true;
525f22ef01cSRoman Divacky       // Block ends with fall-through condbranch.
526d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(2).getMBB();
527d88c1a5aSDimitry Andric       Cond.push_back(LastInst.getOperand(0));
528d88c1a5aSDimitry Andric       Cond.push_back(LastInst.getOperand(1));
529f22ef01cSRoman Divacky       return false;
530d88c1a5aSDimitry Andric     } else if (LastInst.getOpcode() == PPC::BC) {
531d88c1a5aSDimitry Andric       if (!LastInst.getOperand(1).isMBB())
53291bc56edSDimitry Andric         return true;
53391bc56edSDimitry Andric       // Block ends with fall-through condbranch.
534d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(1).getMBB();
53591bc56edSDimitry Andric       Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
536d88c1a5aSDimitry Andric       Cond.push_back(LastInst.getOperand(0));
53791bc56edSDimitry Andric       return false;
538d88c1a5aSDimitry Andric     } else if (LastInst.getOpcode() == PPC::BCn) {
539d88c1a5aSDimitry Andric       if (!LastInst.getOperand(1).isMBB())
54091bc56edSDimitry Andric         return true;
54191bc56edSDimitry Andric       // Block ends with fall-through condbranch.
542d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(1).getMBB();
54391bc56edSDimitry Andric       Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
544d88c1a5aSDimitry Andric       Cond.push_back(LastInst.getOperand(0));
54591bc56edSDimitry Andric       return false;
546d88c1a5aSDimitry Andric     } else if (LastInst.getOpcode() == PPC::BDNZ8 ||
547d88c1a5aSDimitry Andric                LastInst.getOpcode() == PPC::BDNZ) {
548d88c1a5aSDimitry Andric       if (!LastInst.getOperand(0).isMBB())
5497ae0e2c9SDimitry Andric         return true;
5507ae0e2c9SDimitry Andric       if (DisableCTRLoopAnal)
5517ae0e2c9SDimitry Andric         return true;
552d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
5537ae0e2c9SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(1));
5547ae0e2c9SDimitry Andric       Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
5557ae0e2c9SDimitry Andric                                                true));
5567ae0e2c9SDimitry Andric       return false;
557d88c1a5aSDimitry Andric     } else if (LastInst.getOpcode() == PPC::BDZ8 ||
558d88c1a5aSDimitry Andric                LastInst.getOpcode() == PPC::BDZ) {
559d88c1a5aSDimitry Andric       if (!LastInst.getOperand(0).isMBB())
5607ae0e2c9SDimitry Andric         return true;
5617ae0e2c9SDimitry Andric       if (DisableCTRLoopAnal)
5627ae0e2c9SDimitry Andric         return true;
563d88c1a5aSDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
5647ae0e2c9SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(0));
5657ae0e2c9SDimitry Andric       Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
5667ae0e2c9SDimitry Andric                                                true));
5677ae0e2c9SDimitry Andric       return false;
568f22ef01cSRoman Divacky     }
5697ae0e2c9SDimitry Andric 
570f22ef01cSRoman Divacky     // Otherwise, don't know what this is.
571f22ef01cSRoman Divacky     return true;
572f22ef01cSRoman Divacky   }
573f22ef01cSRoman Divacky 
574f22ef01cSRoman Divacky   // Get the instruction before it if it's a terminator.
575d88c1a5aSDimitry Andric   MachineInstr &SecondLastInst = *I;
576f22ef01cSRoman Divacky 
577f22ef01cSRoman Divacky   // If there are three terminators, we don't know what sort of block this is.
578d88c1a5aSDimitry Andric   if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
579f22ef01cSRoman Divacky     return true;
580f22ef01cSRoman Divacky 
581f22ef01cSRoman Divacky   // If the block ends with PPC::B and PPC:BCC, handle it.
582d88c1a5aSDimitry Andric   if (SecondLastInst.getOpcode() == PPC::BCC &&
583d88c1a5aSDimitry Andric       LastInst.getOpcode() == PPC::B) {
584d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(2).isMBB() ||
585d88c1a5aSDimitry Andric         !LastInst.getOperand(0).isMBB())
586f22ef01cSRoman Divacky       return true;
587d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(2).getMBB();
588d88c1a5aSDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
589d88c1a5aSDimitry Andric     Cond.push_back(SecondLastInst.getOperand(1));
590d88c1a5aSDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
591f22ef01cSRoman Divacky     return false;
592d88c1a5aSDimitry Andric   } else if (SecondLastInst.getOpcode() == PPC::BC &&
593d88c1a5aSDimitry Andric              LastInst.getOpcode() == PPC::B) {
594d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(1).isMBB() ||
595d88c1a5aSDimitry Andric         !LastInst.getOperand(0).isMBB())
59691bc56edSDimitry Andric       return true;
597d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(1).getMBB();
59891bc56edSDimitry Andric     Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
599d88c1a5aSDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
600d88c1a5aSDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
60191bc56edSDimitry Andric     return false;
602d88c1a5aSDimitry Andric   } else if (SecondLastInst.getOpcode() == PPC::BCn &&
603d88c1a5aSDimitry Andric              LastInst.getOpcode() == PPC::B) {
604d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(1).isMBB() ||
605d88c1a5aSDimitry Andric         !LastInst.getOperand(0).isMBB())
60691bc56edSDimitry Andric       return true;
607d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(1).getMBB();
60891bc56edSDimitry Andric     Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
609d88c1a5aSDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
610d88c1a5aSDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
61191bc56edSDimitry Andric     return false;
612d88c1a5aSDimitry Andric   } else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||
613d88c1a5aSDimitry Andric               SecondLastInst.getOpcode() == PPC::BDNZ) &&
614d88c1a5aSDimitry Andric              LastInst.getOpcode() == PPC::B) {
615d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB() ||
616d88c1a5aSDimitry Andric         !LastInst.getOperand(0).isMBB())
6177ae0e2c9SDimitry Andric       return true;
6187ae0e2c9SDimitry Andric     if (DisableCTRLoopAnal)
6197ae0e2c9SDimitry Andric       return true;
620d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
6217ae0e2c9SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(1));
6227ae0e2c9SDimitry Andric     Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
6237ae0e2c9SDimitry Andric                                              true));
624d88c1a5aSDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
6257ae0e2c9SDimitry Andric     return false;
626d88c1a5aSDimitry Andric   } else if ((SecondLastInst.getOpcode() == PPC::BDZ8 ||
627d88c1a5aSDimitry Andric               SecondLastInst.getOpcode() == PPC::BDZ) &&
628d88c1a5aSDimitry Andric              LastInst.getOpcode() == PPC::B) {
629d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB() ||
630d88c1a5aSDimitry Andric         !LastInst.getOperand(0).isMBB())
6317ae0e2c9SDimitry Andric       return true;
6327ae0e2c9SDimitry Andric     if (DisableCTRLoopAnal)
6337ae0e2c9SDimitry Andric       return true;
634d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
6357ae0e2c9SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(0));
6367ae0e2c9SDimitry Andric     Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
6377ae0e2c9SDimitry Andric                                              true));
638d88c1a5aSDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
6397ae0e2c9SDimitry Andric     return false;
640f22ef01cSRoman Divacky   }
641f22ef01cSRoman Divacky 
642f22ef01cSRoman Divacky   // If the block ends with two PPC:Bs, handle it.  The second one is not
643f22ef01cSRoman Divacky   // executed, so remove it.
644d88c1a5aSDimitry Andric   if (SecondLastInst.getOpcode() == PPC::B && LastInst.getOpcode() == PPC::B) {
645d88c1a5aSDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB())
646f22ef01cSRoman Divacky       return true;
647d88c1a5aSDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
648f22ef01cSRoman Divacky     I = LastInst;
649f22ef01cSRoman Divacky     if (AllowModify)
650f22ef01cSRoman Divacky       I->eraseFromParent();
651f22ef01cSRoman Divacky     return false;
652f22ef01cSRoman Divacky   }
653f22ef01cSRoman Divacky 
654f22ef01cSRoman Divacky   // Otherwise, can't handle this.
655f22ef01cSRoman Divacky   return true;
656f22ef01cSRoman Divacky }
657f22ef01cSRoman Divacky 
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const658d88c1a5aSDimitry Andric unsigned PPCInstrInfo::removeBranch(MachineBasicBlock &MBB,
659d88c1a5aSDimitry Andric                                     int *BytesRemoved) const {
660d88c1a5aSDimitry Andric   assert(!BytesRemoved && "code size not handled");
661d88c1a5aSDimitry Andric 
6623dac3a9bSDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
6633dac3a9bSDimitry Andric   if (I == MBB.end())
664f22ef01cSRoman Divacky     return 0;
6653dac3a9bSDimitry Andric 
6667ae0e2c9SDimitry Andric   if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&
66791bc56edSDimitry Andric       I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
6687ae0e2c9SDimitry Andric       I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
6697ae0e2c9SDimitry Andric       I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
670f22ef01cSRoman Divacky     return 0;
671f22ef01cSRoman Divacky 
672f22ef01cSRoman Divacky   // Remove the branch.
673f22ef01cSRoman Divacky   I->eraseFromParent();
674f22ef01cSRoman Divacky 
675f22ef01cSRoman Divacky   I = MBB.end();
676f22ef01cSRoman Divacky 
677f22ef01cSRoman Divacky   if (I == MBB.begin()) return 1;
678f22ef01cSRoman Divacky   --I;
6797ae0e2c9SDimitry Andric   if (I->getOpcode() != PPC::BCC &&
68091bc56edSDimitry Andric       I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
6817ae0e2c9SDimitry Andric       I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
6827ae0e2c9SDimitry Andric       I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
683f22ef01cSRoman Divacky     return 1;
684f22ef01cSRoman Divacky 
685f22ef01cSRoman Divacky   // Remove the branch.
686f22ef01cSRoman Divacky   I->eraseFromParent();
687f22ef01cSRoman Divacky   return 2;
688f22ef01cSRoman Divacky }
689f22ef01cSRoman Divacky 
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const690d88c1a5aSDimitry Andric unsigned PPCInstrInfo::insertBranch(MachineBasicBlock &MBB,
6913ca95b02SDimitry Andric                                     MachineBasicBlock *TBB,
692f22ef01cSRoman Divacky                                     MachineBasicBlock *FBB,
6938f0fd8f6SDimitry Andric                                     ArrayRef<MachineOperand> Cond,
694d88c1a5aSDimitry Andric                                     const DebugLoc &DL,
695d88c1a5aSDimitry Andric                                     int *BytesAdded) const {
696f22ef01cSRoman Divacky   // Shouldn't be a fall through.
697d88c1a5aSDimitry Andric   assert(TBB && "insertBranch must not be told to insert a fallthrough");
698f22ef01cSRoman Divacky   assert((Cond.size() == 2 || Cond.size() == 0) &&
699f22ef01cSRoman Divacky          "PPC branch conditions have two components!");
700d88c1a5aSDimitry Andric   assert(!BytesAdded && "code size not handled");
701f22ef01cSRoman Divacky 
70291bc56edSDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
7037ae0e2c9SDimitry Andric 
704f22ef01cSRoman Divacky   // One-way branch.
70591bc56edSDimitry Andric   if (!FBB) {
706f22ef01cSRoman Divacky     if (Cond.empty())   // Unconditional branch
707ffd1746dSEd Schouten       BuildMI(&MBB, DL, get(PPC::B)).addMBB(TBB);
7087ae0e2c9SDimitry Andric     else if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
7097ae0e2c9SDimitry Andric       BuildMI(&MBB, DL, get(Cond[0].getImm() ?
7107ae0e2c9SDimitry Andric                               (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
7117ae0e2c9SDimitry Andric                               (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
71291bc56edSDimitry Andric     else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
7137a7e6055SDimitry Andric       BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
71491bc56edSDimitry Andric     else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
7157a7e6055SDimitry Andric       BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
716f22ef01cSRoman Divacky     else                // Conditional branch
717ffd1746dSEd Schouten       BuildMI(&MBB, DL, get(PPC::BCC))
7187a7e6055SDimitry Andric           .addImm(Cond[0].getImm())
7197a7e6055SDimitry Andric           .add(Cond[1])
7207a7e6055SDimitry Andric           .addMBB(TBB);
721f22ef01cSRoman Divacky     return 1;
722f22ef01cSRoman Divacky   }
723f22ef01cSRoman Divacky 
724f22ef01cSRoman Divacky   // Two-way Conditional Branch.
7257ae0e2c9SDimitry Andric   if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
7267ae0e2c9SDimitry Andric     BuildMI(&MBB, DL, get(Cond[0].getImm() ?
7277ae0e2c9SDimitry Andric                             (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
7287ae0e2c9SDimitry Andric                             (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
72991bc56edSDimitry Andric   else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
7307a7e6055SDimitry Andric     BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
73191bc56edSDimitry Andric   else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
7327a7e6055SDimitry Andric     BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
7337ae0e2c9SDimitry Andric   else
734ffd1746dSEd Schouten     BuildMI(&MBB, DL, get(PPC::BCC))
7357a7e6055SDimitry Andric         .addImm(Cond[0].getImm())
7367a7e6055SDimitry Andric         .add(Cond[1])
7377a7e6055SDimitry Andric         .addMBB(TBB);
738ffd1746dSEd Schouten   BuildMI(&MBB, DL, get(PPC::B)).addMBB(FBB);
739f22ef01cSRoman Divacky   return 2;
740f22ef01cSRoman Divacky }
741f22ef01cSRoman Divacky 
742284c1978SDimitry Andric // Select analysis.
canInsertSelect(const MachineBasicBlock & MBB,ArrayRef<MachineOperand> Cond,unsigned TrueReg,unsigned FalseReg,int & CondCycles,int & TrueCycles,int & FalseCycles) const743284c1978SDimitry Andric bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
7448f0fd8f6SDimitry Andric                 ArrayRef<MachineOperand> Cond,
745284c1978SDimitry Andric                 unsigned TrueReg, unsigned FalseReg,
746284c1978SDimitry Andric                 int &CondCycles, int &TrueCycles, int &FalseCycles) const {
747284c1978SDimitry Andric   if (Cond.size() != 2)
748284c1978SDimitry Andric     return false;
749284c1978SDimitry Andric 
750284c1978SDimitry Andric   // If this is really a bdnz-like condition, then it cannot be turned into a
751284c1978SDimitry Andric   // select.
752284c1978SDimitry Andric   if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
753284c1978SDimitry Andric     return false;
754284c1978SDimitry Andric 
755284c1978SDimitry Andric   // Check register classes.
756284c1978SDimitry Andric   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
757284c1978SDimitry Andric   const TargetRegisterClass *RC =
758284c1978SDimitry Andric     RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
759284c1978SDimitry Andric   if (!RC)
760284c1978SDimitry Andric     return false;
761284c1978SDimitry Andric 
762284c1978SDimitry Andric   // isel is for regular integer GPRs only.
763284c1978SDimitry Andric   if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
764f785676fSDimitry Andric       !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
765f785676fSDimitry Andric       !PPC::G8RCRegClass.hasSubClassEq(RC) &&
766f785676fSDimitry Andric       !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
767284c1978SDimitry Andric     return false;
768284c1978SDimitry Andric 
769284c1978SDimitry Andric   // FIXME: These numbers are for the A2, how well they work for other cores is
770284c1978SDimitry Andric   // an open question. On the A2, the isel instruction has a 2-cycle latency
771284c1978SDimitry Andric   // but single-cycle throughput. These numbers are used in combination with
772284c1978SDimitry Andric   // the MispredictPenalty setting from the active SchedMachineModel.
773284c1978SDimitry Andric   CondCycles = 1;
774284c1978SDimitry Andric   TrueCycles = 1;
775284c1978SDimitry Andric   FalseCycles = 1;
776284c1978SDimitry Andric 
777284c1978SDimitry Andric   return true;
778284c1978SDimitry Andric }
779284c1978SDimitry Andric 
insertSelect(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const DebugLoc & dl,unsigned DestReg,ArrayRef<MachineOperand> Cond,unsigned TrueReg,unsigned FalseReg) const780284c1978SDimitry Andric void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
7813ca95b02SDimitry Andric                                 MachineBasicBlock::iterator MI,
7823ca95b02SDimitry Andric                                 const DebugLoc &dl, unsigned DestReg,
7833ca95b02SDimitry Andric                                 ArrayRef<MachineOperand> Cond, unsigned TrueReg,
7843ca95b02SDimitry Andric                                 unsigned FalseReg) const {
785284c1978SDimitry Andric   assert(Cond.size() == 2 &&
786284c1978SDimitry Andric          "PPC branch conditions have two components!");
787284c1978SDimitry Andric 
788284c1978SDimitry Andric   // Get the register classes.
789284c1978SDimitry Andric   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
790284c1978SDimitry Andric   const TargetRegisterClass *RC =
791284c1978SDimitry Andric     RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
792284c1978SDimitry Andric   assert(RC && "TrueReg and FalseReg must have overlapping register classes");
793f785676fSDimitry Andric 
794f785676fSDimitry Andric   bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
795f785676fSDimitry Andric                  PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
796f785676fSDimitry Andric   assert((Is64Bit ||
797f785676fSDimitry Andric           PPC::GPRCRegClass.hasSubClassEq(RC) ||
798f785676fSDimitry Andric           PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
799284c1978SDimitry Andric          "isel is for regular integer GPRs only");
800284c1978SDimitry Andric 
801f785676fSDimitry Andric   unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
802444ed5c5SDimitry Andric   auto SelectPred = static_cast<PPC::Predicate>(Cond[0].getImm());
803284c1978SDimitry Andric 
8043ca95b02SDimitry Andric   unsigned SubIdx = 0;
8053ca95b02SDimitry Andric   bool SwapOps = false;
806284c1978SDimitry Andric   switch (SelectPred) {
807444ed5c5SDimitry Andric   case PPC::PRED_EQ:
808444ed5c5SDimitry Andric   case PPC::PRED_EQ_MINUS:
809444ed5c5SDimitry Andric   case PPC::PRED_EQ_PLUS:
810444ed5c5SDimitry Andric       SubIdx = PPC::sub_eq; SwapOps = false; break;
811444ed5c5SDimitry Andric   case PPC::PRED_NE:
812444ed5c5SDimitry Andric   case PPC::PRED_NE_MINUS:
813444ed5c5SDimitry Andric   case PPC::PRED_NE_PLUS:
814444ed5c5SDimitry Andric       SubIdx = PPC::sub_eq; SwapOps = true; break;
815444ed5c5SDimitry Andric   case PPC::PRED_LT:
816444ed5c5SDimitry Andric   case PPC::PRED_LT_MINUS:
817444ed5c5SDimitry Andric   case PPC::PRED_LT_PLUS:
818444ed5c5SDimitry Andric       SubIdx = PPC::sub_lt; SwapOps = false; break;
819444ed5c5SDimitry Andric   case PPC::PRED_GE:
820444ed5c5SDimitry Andric   case PPC::PRED_GE_MINUS:
821444ed5c5SDimitry Andric   case PPC::PRED_GE_PLUS:
822444ed5c5SDimitry Andric       SubIdx = PPC::sub_lt; SwapOps = true; break;
823444ed5c5SDimitry Andric   case PPC::PRED_GT:
824444ed5c5SDimitry Andric   case PPC::PRED_GT_MINUS:
825444ed5c5SDimitry Andric   case PPC::PRED_GT_PLUS:
826444ed5c5SDimitry Andric       SubIdx = PPC::sub_gt; SwapOps = false; break;
827444ed5c5SDimitry Andric   case PPC::PRED_LE:
828444ed5c5SDimitry Andric   case PPC::PRED_LE_MINUS:
829444ed5c5SDimitry Andric   case PPC::PRED_LE_PLUS:
830444ed5c5SDimitry Andric       SubIdx = PPC::sub_gt; SwapOps = true; break;
831444ed5c5SDimitry Andric   case PPC::PRED_UN:
832444ed5c5SDimitry Andric   case PPC::PRED_UN_MINUS:
833444ed5c5SDimitry Andric   case PPC::PRED_UN_PLUS:
834444ed5c5SDimitry Andric       SubIdx = PPC::sub_un; SwapOps = false; break;
835444ed5c5SDimitry Andric   case PPC::PRED_NU:
836444ed5c5SDimitry Andric   case PPC::PRED_NU_MINUS:
837444ed5c5SDimitry Andric   case PPC::PRED_NU_PLUS:
838444ed5c5SDimitry Andric       SubIdx = PPC::sub_un; SwapOps = true; break;
83991bc56edSDimitry Andric   case PPC::PRED_BIT_SET:   SubIdx = 0; SwapOps = false; break;
84091bc56edSDimitry Andric   case PPC::PRED_BIT_UNSET: SubIdx = 0; SwapOps = true; break;
841284c1978SDimitry Andric   }
842284c1978SDimitry Andric 
843284c1978SDimitry Andric   unsigned FirstReg =  SwapOps ? FalseReg : TrueReg,
844284c1978SDimitry Andric            SecondReg = SwapOps ? TrueReg  : FalseReg;
845284c1978SDimitry Andric 
846284c1978SDimitry Andric   // The first input register of isel cannot be r0. If it is a member
847284c1978SDimitry Andric   // of a register class that can be r0, then copy it first (the
848284c1978SDimitry Andric   // register allocator should eliminate the copy).
849284c1978SDimitry Andric   if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
850284c1978SDimitry Andric       MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
851284c1978SDimitry Andric     const TargetRegisterClass *FirstRC =
852284c1978SDimitry Andric       MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
853284c1978SDimitry Andric         &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
854284c1978SDimitry Andric     unsigned OldFirstReg = FirstReg;
855284c1978SDimitry Andric     FirstReg = MRI.createVirtualRegister(FirstRC);
856284c1978SDimitry Andric     BuildMI(MBB, MI, dl, get(TargetOpcode::COPY), FirstReg)
857284c1978SDimitry Andric       .addReg(OldFirstReg);
858284c1978SDimitry Andric   }
859284c1978SDimitry Andric 
860284c1978SDimitry Andric   BuildMI(MBB, MI, dl, get(OpCode), DestReg)
861284c1978SDimitry Andric     .addReg(FirstReg).addReg(SecondReg)
862284c1978SDimitry Andric     .addReg(Cond[1].getReg(), 0, SubIdx);
863284c1978SDimitry Andric }
864284c1978SDimitry Andric 
getCRBitValue(unsigned CRBit)865ff0cc061SDimitry Andric static unsigned getCRBitValue(unsigned CRBit) {
866ff0cc061SDimitry Andric   unsigned Ret = 4;
867ff0cc061SDimitry Andric   if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
868ff0cc061SDimitry Andric       CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
869ff0cc061SDimitry Andric       CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
870ff0cc061SDimitry Andric       CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
871ff0cc061SDimitry Andric     Ret = 3;
872ff0cc061SDimitry Andric   if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
873ff0cc061SDimitry Andric       CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
874ff0cc061SDimitry Andric       CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
875ff0cc061SDimitry Andric       CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
876ff0cc061SDimitry Andric     Ret = 2;
877ff0cc061SDimitry Andric   if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
878ff0cc061SDimitry Andric       CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
879ff0cc061SDimitry Andric       CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
880ff0cc061SDimitry Andric       CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
881ff0cc061SDimitry Andric     Ret = 1;
882ff0cc061SDimitry Andric   if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
883ff0cc061SDimitry Andric       CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
884ff0cc061SDimitry Andric       CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
885ff0cc061SDimitry Andric       CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
886ff0cc061SDimitry Andric     Ret = 0;
887ff0cc061SDimitry Andric 
888ff0cc061SDimitry Andric   assert(Ret != 4 && "Invalid CR bit register");
889ff0cc061SDimitry Andric   return Ret;
890ff0cc061SDimitry Andric }
891ff0cc061SDimitry Andric 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const892ffd1746dSEd Schouten void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
8933ca95b02SDimitry Andric                                MachineBasicBlock::iterator I,
8943ca95b02SDimitry Andric                                const DebugLoc &DL, unsigned DestReg,
8953ca95b02SDimitry Andric                                unsigned SrcReg, bool KillSrc) const {
89691bc56edSDimitry Andric   // We can end up with self copies and similar things as a result of VSX copy
89791bc56edSDimitry Andric   // legalization. Promote them here.
89891bc56edSDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
89991bc56edSDimitry Andric   if (PPC::F8RCRegClass.contains(DestReg) &&
900ff0cc061SDimitry Andric       PPC::VSRCRegClass.contains(SrcReg)) {
90191bc56edSDimitry Andric     unsigned SuperReg =
90291bc56edSDimitry Andric       TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
90391bc56edSDimitry Andric 
90491bc56edSDimitry Andric     if (VSXSelfCopyCrash && SrcReg == SuperReg)
90591bc56edSDimitry Andric       llvm_unreachable("nop VSX copy");
90691bc56edSDimitry Andric 
90791bc56edSDimitry Andric     DestReg = SuperReg;
90891bc56edSDimitry Andric   } else if (PPC::F8RCRegClass.contains(SrcReg) &&
909ff0cc061SDimitry Andric              PPC::VSRCRegClass.contains(DestReg)) {
91091bc56edSDimitry Andric     unsigned SuperReg =
91191bc56edSDimitry Andric       TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
91291bc56edSDimitry Andric 
91391bc56edSDimitry Andric     if (VSXSelfCopyCrash && DestReg == SuperReg)
91491bc56edSDimitry Andric       llvm_unreachable("nop VSX copy");
91591bc56edSDimitry Andric 
91691bc56edSDimitry Andric     SrcReg = SuperReg;
91791bc56edSDimitry Andric   }
91891bc56edSDimitry Andric 
919ff0cc061SDimitry Andric   // Different class register copy
920ff0cc061SDimitry Andric   if (PPC::CRBITRCRegClass.contains(SrcReg) &&
921ff0cc061SDimitry Andric       PPC::GPRCRegClass.contains(DestReg)) {
922ff0cc061SDimitry Andric     unsigned CRReg = getCRFromCRBit(SrcReg);
9233ca95b02SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg).addReg(CRReg);
9243ca95b02SDimitry Andric     getKillRegState(KillSrc);
925ff0cc061SDimitry Andric     // Rotate the CR bit in the CR fields to be the least significant bit and
926ff0cc061SDimitry Andric     // then mask with 0x1 (MB = ME = 31).
927ff0cc061SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)
928ff0cc061SDimitry Andric        .addReg(DestReg, RegState::Kill)
929ff0cc061SDimitry Andric        .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))
930ff0cc061SDimitry Andric        .addImm(31)
931ff0cc061SDimitry Andric        .addImm(31);
932ff0cc061SDimitry Andric     return;
933ff0cc061SDimitry Andric   } else if (PPC::CRRCRegClass.contains(SrcReg) &&
934ff0cc061SDimitry Andric       PPC::G8RCRegClass.contains(DestReg)) {
9353ca95b02SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFOCRF8), DestReg).addReg(SrcReg);
9363ca95b02SDimitry Andric     getKillRegState(KillSrc);
937ff0cc061SDimitry Andric     return;
938ff0cc061SDimitry Andric   } else if (PPC::CRRCRegClass.contains(SrcReg) &&
939ff0cc061SDimitry Andric       PPC::GPRCRegClass.contains(DestReg)) {
9403ca95b02SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg).addReg(SrcReg);
9413ca95b02SDimitry Andric     getKillRegState(KillSrc);
942ff0cc061SDimitry Andric     return;
9432cab237bSDimitry Andric   } else if (PPC::G8RCRegClass.contains(SrcReg) &&
9442cab237bSDimitry Andric              PPC::VSFRCRegClass.contains(DestReg)) {
9452cab237bSDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MTVSRD), DestReg).addReg(SrcReg);
9462cab237bSDimitry Andric     NumGPRtoVSRSpill++;
9472cab237bSDimitry Andric     getKillRegState(KillSrc);
9482cab237bSDimitry Andric     return;
9492cab237bSDimitry Andric   } else if (PPC::VSFRCRegClass.contains(SrcReg) &&
9502cab237bSDimitry Andric              PPC::G8RCRegClass.contains(DestReg)) {
9512cab237bSDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFVSRD), DestReg).addReg(SrcReg);
9522cab237bSDimitry Andric     getKillRegState(KillSrc);
9532cab237bSDimitry Andric     return;
9544ba319b5SDimitry Andric   } else if (PPC::SPERCRegClass.contains(SrcReg) &&
9554ba319b5SDimitry Andric              PPC::SPE4RCRegClass.contains(DestReg)) {
9564ba319b5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::EFSCFD), DestReg).addReg(SrcReg);
9574ba319b5SDimitry Andric     getKillRegState(KillSrc);
9584ba319b5SDimitry Andric     return;
9594ba319b5SDimitry Andric   } else if (PPC::SPE4RCRegClass.contains(SrcReg) &&
9604ba319b5SDimitry Andric              PPC::SPERCRegClass.contains(DestReg)) {
9614ba319b5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::EFDCFS), DestReg).addReg(SrcReg);
9624ba319b5SDimitry Andric     getKillRegState(KillSrc);
9634ba319b5SDimitry Andric     return;
964ff0cc061SDimitry Andric   }
965ff0cc061SDimitry Andric 
9664ba319b5SDimitry Andric 
967ffd1746dSEd Schouten   unsigned Opc;
968ffd1746dSEd Schouten   if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
969ffd1746dSEd Schouten     Opc = PPC::OR;
970ffd1746dSEd Schouten   else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))
971ffd1746dSEd Schouten     Opc = PPC::OR8;
972ffd1746dSEd Schouten   else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))
973ffd1746dSEd Schouten     Opc = PPC::FMR;
974ffd1746dSEd Schouten   else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))
975ffd1746dSEd Schouten     Opc = PPC::MCRF;
976ffd1746dSEd Schouten   else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))
977ffd1746dSEd Schouten     Opc = PPC::VOR;
97891bc56edSDimitry Andric   else if (PPC::VSRCRegClass.contains(DestReg, SrcReg))
97991bc56edSDimitry Andric     // There are two different ways this can be done:
98091bc56edSDimitry Andric     //   1. xxlor : This has lower latency (on the P7), 2 cycles, but can only
98191bc56edSDimitry Andric     //      issue in VSU pipeline 0.
98291bc56edSDimitry Andric     //   2. xmovdp/xmovsp: This has higher latency (on the P7), 6 cycles, but
98391bc56edSDimitry Andric     //      can go to either pipeline.
98491bc56edSDimitry Andric     // We'll always use xxlor here, because in practically all cases where
98591bc56edSDimitry Andric     // copies are generated, they are close enough to some use that the
98691bc56edSDimitry Andric     // lower-latency form is preferable.
98791bc56edSDimitry Andric     Opc = PPC::XXLOR;
988ff0cc061SDimitry Andric   else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||
989ff0cc061SDimitry Andric            PPC::VSSRCRegClass.contains(DestReg, SrcReg))
990*b5893f02SDimitry Andric     Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
991ff0cc061SDimitry Andric   else if (PPC::QFRCRegClass.contains(DestReg, SrcReg))
992ff0cc061SDimitry Andric     Opc = PPC::QVFMR;
993ff0cc061SDimitry Andric   else if (PPC::QSRCRegClass.contains(DestReg, SrcReg))
994ff0cc061SDimitry Andric     Opc = PPC::QVFMRs;
995ff0cc061SDimitry Andric   else if (PPC::QBRCRegClass.contains(DestReg, SrcReg))
996ff0cc061SDimitry Andric     Opc = PPC::QVFMRb;
997ffd1746dSEd Schouten   else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
998ffd1746dSEd Schouten     Opc = PPC::CROR;
9994ba319b5SDimitry Andric   else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
10004ba319b5SDimitry Andric     Opc = PPC::EVOR;
1001ffd1746dSEd Schouten   else
1002ffd1746dSEd Schouten     llvm_unreachable("Impossible reg-to-reg copy");
1003f22ef01cSRoman Divacky 
100417a519f9SDimitry Andric   const MCInstrDesc &MCID = get(Opc);
100517a519f9SDimitry Andric   if (MCID.getNumOperands() == 3)
100617a519f9SDimitry Andric     BuildMI(MBB, I, DL, MCID, DestReg)
1007ffd1746dSEd Schouten       .addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
1008ffd1746dSEd Schouten   else
100917a519f9SDimitry Andric     BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc));
1010f22ef01cSRoman Divacky }
1011f22ef01cSRoman Divacky 
getStoreOpcodeForSpill(unsigned Reg,const TargetRegisterClass * RC) const10124ba319b5SDimitry Andric unsigned PPCInstrInfo::getStoreOpcodeForSpill(unsigned Reg,
10134ba319b5SDimitry Andric                                               const TargetRegisterClass *RC)
10144ba319b5SDimitry Andric                                               const {
10154ba319b5SDimitry Andric   const unsigned *OpcodesForSpill = getStoreOpcodesForSpillArray();
10164ba319b5SDimitry Andric   int OpcodeIndex = 0;
1017139f7f9bSDimitry Andric 
10184ba319b5SDimitry Andric   if (RC != nullptr) {
101985d60e68SDimitry Andric     if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
102085d60e68SDimitry Andric         PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
10214ba319b5SDimitry Andric       OpcodeIndex = SOK_Int4Spill;
102285d60e68SDimitry Andric     } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
102385d60e68SDimitry Andric                PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
10244ba319b5SDimitry Andric       OpcodeIndex = SOK_Int8Spill;
10257ae0e2c9SDimitry Andric     } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
10264ba319b5SDimitry Andric       OpcodeIndex = SOK_Float8Spill;
10277ae0e2c9SDimitry Andric     } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
10284ba319b5SDimitry Andric       OpcodeIndex = SOK_Float4Spill;
10294ba319b5SDimitry Andric     } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
10304ba319b5SDimitry Andric       OpcodeIndex = SOK_SPESpill;
10314ba319b5SDimitry Andric     } else if (PPC::SPE4RCRegClass.hasSubClassEq(RC)) {
10324ba319b5SDimitry Andric       OpcodeIndex = SOK_SPE4Spill;
10337ae0e2c9SDimitry Andric     } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
10344ba319b5SDimitry Andric       OpcodeIndex = SOK_CRSpill;
10357ae0e2c9SDimitry Andric     } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
10364ba319b5SDimitry Andric       OpcodeIndex = SOK_CRBitSpill;
10377ae0e2c9SDimitry Andric     } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
10384ba319b5SDimitry Andric       OpcodeIndex = SOK_VRVectorSpill;
103991bc56edSDimitry Andric     } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
10404ba319b5SDimitry Andric       OpcodeIndex = SOK_VSXVectorSpill;
104191bc56edSDimitry Andric     } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
10424ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat8Spill;
1043ff0cc061SDimitry Andric     } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
10444ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat4Spill;
1045139f7f9bSDimitry Andric     } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) {
10464ba319b5SDimitry Andric       OpcodeIndex = SOK_VRSaveSpill;
1047ff0cc061SDimitry Andric     } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) {
10484ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat8Spill;
1049ff0cc061SDimitry Andric     } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) {
10504ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat4Spill;
1051ff0cc061SDimitry Andric     } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) {
10524ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadBitSpill;
10532cab237bSDimitry Andric     } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
10544ba319b5SDimitry Andric       OpcodeIndex = SOK_SpillToVSR;
1055f22ef01cSRoman Divacky     } else {
1056f22ef01cSRoman Divacky       llvm_unreachable("Unknown regclass!");
1057f22ef01cSRoman Divacky     }
10584ba319b5SDimitry Andric   } else {
10594ba319b5SDimitry Andric     if (PPC::GPRCRegClass.contains(Reg) ||
10604ba319b5SDimitry Andric         PPC::GPRC_NOR0RegClass.contains(Reg)) {
10614ba319b5SDimitry Andric       OpcodeIndex = SOK_Int4Spill;
10624ba319b5SDimitry Andric     } else if (PPC::G8RCRegClass.contains(Reg) ||
10634ba319b5SDimitry Andric                PPC::G8RC_NOX0RegClass.contains(Reg)) {
10644ba319b5SDimitry Andric       OpcodeIndex = SOK_Int8Spill;
10654ba319b5SDimitry Andric     } else if (PPC::F8RCRegClass.contains(Reg)) {
10664ba319b5SDimitry Andric       OpcodeIndex = SOK_Float8Spill;
10674ba319b5SDimitry Andric     } else if (PPC::F4RCRegClass.contains(Reg)) {
10684ba319b5SDimitry Andric       OpcodeIndex = SOK_Float4Spill;
10694ba319b5SDimitry Andric     } else if (PPC::CRRCRegClass.contains(Reg)) {
10704ba319b5SDimitry Andric       OpcodeIndex = SOK_CRSpill;
10714ba319b5SDimitry Andric     } else if (PPC::CRBITRCRegClass.contains(Reg)) {
10724ba319b5SDimitry Andric       OpcodeIndex = SOK_CRBitSpill;
10734ba319b5SDimitry Andric     } else if (PPC::VRRCRegClass.contains(Reg)) {
10744ba319b5SDimitry Andric       OpcodeIndex = SOK_VRVectorSpill;
10754ba319b5SDimitry Andric     } else if (PPC::VSRCRegClass.contains(Reg)) {
10764ba319b5SDimitry Andric       OpcodeIndex = SOK_VSXVectorSpill;
10774ba319b5SDimitry Andric     } else if (PPC::VSFRCRegClass.contains(Reg)) {
10784ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat8Spill;
10794ba319b5SDimitry Andric     } else if (PPC::VSSRCRegClass.contains(Reg)) {
10804ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat4Spill;
10814ba319b5SDimitry Andric     } else if (PPC::VRSAVERCRegClass.contains(Reg)) {
10824ba319b5SDimitry Andric       OpcodeIndex = SOK_VRSaveSpill;
10834ba319b5SDimitry Andric     } else if (PPC::QFRCRegClass.contains(Reg)) {
10844ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat8Spill;
10854ba319b5SDimitry Andric     } else if (PPC::QSRCRegClass.contains(Reg)) {
10864ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat4Spill;
10874ba319b5SDimitry Andric     } else if (PPC::QBRCRegClass.contains(Reg)) {
10884ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadBitSpill;
10894ba319b5SDimitry Andric     } else if (PPC::SPILLTOVSRRCRegClass.contains(Reg)) {
10904ba319b5SDimitry Andric       OpcodeIndex = SOK_SpillToVSR;
10914ba319b5SDimitry Andric     } else {
10924ba319b5SDimitry Andric       llvm_unreachable("Unknown regclass!");
10934ba319b5SDimitry Andric     }
10944ba319b5SDimitry Andric   }
10954ba319b5SDimitry Andric   return OpcodesForSpill[OpcodeIndex];
1096f22ef01cSRoman Divacky }
1097f22ef01cSRoman Divacky 
10984ba319b5SDimitry Andric unsigned
getLoadOpcodeForSpill(unsigned Reg,const TargetRegisterClass * RC) const10994ba319b5SDimitry Andric PPCInstrInfo::getLoadOpcodeForSpill(unsigned Reg,
11004ba319b5SDimitry Andric                                     const TargetRegisterClass *RC) const {
11014ba319b5SDimitry Andric   const unsigned *OpcodesForSpill = getLoadOpcodesForSpillArray();
11024ba319b5SDimitry Andric   int OpcodeIndex = 0;
11034ba319b5SDimitry Andric 
11044ba319b5SDimitry Andric   if (RC != nullptr) {
11054ba319b5SDimitry Andric     if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
11064ba319b5SDimitry Andric         PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
11074ba319b5SDimitry Andric       OpcodeIndex = SOK_Int4Spill;
11084ba319b5SDimitry Andric     } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
11094ba319b5SDimitry Andric                PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
11104ba319b5SDimitry Andric       OpcodeIndex = SOK_Int8Spill;
11114ba319b5SDimitry Andric     } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
11124ba319b5SDimitry Andric       OpcodeIndex = SOK_Float8Spill;
11134ba319b5SDimitry Andric     } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
11144ba319b5SDimitry Andric       OpcodeIndex = SOK_Float4Spill;
11154ba319b5SDimitry Andric     } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
11164ba319b5SDimitry Andric       OpcodeIndex = SOK_SPESpill;
11174ba319b5SDimitry Andric     } else if (PPC::SPE4RCRegClass.hasSubClassEq(RC)) {
11184ba319b5SDimitry Andric       OpcodeIndex = SOK_SPE4Spill;
11194ba319b5SDimitry Andric     } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
11204ba319b5SDimitry Andric       OpcodeIndex = SOK_CRSpill;
11214ba319b5SDimitry Andric     } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
11224ba319b5SDimitry Andric       OpcodeIndex = SOK_CRBitSpill;
11234ba319b5SDimitry Andric     } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
11244ba319b5SDimitry Andric       OpcodeIndex = SOK_VRVectorSpill;
11254ba319b5SDimitry Andric     } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
11264ba319b5SDimitry Andric       OpcodeIndex = SOK_VSXVectorSpill;
11274ba319b5SDimitry Andric     } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
11284ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat8Spill;
11294ba319b5SDimitry Andric     } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
11304ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat4Spill;
11314ba319b5SDimitry Andric     } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) {
11324ba319b5SDimitry Andric       OpcodeIndex = SOK_VRSaveSpill;
11334ba319b5SDimitry Andric     } else if (PPC::QFRCRegClass.hasSubClassEq(RC)) {
11344ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat8Spill;
11354ba319b5SDimitry Andric     } else if (PPC::QSRCRegClass.hasSubClassEq(RC)) {
11364ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat4Spill;
11374ba319b5SDimitry Andric     } else if (PPC::QBRCRegClass.hasSubClassEq(RC)) {
11384ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadBitSpill;
11394ba319b5SDimitry Andric     } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
11404ba319b5SDimitry Andric       OpcodeIndex = SOK_SpillToVSR;
11414ba319b5SDimitry Andric     } else {
11424ba319b5SDimitry Andric       llvm_unreachable("Unknown regclass!");
11434ba319b5SDimitry Andric     }
11444ba319b5SDimitry Andric   } else {
11454ba319b5SDimitry Andric     if (PPC::GPRCRegClass.contains(Reg) ||
11464ba319b5SDimitry Andric         PPC::GPRC_NOR0RegClass.contains(Reg)) {
11474ba319b5SDimitry Andric       OpcodeIndex = SOK_Int4Spill;
11484ba319b5SDimitry Andric     } else if (PPC::G8RCRegClass.contains(Reg) ||
11494ba319b5SDimitry Andric                PPC::G8RC_NOX0RegClass.contains(Reg)) {
11504ba319b5SDimitry Andric       OpcodeIndex = SOK_Int8Spill;
11514ba319b5SDimitry Andric     } else if (PPC::F8RCRegClass.contains(Reg)) {
11524ba319b5SDimitry Andric       OpcodeIndex = SOK_Float8Spill;
11534ba319b5SDimitry Andric     } else if (PPC::F4RCRegClass.contains(Reg)) {
11544ba319b5SDimitry Andric       OpcodeIndex = SOK_Float4Spill;
11554ba319b5SDimitry Andric     } else if (PPC::CRRCRegClass.contains(Reg)) {
11564ba319b5SDimitry Andric       OpcodeIndex = SOK_CRSpill;
11574ba319b5SDimitry Andric     } else if (PPC::CRBITRCRegClass.contains(Reg)) {
11584ba319b5SDimitry Andric       OpcodeIndex = SOK_CRBitSpill;
11594ba319b5SDimitry Andric     } else if (PPC::VRRCRegClass.contains(Reg)) {
11604ba319b5SDimitry Andric       OpcodeIndex = SOK_VRVectorSpill;
11614ba319b5SDimitry Andric     } else if (PPC::VSRCRegClass.contains(Reg)) {
11624ba319b5SDimitry Andric       OpcodeIndex = SOK_VSXVectorSpill;
11634ba319b5SDimitry Andric     } else if (PPC::VSFRCRegClass.contains(Reg)) {
11644ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat8Spill;
11654ba319b5SDimitry Andric     } else if (PPC::VSSRCRegClass.contains(Reg)) {
11664ba319b5SDimitry Andric       OpcodeIndex = SOK_VectorFloat4Spill;
11674ba319b5SDimitry Andric     } else if (PPC::VRSAVERCRegClass.contains(Reg)) {
11684ba319b5SDimitry Andric       OpcodeIndex = SOK_VRSaveSpill;
11694ba319b5SDimitry Andric     } else if (PPC::QFRCRegClass.contains(Reg)) {
11704ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat8Spill;
11714ba319b5SDimitry Andric     } else if (PPC::QSRCRegClass.contains(Reg)) {
11724ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadFloat4Spill;
11734ba319b5SDimitry Andric     } else if (PPC::QBRCRegClass.contains(Reg)) {
11744ba319b5SDimitry Andric       OpcodeIndex = SOK_QuadBitSpill;
11754ba319b5SDimitry Andric     } else if (PPC::SPILLTOVSRRCRegClass.contains(Reg)) {
11764ba319b5SDimitry Andric       OpcodeIndex = SOK_SpillToVSR;
11774ba319b5SDimitry Andric     } else {
11784ba319b5SDimitry Andric       llvm_unreachable("Unknown regclass!");
11794ba319b5SDimitry Andric     }
11804ba319b5SDimitry Andric   }
11814ba319b5SDimitry Andric   return OpcodesForSpill[OpcodeIndex];
11824ba319b5SDimitry Andric }
11834ba319b5SDimitry Andric 
StoreRegToStackSlot(MachineFunction & MF,unsigned SrcReg,bool isKill,int FrameIdx,const TargetRegisterClass * RC,SmallVectorImpl<MachineInstr * > & NewMIs) const11844ba319b5SDimitry Andric void PPCInstrInfo::StoreRegToStackSlot(
11854ba319b5SDimitry Andric     MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,
11864ba319b5SDimitry Andric     const TargetRegisterClass *RC,
11874ba319b5SDimitry Andric     SmallVectorImpl<MachineInstr *> &NewMIs) const {
11884ba319b5SDimitry Andric   unsigned Opcode = getStoreOpcodeForSpill(PPC::NoRegister, RC);
11894ba319b5SDimitry Andric   DebugLoc DL;
11904ba319b5SDimitry Andric 
11914ba319b5SDimitry Andric   PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
11924ba319b5SDimitry Andric   FuncInfo->setHasSpills();
11934ba319b5SDimitry Andric 
11944ba319b5SDimitry Andric   NewMIs.push_back(addFrameReference(
11954ba319b5SDimitry Andric       BuildMI(MF, DL, get(Opcode)).addReg(SrcReg, getKillRegState(isKill)),
11964ba319b5SDimitry Andric       FrameIdx));
11974ba319b5SDimitry Andric 
11984ba319b5SDimitry Andric   if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
11994ba319b5SDimitry Andric       PPC::CRBITRCRegClass.hasSubClassEq(RC))
12004ba319b5SDimitry Andric     FuncInfo->setSpillsCR();
12014ba319b5SDimitry Andric 
12024ba319b5SDimitry Andric   if (PPC::VRSAVERCRegClass.hasSubClassEq(RC))
12034ba319b5SDimitry Andric     FuncInfo->setSpillsVRSAVE();
12044ba319b5SDimitry Andric 
12054ba319b5SDimitry Andric   if (isXFormMemOp(Opcode))
12064ba319b5SDimitry Andric     FuncInfo->setHasNonRISpills();
12074ba319b5SDimitry Andric }
12084ba319b5SDimitry Andric 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,unsigned SrcReg,bool isKill,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const12094ba319b5SDimitry Andric void PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
1210f22ef01cSRoman Divacky                                        MachineBasicBlock::iterator MI,
12114ba319b5SDimitry Andric                                        unsigned SrcReg, bool isKill,
12124ba319b5SDimitry Andric                                        int FrameIdx,
1213f22ef01cSRoman Divacky                                        const TargetRegisterClass *RC,
1214f22ef01cSRoman Divacky                                        const TargetRegisterInfo *TRI) const {
1215f22ef01cSRoman Divacky   MachineFunction &MF = *MBB.getParent();
1216f22ef01cSRoman Divacky   SmallVector<MachineInstr *, 4> NewMIs;
1217f22ef01cSRoman Divacky 
1218d88c1a5aSDimitry Andric   // We need to avoid a situation in which the value from a VRRC register is
1219d88c1a5aSDimitry Andric   // spilled using an Altivec instruction and reloaded into a VSRC register
1220d88c1a5aSDimitry Andric   // using a VSX instruction. The issue with this is that the VSX
1221d88c1a5aSDimitry Andric   // load/store instructions swap the doublewords in the vector and the Altivec
1222d88c1a5aSDimitry Andric   // ones don't. The register classes on the spill/reload may be different if
1223d88c1a5aSDimitry Andric   // the register is defined using an Altivec instruction and is then used by a
1224d88c1a5aSDimitry Andric   // VSX instruction.
1225d88c1a5aSDimitry Andric   RC = updatedRC(RC);
1226d88c1a5aSDimitry Andric 
12274ba319b5SDimitry Andric   StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
1228f22ef01cSRoman Divacky 
1229f22ef01cSRoman Divacky   for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
1230f22ef01cSRoman Divacky     MBB.insert(MI, NewMIs[i]);
1231e580952dSDimitry Andric 
1232d88c1a5aSDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
12337d523365SDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
12347d523365SDimitry Andric       MachinePointerInfo::getFixedStack(MF, FrameIdx),
12357d523365SDimitry Andric       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
1236e580952dSDimitry Andric       MFI.getObjectAlignment(FrameIdx));
1237e580952dSDimitry Andric   NewMIs.back()->addMemOperand(MF, MMO);
1238f22ef01cSRoman Divacky }
1239f22ef01cSRoman Divacky 
LoadRegFromStackSlot(MachineFunction & MF,const DebugLoc & DL,unsigned DestReg,int FrameIdx,const TargetRegisterClass * RC,SmallVectorImpl<MachineInstr * > & NewMIs) const12404ba319b5SDimitry Andric void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL,
1241f22ef01cSRoman Divacky                                         unsigned DestReg, int FrameIdx,
1242f22ef01cSRoman Divacky                                         const TargetRegisterClass *RC,
12434ba319b5SDimitry Andric                                         SmallVectorImpl<MachineInstr *> &NewMIs)
12444ba319b5SDimitry Andric                                         const {
12454ba319b5SDimitry Andric   unsigned Opcode = getLoadOpcodeForSpill(PPC::NoRegister, RC);
12464ba319b5SDimitry Andric   NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opcode), DestReg),
12474ba319b5SDimitry Andric                                      FrameIdx));
12484ba319b5SDimitry Andric   PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
1249139f7f9bSDimitry Andric 
12504ba319b5SDimitry Andric   if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
12514ba319b5SDimitry Andric       PPC::CRBITRCRegClass.hasSubClassEq(RC))
12524ba319b5SDimitry Andric     FuncInfo->setSpillsCR();
1253dff0c46cSDimitry Andric 
12544ba319b5SDimitry Andric   if (PPC::VRSAVERCRegClass.hasSubClassEq(RC))
12554ba319b5SDimitry Andric     FuncInfo->setSpillsVRSAVE();
12564ba319b5SDimitry Andric 
12574ba319b5SDimitry Andric   if (isXFormMemOp(Opcode))
12584ba319b5SDimitry Andric     FuncInfo->setHasNonRISpills();
1259f22ef01cSRoman Divacky }
1260f22ef01cSRoman Divacky 
1261f22ef01cSRoman Divacky void
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,unsigned DestReg,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const1262f22ef01cSRoman Divacky PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
1263f22ef01cSRoman Divacky                                    MachineBasicBlock::iterator MI,
1264f22ef01cSRoman Divacky                                    unsigned DestReg, int FrameIdx,
1265f22ef01cSRoman Divacky                                    const TargetRegisterClass *RC,
1266f22ef01cSRoman Divacky                                    const TargetRegisterInfo *TRI) const {
1267f22ef01cSRoman Divacky   MachineFunction &MF = *MBB.getParent();
1268f22ef01cSRoman Divacky   SmallVector<MachineInstr*, 4> NewMIs;
1269f22ef01cSRoman Divacky   DebugLoc DL;
1270f22ef01cSRoman Divacky   if (MI != MBB.end()) DL = MI->getDebugLoc();
1271139f7f9bSDimitry Andric 
1272dff0c46cSDimitry Andric   PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
1273139f7f9bSDimitry Andric   FuncInfo->setHasSpills();
1274139f7f9bSDimitry Andric 
1275d88c1a5aSDimitry Andric   // We need to avoid a situation in which the value from a VRRC register is
1276d88c1a5aSDimitry Andric   // spilled using an Altivec instruction and reloaded into a VSRC register
1277d88c1a5aSDimitry Andric   // using a VSX instruction. The issue with this is that the VSX
1278d88c1a5aSDimitry Andric   // load/store instructions swap the doublewords in the vector and the Altivec
1279d88c1a5aSDimitry Andric   // ones don't. The register classes on the spill/reload may be different if
1280d88c1a5aSDimitry Andric   // the register is defined using an Altivec instruction and is then used by a
1281d88c1a5aSDimitry Andric   // VSX instruction.
1282d88c1a5aSDimitry Andric   if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
1283d88c1a5aSDimitry Andric     RC = &PPC::VSRCRegClass;
1284d88c1a5aSDimitry Andric 
12854ba319b5SDimitry Andric   LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);
1286139f7f9bSDimitry Andric 
1287f22ef01cSRoman Divacky   for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
1288f22ef01cSRoman Divacky     MBB.insert(MI, NewMIs[i]);
1289e580952dSDimitry Andric 
1290d88c1a5aSDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
12917d523365SDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
12927d523365SDimitry Andric       MachinePointerInfo::getFixedStack(MF, FrameIdx),
12937d523365SDimitry Andric       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
1294e580952dSDimitry Andric       MFI.getObjectAlignment(FrameIdx));
1295e580952dSDimitry Andric   NewMIs.back()->addMemOperand(MF, MMO);
1296f22ef01cSRoman Divacky }
1297f22ef01cSRoman Divacky 
1298f22ef01cSRoman Divacky bool PPCInstrInfo::
reverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const1299d88c1a5aSDimitry Andric reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
1300f22ef01cSRoman Divacky   assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
13017ae0e2c9SDimitry Andric   if (Cond[1].getReg() == PPC::CTR8 || Cond[1].getReg() == PPC::CTR)
13027ae0e2c9SDimitry Andric     Cond[0].setImm(Cond[0].getImm() == 0 ? 1 : 0);
13037ae0e2c9SDimitry Andric   else
1304f22ef01cSRoman Divacky     // Leave the CR# the same, but invert the condition.
1305f22ef01cSRoman Divacky     Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm()));
1306f22ef01cSRoman Divacky   return false;
1307f22ef01cSRoman Divacky }
1308f22ef01cSRoman Divacky 
FoldImmediate(MachineInstr & UseMI,MachineInstr & DefMI,unsigned Reg,MachineRegisterInfo * MRI) const13093ca95b02SDimitry Andric bool PPCInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
1310284c1978SDimitry Andric                                  unsigned Reg, MachineRegisterInfo *MRI) const {
1311284c1978SDimitry Andric   // For some instructions, it is legal to fold ZERO into the RA register field.
1312284c1978SDimitry Andric   // A zero immediate should always be loaded with a single li.
13133ca95b02SDimitry Andric   unsigned DefOpc = DefMI.getOpcode();
1314284c1978SDimitry Andric   if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
1315284c1978SDimitry Andric     return false;
13163ca95b02SDimitry Andric   if (!DefMI.getOperand(1).isImm())
1317284c1978SDimitry Andric     return false;
13183ca95b02SDimitry Andric   if (DefMI.getOperand(1).getImm() != 0)
1319284c1978SDimitry Andric     return false;
1320284c1978SDimitry Andric 
1321284c1978SDimitry Andric   // Note that we cannot here invert the arguments of an isel in order to fold
1322284c1978SDimitry Andric   // a ZERO into what is presented as the second argument. All we have here
1323284c1978SDimitry Andric   // is the condition bit, and that might come from a CR-logical bit operation.
1324284c1978SDimitry Andric 
13253ca95b02SDimitry Andric   const MCInstrDesc &UseMCID = UseMI.getDesc();
1326284c1978SDimitry Andric 
1327284c1978SDimitry Andric   // Only fold into real machine instructions.
1328284c1978SDimitry Andric   if (UseMCID.isPseudo())
1329284c1978SDimitry Andric     return false;
1330284c1978SDimitry Andric 
1331284c1978SDimitry Andric   unsigned UseIdx;
13323ca95b02SDimitry Andric   for (UseIdx = 0; UseIdx < UseMI.getNumOperands(); ++UseIdx)
13333ca95b02SDimitry Andric     if (UseMI.getOperand(UseIdx).isReg() &&
13343ca95b02SDimitry Andric         UseMI.getOperand(UseIdx).getReg() == Reg)
1335284c1978SDimitry Andric       break;
1336284c1978SDimitry Andric 
13373ca95b02SDimitry Andric   assert(UseIdx < UseMI.getNumOperands() && "Cannot find Reg in UseMI");
1338284c1978SDimitry Andric   assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");
1339284c1978SDimitry Andric 
1340284c1978SDimitry Andric   const MCOperandInfo *UseInfo = &UseMCID.OpInfo[UseIdx];
1341284c1978SDimitry Andric 
1342284c1978SDimitry Andric   // We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0
1343284c1978SDimitry Andric   // register (which might also be specified as a pointer class kind).
1344284c1978SDimitry Andric   if (UseInfo->isLookupPtrRegClass()) {
1345284c1978SDimitry Andric     if (UseInfo->RegClass /* Kind */ != 1)
1346284c1978SDimitry Andric       return false;
1347284c1978SDimitry Andric   } else {
1348284c1978SDimitry Andric     if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID &&
1349284c1978SDimitry Andric         UseInfo->RegClass != PPC::G8RC_NOX0RegClassID)
1350284c1978SDimitry Andric       return false;
1351284c1978SDimitry Andric   }
1352284c1978SDimitry Andric 
1353284c1978SDimitry Andric   // Make sure this is not tied to an output register (or otherwise
1354284c1978SDimitry Andric   // constrained). This is true for ST?UX registers, for example, which
1355284c1978SDimitry Andric   // are tied to their output registers.
1356284c1978SDimitry Andric   if (UseInfo->Constraints != 0)
1357284c1978SDimitry Andric     return false;
1358284c1978SDimitry Andric 
1359284c1978SDimitry Andric   unsigned ZeroReg;
1360284c1978SDimitry Andric   if (UseInfo->isLookupPtrRegClass()) {
136191bc56edSDimitry Andric     bool isPPC64 = Subtarget.isPPC64();
1362284c1978SDimitry Andric     ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO;
1363284c1978SDimitry Andric   } else {
1364284c1978SDimitry Andric     ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ?
1365284c1978SDimitry Andric               PPC::ZERO8 : PPC::ZERO;
1366284c1978SDimitry Andric   }
1367284c1978SDimitry Andric 
1368284c1978SDimitry Andric   bool DeleteDef = MRI->hasOneNonDBGUse(Reg);
13693ca95b02SDimitry Andric   UseMI.getOperand(UseIdx).setReg(ZeroReg);
1370284c1978SDimitry Andric 
1371284c1978SDimitry Andric   if (DeleteDef)
13723ca95b02SDimitry Andric     DefMI.eraseFromParent();
1373284c1978SDimitry Andric 
1374284c1978SDimitry Andric   return true;
1375284c1978SDimitry Andric }
1376284c1978SDimitry Andric 
MBBDefinesCTR(MachineBasicBlock & MBB)1377284c1978SDimitry Andric static bool MBBDefinesCTR(MachineBasicBlock &MBB) {
1378284c1978SDimitry Andric   for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
1379284c1978SDimitry Andric        I != IE; ++I)
1380284c1978SDimitry Andric     if (I->definesRegister(PPC::CTR) || I->definesRegister(PPC::CTR8))
1381284c1978SDimitry Andric       return true;
1382284c1978SDimitry Andric   return false;
1383284c1978SDimitry Andric }
1384284c1978SDimitry Andric 
1385284c1978SDimitry Andric // We should make sure that, if we're going to predicate both sides of a
1386284c1978SDimitry Andric // condition (a diamond), that both sides don't define the counter register. We
1387284c1978SDimitry Andric // can predicate counter-decrement-based branches, but while that predicates
1388284c1978SDimitry Andric // the branching, it does not predicate the counter decrement. If we tried to
1389284c1978SDimitry Andric // merge the triangle into one predicated block, we'd decrement the counter
1390284c1978SDimitry Andric // twice.
isProfitableToIfCvt(MachineBasicBlock & TMBB,unsigned NumT,unsigned ExtraT,MachineBasicBlock & FMBB,unsigned NumF,unsigned ExtraF,BranchProbability Probability) const1391284c1978SDimitry Andric bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
1392284c1978SDimitry Andric                      unsigned NumT, unsigned ExtraT,
1393284c1978SDimitry Andric                      MachineBasicBlock &FMBB,
1394284c1978SDimitry Andric                      unsigned NumF, unsigned ExtraF,
13957d523365SDimitry Andric                      BranchProbability Probability) const {
1396284c1978SDimitry Andric   return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB));
1397284c1978SDimitry Andric }
1398284c1978SDimitry Andric 
1399284c1978SDimitry Andric 
isPredicated(const MachineInstr & MI) const14003ca95b02SDimitry Andric bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
1401284c1978SDimitry Andric   // The predicated branches are identified by their type, not really by the
1402284c1978SDimitry Andric   // explicit presence of a predicate. Furthermore, some of them can be
1403284c1978SDimitry Andric   // predicated more than once. Because if conversion won't try to predicate
1404284c1978SDimitry Andric   // any instruction which already claims to be predicated (by returning true
1405284c1978SDimitry Andric   // here), always return false. In doing so, we let isPredicable() be the
1406284c1978SDimitry Andric   // final word on whether not the instruction can be (further) predicated.
1407284c1978SDimitry Andric 
1408284c1978SDimitry Andric   return false;
1409284c1978SDimitry Andric }
1410284c1978SDimitry Andric 
isUnpredicatedTerminator(const MachineInstr & MI) const14113ca95b02SDimitry Andric bool PPCInstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
14123ca95b02SDimitry Andric   if (!MI.isTerminator())
1413284c1978SDimitry Andric     return false;
1414284c1978SDimitry Andric 
1415284c1978SDimitry Andric   // Conditional branch is a special case.
14163ca95b02SDimitry Andric   if (MI.isBranch() && !MI.isBarrier())
1417284c1978SDimitry Andric     return true;
1418284c1978SDimitry Andric 
1419284c1978SDimitry Andric   return !isPredicated(MI);
1420284c1978SDimitry Andric }
1421284c1978SDimitry Andric 
PredicateInstruction(MachineInstr & MI,ArrayRef<MachineOperand> Pred) const14223ca95b02SDimitry Andric bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
14238f0fd8f6SDimitry Andric                                         ArrayRef<MachineOperand> Pred) const {
14243ca95b02SDimitry Andric   unsigned OpC = MI.getOpcode();
142539d628a0SDimitry Andric   if (OpC == PPC::BLR || OpC == PPC::BLR8) {
1426284c1978SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
142791bc56edSDimitry Andric       bool isPPC64 = Subtarget.isPPC64();
14283ca95b02SDimitry Andric       MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
14293ca95b02SDimitry Andric                                       : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
143091bc56edSDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
14313ca95b02SDimitry Andric       MI.setDesc(get(PPC::BCLR));
1432*b5893f02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
143391bc56edSDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
14343ca95b02SDimitry Andric       MI.setDesc(get(PPC::BCLRn));
1435*b5893f02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
143691bc56edSDimitry Andric     } else {
14373ca95b02SDimitry Andric       MI.setDesc(get(PPC::BCCLR));
14383ca95b02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
1439284c1978SDimitry Andric           .addImm(Pred[0].getImm())
1440*b5893f02SDimitry Andric           .add(Pred[1]);
1441284c1978SDimitry Andric     }
1442284c1978SDimitry Andric 
1443284c1978SDimitry Andric     return true;
1444284c1978SDimitry Andric   } else if (OpC == PPC::B) {
1445284c1978SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
144691bc56edSDimitry Andric       bool isPPC64 = Subtarget.isPPC64();
14473ca95b02SDimitry Andric       MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
14483ca95b02SDimitry Andric                                       : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
144991bc56edSDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
14503ca95b02SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
14513ca95b02SDimitry Andric       MI.RemoveOperand(0);
145291bc56edSDimitry Andric 
14533ca95b02SDimitry Andric       MI.setDesc(get(PPC::BC));
14543ca95b02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
1455*b5893f02SDimitry Andric           .add(Pred[1])
145691bc56edSDimitry Andric           .addMBB(MBB);
145791bc56edSDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
14583ca95b02SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
14593ca95b02SDimitry Andric       MI.RemoveOperand(0);
146091bc56edSDimitry Andric 
14613ca95b02SDimitry Andric       MI.setDesc(get(PPC::BCn));
14623ca95b02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
1463*b5893f02SDimitry Andric           .add(Pred[1])
146491bc56edSDimitry Andric           .addMBB(MBB);
1465284c1978SDimitry Andric     } else {
14663ca95b02SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
14673ca95b02SDimitry Andric       MI.RemoveOperand(0);
1468284c1978SDimitry Andric 
14693ca95b02SDimitry Andric       MI.setDesc(get(PPC::BCC));
14703ca95b02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
1471284c1978SDimitry Andric           .addImm(Pred[0].getImm())
1472*b5893f02SDimitry Andric           .add(Pred[1])
1473284c1978SDimitry Andric           .addMBB(MBB);
1474284c1978SDimitry Andric     }
1475284c1978SDimitry Andric 
1476284c1978SDimitry Andric     return true;
1477*b5893f02SDimitry Andric   } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
1478*b5893f02SDimitry Andric              OpC == PPC::BCTRL8) {
1479284c1978SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)
1480284c1978SDimitry Andric       llvm_unreachable("Cannot predicate bctr[l] on the ctr register");
1481284c1978SDimitry Andric 
1482284c1978SDimitry Andric     bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8;
148391bc56edSDimitry Andric     bool isPPC64 = Subtarget.isPPC64();
148491bc56edSDimitry Andric 
148591bc56edSDimitry Andric     if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
14863ca95b02SDimitry Andric       MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
14873ca95b02SDimitry Andric                              : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
1488*b5893f02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
148991bc56edSDimitry Andric       return true;
149091bc56edSDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
14913ca95b02SDimitry Andric       MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
14923ca95b02SDimitry Andric                              : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
1493*b5893f02SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
149491bc56edSDimitry Andric       return true;
149591bc56edSDimitry Andric     }
149691bc56edSDimitry Andric 
14973ca95b02SDimitry Andric     MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
14983ca95b02SDimitry Andric                            : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
14993ca95b02SDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
1500284c1978SDimitry Andric         .addImm(Pred[0].getImm())
1501*b5893f02SDimitry Andric         .add(Pred[1]);
1502284c1978SDimitry Andric     return true;
1503284c1978SDimitry Andric   }
1504284c1978SDimitry Andric 
1505284c1978SDimitry Andric   return false;
1506284c1978SDimitry Andric }
1507284c1978SDimitry Andric 
SubsumesPredicate(ArrayRef<MachineOperand> Pred1,ArrayRef<MachineOperand> Pred2) const15088f0fd8f6SDimitry Andric bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
15098f0fd8f6SDimitry Andric                                      ArrayRef<MachineOperand> Pred2) const {
1510284c1978SDimitry Andric   assert(Pred1.size() == 2 && "Invalid PPC first predicate");
1511284c1978SDimitry Andric   assert(Pred2.size() == 2 && "Invalid PPC second predicate");
1512284c1978SDimitry Andric 
1513284c1978SDimitry Andric   if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)
1514284c1978SDimitry Andric     return false;
1515284c1978SDimitry Andric   if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)
1516284c1978SDimitry Andric     return false;
1517284c1978SDimitry Andric 
1518f785676fSDimitry Andric   // P1 can only subsume P2 if they test the same condition register.
1519f785676fSDimitry Andric   if (Pred1[1].getReg() != Pred2[1].getReg())
1520f785676fSDimitry Andric     return false;
1521f785676fSDimitry Andric 
1522284c1978SDimitry Andric   PPC::Predicate P1 = (PPC::Predicate) Pred1[0].getImm();
1523284c1978SDimitry Andric   PPC::Predicate P2 = (PPC::Predicate) Pred2[0].getImm();
1524284c1978SDimitry Andric 
1525284c1978SDimitry Andric   if (P1 == P2)
1526284c1978SDimitry Andric     return true;
1527284c1978SDimitry Andric 
1528284c1978SDimitry Andric   // Does P1 subsume P2, e.g. GE subsumes GT.
1529284c1978SDimitry Andric   if (P1 == PPC::PRED_LE &&
1530284c1978SDimitry Andric       (P2 == PPC::PRED_LT || P2 == PPC::PRED_EQ))
1531284c1978SDimitry Andric     return true;
1532284c1978SDimitry Andric   if (P1 == PPC::PRED_GE &&
1533284c1978SDimitry Andric       (P2 == PPC::PRED_GT || P2 == PPC::PRED_EQ))
1534284c1978SDimitry Andric     return true;
1535284c1978SDimitry Andric 
1536284c1978SDimitry Andric   return false;
1537284c1978SDimitry Andric }
1538284c1978SDimitry Andric 
DefinesPredicate(MachineInstr & MI,std::vector<MachineOperand> & Pred) const15393ca95b02SDimitry Andric bool PPCInstrInfo::DefinesPredicate(MachineInstr &MI,
1540284c1978SDimitry Andric                                     std::vector<MachineOperand> &Pred) const {
1541284c1978SDimitry Andric   // Note: At the present time, the contents of Pred from this function is
1542284c1978SDimitry Andric   // unused by IfConversion. This implementation follows ARM by pushing the
1543284c1978SDimitry Andric   // CR-defining operand. Because the 'DZ' and 'DNZ' count as types of
1544284c1978SDimitry Andric   // predicate, instructions defining CTR or CTR8 are also included as
1545284c1978SDimitry Andric   // predicate-defining instructions.
1546284c1978SDimitry Andric 
1547284c1978SDimitry Andric   const TargetRegisterClass *RCs[] =
1548284c1978SDimitry Andric     { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
1549284c1978SDimitry Andric       &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
1550284c1978SDimitry Andric 
1551284c1978SDimitry Andric   bool Found = false;
15523ca95b02SDimitry Andric   for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
15533ca95b02SDimitry Andric     const MachineOperand &MO = MI.getOperand(i);
1554284c1978SDimitry Andric     for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) {
1555284c1978SDimitry Andric       const TargetRegisterClass *RC = RCs[c];
1556284c1978SDimitry Andric       if (MO.isReg()) {
1557284c1978SDimitry Andric         if (MO.isDef() && RC->contains(MO.getReg())) {
1558284c1978SDimitry Andric           Pred.push_back(MO);
1559284c1978SDimitry Andric           Found = true;
1560284c1978SDimitry Andric         }
1561284c1978SDimitry Andric       } else if (MO.isRegMask()) {
1562284c1978SDimitry Andric         for (TargetRegisterClass::iterator I = RC->begin(),
1563284c1978SDimitry Andric              IE = RC->end(); I != IE; ++I)
1564284c1978SDimitry Andric           if (MO.clobbersPhysReg(*I)) {
1565284c1978SDimitry Andric             Pred.push_back(MO);
1566284c1978SDimitry Andric             Found = true;
1567284c1978SDimitry Andric           }
1568284c1978SDimitry Andric       }
1569284c1978SDimitry Andric     }
1570284c1978SDimitry Andric   }
1571284c1978SDimitry Andric 
1572284c1978SDimitry Andric   return Found;
1573284c1978SDimitry Andric }
1574284c1978SDimitry Andric 
isPredicable(const MachineInstr & MI) const15757a7e6055SDimitry Andric bool PPCInstrInfo::isPredicable(const MachineInstr &MI) const {
15763ca95b02SDimitry Andric   unsigned OpC = MI.getOpcode();
1577284c1978SDimitry Andric   switch (OpC) {
1578284c1978SDimitry Andric   default:
1579284c1978SDimitry Andric     return false;
1580284c1978SDimitry Andric   case PPC::B:
1581284c1978SDimitry Andric   case PPC::BLR:
158239d628a0SDimitry Andric   case PPC::BLR8:
1583284c1978SDimitry Andric   case PPC::BCTR:
1584284c1978SDimitry Andric   case PPC::BCTR8:
1585284c1978SDimitry Andric   case PPC::BCTRL:
1586284c1978SDimitry Andric   case PPC::BCTRL8:
1587284c1978SDimitry Andric     return true;
1588284c1978SDimitry Andric   }
1589284c1978SDimitry Andric }
1590284c1978SDimitry Andric 
analyzeCompare(const MachineInstr & MI,unsigned & SrcReg,unsigned & SrcReg2,int & Mask,int & Value) const15913ca95b02SDimitry Andric bool PPCInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
15923ca95b02SDimitry Andric                                   unsigned &SrcReg2, int &Mask,
15933ca95b02SDimitry Andric                                   int &Value) const {
15943ca95b02SDimitry Andric   unsigned Opc = MI.getOpcode();
1595284c1978SDimitry Andric 
1596284c1978SDimitry Andric   switch (Opc) {
1597284c1978SDimitry Andric   default: return false;
1598284c1978SDimitry Andric   case PPC::CMPWI:
1599284c1978SDimitry Andric   case PPC::CMPLWI:
1600284c1978SDimitry Andric   case PPC::CMPDI:
1601284c1978SDimitry Andric   case PPC::CMPLDI:
16023ca95b02SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
1603284c1978SDimitry Andric     SrcReg2 = 0;
16043ca95b02SDimitry Andric     Value = MI.getOperand(2).getImm();
1605284c1978SDimitry Andric     Mask = 0xFFFF;
1606284c1978SDimitry Andric     return true;
1607284c1978SDimitry Andric   case PPC::CMPW:
1608284c1978SDimitry Andric   case PPC::CMPLW:
1609284c1978SDimitry Andric   case PPC::CMPD:
1610284c1978SDimitry Andric   case PPC::CMPLD:
1611284c1978SDimitry Andric   case PPC::FCMPUS:
1612284c1978SDimitry Andric   case PPC::FCMPUD:
16133ca95b02SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
16143ca95b02SDimitry Andric     SrcReg2 = MI.getOperand(2).getReg();
1615d8866befSDimitry Andric     Value = 0;
1616d8866befSDimitry Andric     Mask = 0;
1617284c1978SDimitry Andric     return true;
1618284c1978SDimitry Andric   }
1619284c1978SDimitry Andric }
1620284c1978SDimitry Andric 
optimizeCompareInstr(MachineInstr & CmpInstr,unsigned SrcReg,unsigned SrcReg2,int Mask,int Value,const MachineRegisterInfo * MRI) const16213ca95b02SDimitry Andric bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
16223ca95b02SDimitry Andric                                         unsigned SrcReg2, int Mask, int Value,
1623284c1978SDimitry Andric                                         const MachineRegisterInfo *MRI) const {
1624284c1978SDimitry Andric   if (DisableCmpOpt)
1625284c1978SDimitry Andric     return false;
1626284c1978SDimitry Andric 
16273ca95b02SDimitry Andric   int OpC = CmpInstr.getOpcode();
16283ca95b02SDimitry Andric   unsigned CRReg = CmpInstr.getOperand(0).getReg();
1629284c1978SDimitry Andric 
16304ba319b5SDimitry Andric   // FP record forms set CR1 based on the exception status bits, not a
1631284c1978SDimitry Andric   // comparison with zero.
1632284c1978SDimitry Andric   if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
1633284c1978SDimitry Andric     return false;
1634284c1978SDimitry Andric 
1635284c1978SDimitry Andric   // The record forms set the condition register based on a signed comparison
1636284c1978SDimitry Andric   // with zero (so says the ISA manual). This is not as straightforward as it
1637284c1978SDimitry Andric   // seems, however, because this is always a 64-bit comparison on PPC64, even
1638284c1978SDimitry Andric   // for instructions that are 32-bit in nature (like slw for example).
1639284c1978SDimitry Andric   // So, on PPC32, for unsigned comparisons, we can use the record forms only
1640284c1978SDimitry Andric   // for equality checks (as those don't depend on the sign). On PPC64,
1641284c1978SDimitry Andric   // we are restricted to equality for unsigned 64-bit comparisons and for
1642284c1978SDimitry Andric   // signed 32-bit comparisons the applicability is more restricted.
164391bc56edSDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
1644284c1978SDimitry Andric   bool is32BitSignedCompare   = OpC ==  PPC::CMPWI || OpC == PPC::CMPW;
1645284c1978SDimitry Andric   bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
1646284c1978SDimitry Andric   bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
1647284c1978SDimitry Andric 
1648284c1978SDimitry Andric   // Get the unique definition of SrcReg.
1649284c1978SDimitry Andric   MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
1650284c1978SDimitry Andric   if (!MI) return false;
1651284c1978SDimitry Andric 
1652284c1978SDimitry Andric   bool equalityOnly = false;
1653284c1978SDimitry Andric   bool noSub = false;
1654284c1978SDimitry Andric   if (isPPC64) {
1655284c1978SDimitry Andric     if (is32BitSignedCompare) {
1656284c1978SDimitry Andric       // We can perform this optimization only if MI is sign-extending.
16572cab237bSDimitry Andric       if (isSignExtended(*MI))
1658284c1978SDimitry Andric         noSub = true;
16592cab237bSDimitry Andric       else
1660284c1978SDimitry Andric         return false;
1661284c1978SDimitry Andric     } else if (is32BitUnsignedCompare) {
1662284c1978SDimitry Andric       // We can perform this optimization, equality only, if MI is
1663284c1978SDimitry Andric       // zero-extending.
16642cab237bSDimitry Andric       if (isZeroExtended(*MI)) {
1665284c1978SDimitry Andric         noSub = true;
1666284c1978SDimitry Andric         equalityOnly = true;
1667284c1978SDimitry Andric       } else
1668284c1978SDimitry Andric         return false;
1669284c1978SDimitry Andric     } else
1670284c1978SDimitry Andric       equalityOnly = is64BitUnsignedCompare;
1671284c1978SDimitry Andric   } else
1672284c1978SDimitry Andric     equalityOnly = is32BitUnsignedCompare;
1673284c1978SDimitry Andric 
1674284c1978SDimitry Andric   if (equalityOnly) {
1675284c1978SDimitry Andric     // We need to check the uses of the condition register in order to reject
1676284c1978SDimitry Andric     // non-equality comparisons.
1677b40b48b8SDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
1678b40b48b8SDimitry Andric          I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
1679b40b48b8SDimitry Andric          I != IE; ++I) {
1680284c1978SDimitry Andric       MachineInstr *UseMI = &*I;
1681284c1978SDimitry Andric       if (UseMI->getOpcode() == PPC::BCC) {
16822cab237bSDimitry Andric         PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
16832cab237bSDimitry Andric         unsigned PredCond = PPC::getPredicateCondition(Pred);
16842cab237bSDimitry Andric         // We ignore hint bits when checking for non-equality comparisons.
16852cab237bSDimitry Andric         if (PredCond != PPC::PRED_EQ && PredCond != PPC::PRED_NE)
1686284c1978SDimitry Andric           return false;
1687284c1978SDimitry Andric       } else if (UseMI->getOpcode() == PPC::ISEL ||
1688284c1978SDimitry Andric                  UseMI->getOpcode() == PPC::ISEL8) {
1689284c1978SDimitry Andric         unsigned SubIdx = UseMI->getOperand(3).getSubReg();
1690f785676fSDimitry Andric         if (SubIdx != PPC::sub_eq)
1691284c1978SDimitry Andric           return false;
1692284c1978SDimitry Andric       } else
1693284c1978SDimitry Andric         return false;
1694284c1978SDimitry Andric     }
1695284c1978SDimitry Andric   }
1696284c1978SDimitry Andric 
1697f785676fSDimitry Andric   MachineBasicBlock::iterator I = CmpInstr;
1698284c1978SDimitry Andric 
1699284c1978SDimitry Andric   // Scan forward to find the first use of the compare.
17003ca95b02SDimitry Andric   for (MachineBasicBlock::iterator EL = CmpInstr.getParent()->end(); I != EL;
17013ca95b02SDimitry Andric        ++I) {
1702284c1978SDimitry Andric     bool FoundUse = false;
1703b40b48b8SDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
1704b40b48b8SDimitry Andric          J = MRI->use_instr_begin(CRReg), JE = MRI->use_instr_end();
1705b40b48b8SDimitry Andric          J != JE; ++J)
1706284c1978SDimitry Andric       if (&*J == &*I) {
1707284c1978SDimitry Andric         FoundUse = true;
1708284c1978SDimitry Andric         break;
1709284c1978SDimitry Andric       }
1710284c1978SDimitry Andric 
1711284c1978SDimitry Andric     if (FoundUse)
1712284c1978SDimitry Andric       break;
1713284c1978SDimitry Andric   }
1714284c1978SDimitry Andric 
1715d8866befSDimitry Andric   SmallVector<std::pair<MachineOperand*, PPC::Predicate>, 4> PredsToUpdate;
1716d8866befSDimitry Andric   SmallVector<std::pair<MachineOperand*, unsigned>, 4> SubRegsToUpdate;
1717d8866befSDimitry Andric 
1718284c1978SDimitry Andric   // There are two possible candidates which can be changed to set CR[01].
1719284c1978SDimitry Andric   // One is MI, the other is a SUB instruction.
1720284c1978SDimitry Andric   // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
172191bc56edSDimitry Andric   MachineInstr *Sub = nullptr;
1722284c1978SDimitry Andric   if (SrcReg2 != 0)
1723284c1978SDimitry Andric     // MI is not a candidate for CMPrr.
172491bc56edSDimitry Andric     MI = nullptr;
1725284c1978SDimitry Andric   // FIXME: Conservatively refuse to convert an instruction which isn't in the
1726284c1978SDimitry Andric   // same BB as the comparison. This is to allow the check below to avoid calls
1727284c1978SDimitry Andric   // (and other explicit clobbers); instead we should really check for these
1728284c1978SDimitry Andric   // more explicitly (in at least a few predecessors).
1729d8866befSDimitry Andric   else if (MI->getParent() != CmpInstr.getParent())
1730d8866befSDimitry Andric     return false;
1731d8866befSDimitry Andric   else if (Value != 0) {
17322cab237bSDimitry Andric     // The record-form instructions set CR bit based on signed comparison
17332cab237bSDimitry Andric     // against 0. We try to convert a compare against 1 or -1 into a compare
17342cab237bSDimitry Andric     // against 0 to exploit record-form instructions. For example, we change
17352cab237bSDimitry Andric     // the condition "greater than -1" into "greater than or equal to 0"
17362cab237bSDimitry Andric     // and "less than 1" into "less than or equal to 0".
17372cab237bSDimitry Andric 
17382cab237bSDimitry Andric     // Since we optimize comparison based on a specific branch condition,
17392cab237bSDimitry Andric     // we don't optimize if condition code is used by more than once.
17402cab237bSDimitry Andric     if (equalityOnly || !MRI->hasOneUse(CRReg))
17412cab237bSDimitry Andric       return false;
17422cab237bSDimitry Andric 
1743d8866befSDimitry Andric     MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
17442cab237bSDimitry Andric     if (UseMI->getOpcode() != PPC::BCC)
17452cab237bSDimitry Andric       return false;
17462cab237bSDimitry Andric 
1747d8866befSDimitry Andric     PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
17482cab237bSDimitry Andric     PPC::Predicate NewPred = Pred;
17492cab237bSDimitry Andric     unsigned PredCond = PPC::getPredicateCondition(Pred);
17502cab237bSDimitry Andric     unsigned PredHint = PPC::getPredicateHint(Pred);
1751d8866befSDimitry Andric     int16_t Immed = (int16_t)Value;
1752d8866befSDimitry Andric 
17534ba319b5SDimitry Andric     // When modifying the condition in the predicate, we propagate hint bits
17542cab237bSDimitry Andric     // from the original predicate to the new one.
17552cab237bSDimitry Andric     if (Immed == -1 && PredCond == PPC::PRED_GT)
1756d8866befSDimitry Andric       // We convert "greater than -1" into "greater than or equal to 0",
1757d8866befSDimitry Andric       // since we are assuming signed comparison by !equalityOnly
17582cab237bSDimitry Andric       NewPred = PPC::getPredicate(PPC::PRED_GE, PredHint);
17592cab237bSDimitry Andric     else if (Immed == -1 && PredCond == PPC::PRED_LE)
17602cab237bSDimitry Andric       // We convert "less than or equal to -1" into "less than 0".
17612cab237bSDimitry Andric       NewPred = PPC::getPredicate(PPC::PRED_LT, PredHint);
17622cab237bSDimitry Andric     else if (Immed == 1 && PredCond == PPC::PRED_LT)
1763d8866befSDimitry Andric       // We convert "less than 1" into "less than or equal to 0".
17642cab237bSDimitry Andric       NewPred = PPC::getPredicate(PPC::PRED_LE, PredHint);
17652cab237bSDimitry Andric     else if (Immed == 1 && PredCond == PPC::PRED_GE)
17662cab237bSDimitry Andric       // We convert "greater than or equal to 1" into "greater than 0".
17672cab237bSDimitry Andric       NewPred = PPC::getPredicate(PPC::PRED_GT, PredHint);
17682cab237bSDimitry Andric     else
1769284c1978SDimitry Andric       return false;
17702cab237bSDimitry Andric 
17712cab237bSDimitry Andric     PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
17722cab237bSDimitry Andric                                             NewPred));
1773284c1978SDimitry Andric   }
1774284c1978SDimitry Andric 
1775284c1978SDimitry Andric   // Search for Sub.
1776284c1978SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
1777284c1978SDimitry Andric   --I;
1778f785676fSDimitry Andric 
1779f785676fSDimitry Andric   // Get ready to iterate backward from CmpInstr.
17803ca95b02SDimitry Andric   MachineBasicBlock::iterator E = MI, B = CmpInstr.getParent()->begin();
1781f785676fSDimitry Andric 
1782284c1978SDimitry Andric   for (; I != E && !noSub; --I) {
1783284c1978SDimitry Andric     const MachineInstr &Instr = *I;
1784284c1978SDimitry Andric     unsigned IOpC = Instr.getOpcode();
1785284c1978SDimitry Andric 
17863ca95b02SDimitry Andric     if (&*I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, TRI) ||
1787284c1978SDimitry Andric                              Instr.readsRegister(PPC::CR0, TRI)))
1788284c1978SDimitry Andric       // This instruction modifies or uses the record condition register after
1789284c1978SDimitry Andric       // the one we want to change. While we could do this transformation, it
1790284c1978SDimitry Andric       // would likely not be profitable. This transformation removes one
1791284c1978SDimitry Andric       // instruction, and so even forcing RA to generate one move probably
1792284c1978SDimitry Andric       // makes it unprofitable.
1793284c1978SDimitry Andric       return false;
1794284c1978SDimitry Andric 
1795284c1978SDimitry Andric     // Check whether CmpInstr can be made redundant by the current instruction.
1796284c1978SDimitry Andric     if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
1797284c1978SDimitry Andric          OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
1798284c1978SDimitry Andric         (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
1799284c1978SDimitry Andric         ((Instr.getOperand(1).getReg() == SrcReg &&
1800284c1978SDimitry Andric           Instr.getOperand(2).getReg() == SrcReg2) ||
1801284c1978SDimitry Andric         (Instr.getOperand(1).getReg() == SrcReg2 &&
1802284c1978SDimitry Andric          Instr.getOperand(2).getReg() == SrcReg))) {
1803284c1978SDimitry Andric       Sub = &*I;
1804284c1978SDimitry Andric       break;
1805284c1978SDimitry Andric     }
1806284c1978SDimitry Andric 
1807284c1978SDimitry Andric     if (I == B)
1808284c1978SDimitry Andric       // The 'and' is below the comparison instruction.
1809284c1978SDimitry Andric       return false;
1810284c1978SDimitry Andric   }
1811284c1978SDimitry Andric 
1812284c1978SDimitry Andric   // Return false if no candidates exist.
1813284c1978SDimitry Andric   if (!MI && !Sub)
1814284c1978SDimitry Andric     return false;
1815284c1978SDimitry Andric 
1816284c1978SDimitry Andric   // The single candidate is called MI.
1817284c1978SDimitry Andric   if (!MI) MI = Sub;
1818284c1978SDimitry Andric 
1819284c1978SDimitry Andric   int NewOpC = -1;
18202cab237bSDimitry Andric   int MIOpC = MI->getOpcode();
1821*b5893f02SDimitry Andric   if (MIOpC == PPC::ANDIo || MIOpC == PPC::ANDIo8 ||
1822*b5893f02SDimitry Andric       MIOpC == PPC::ANDISo || MIOpC == PPC::ANDISo8)
1823284c1978SDimitry Andric     NewOpC = MIOpC;
1824284c1978SDimitry Andric   else {
1825284c1978SDimitry Andric     NewOpC = PPC::getRecordFormOpcode(MIOpC);
1826284c1978SDimitry Andric     if (NewOpC == -1 && PPC::getNonRecordFormOpcode(MIOpC) != -1)
1827284c1978SDimitry Andric       NewOpC = MIOpC;
1828284c1978SDimitry Andric   }
1829284c1978SDimitry Andric 
1830284c1978SDimitry Andric   // FIXME: On the non-embedded POWER architectures, only some of the record
1831284c1978SDimitry Andric   // forms are fast, and we should use only the fast ones.
1832284c1978SDimitry Andric 
1833284c1978SDimitry Andric   // The defining instruction has a record form (or is already a record
1834284c1978SDimitry Andric   // form). It is possible, however, that we'll need to reverse the condition
1835284c1978SDimitry Andric   // code of the users.
1836284c1978SDimitry Andric   if (NewOpC == -1)
1837284c1978SDimitry Andric     return false;
1838284c1978SDimitry Andric 
1839284c1978SDimitry Andric   // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP
1840284c1978SDimitry Andric   // needs to be updated to be based on SUB.  Push the condition code
1841284c1978SDimitry Andric   // operands to OperandsToUpdate.  If it is safe to remove CmpInstr, the
1842284c1978SDimitry Andric   // condition code of these operands will be modified.
1843d8866befSDimitry Andric   // Here, Value == 0 means we haven't converted comparison against 1 or -1 to
1844d8866befSDimitry Andric   // comparison against 0, which may modify predicate.
1845284c1978SDimitry Andric   bool ShouldSwap = false;
1846d8866befSDimitry Andric   if (Sub && Value == 0) {
1847284c1978SDimitry Andric     ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
1848284c1978SDimitry Andric       Sub->getOperand(2).getReg() == SrcReg;
1849284c1978SDimitry Andric 
1850284c1978SDimitry Andric     // The operands to subf are the opposite of sub, so only in the fixed-point
1851284c1978SDimitry Andric     // case, invert the order.
1852284c1978SDimitry Andric     ShouldSwap = !ShouldSwap;
1853284c1978SDimitry Andric   }
1854284c1978SDimitry Andric 
1855284c1978SDimitry Andric   if (ShouldSwap)
185691bc56edSDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
185791bc56edSDimitry Andric          I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
185891bc56edSDimitry Andric          I != IE; ++I) {
1859284c1978SDimitry Andric       MachineInstr *UseMI = &*I;
1860284c1978SDimitry Andric       if (UseMI->getOpcode() == PPC::BCC) {
1861284c1978SDimitry Andric         PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm();
18622cab237bSDimitry Andric         unsigned PredCond = PPC::getPredicateCondition(Pred);
1863284c1978SDimitry Andric         assert((!equalityOnly ||
18642cab237bSDimitry Andric                 PredCond == PPC::PRED_EQ || PredCond == PPC::PRED_NE) &&
1865284c1978SDimitry Andric                "Invalid predicate for equality-only optimization");
18662cab237bSDimitry Andric         (void)PredCond; // To suppress warning in release build.
186791bc56edSDimitry Andric         PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
1868284c1978SDimitry Andric                                 PPC::getSwappedPredicate(Pred)));
1869284c1978SDimitry Andric       } else if (UseMI->getOpcode() == PPC::ISEL ||
1870284c1978SDimitry Andric                  UseMI->getOpcode() == PPC::ISEL8) {
1871284c1978SDimitry Andric         unsigned NewSubReg = UseMI->getOperand(3).getSubReg();
1872284c1978SDimitry Andric         assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
1873284c1978SDimitry Andric                "Invalid CR bit for equality-only optimization");
1874284c1978SDimitry Andric 
1875284c1978SDimitry Andric         if (NewSubReg == PPC::sub_lt)
1876284c1978SDimitry Andric           NewSubReg = PPC::sub_gt;
1877284c1978SDimitry Andric         else if (NewSubReg == PPC::sub_gt)
1878284c1978SDimitry Andric           NewSubReg = PPC::sub_lt;
1879284c1978SDimitry Andric 
188091bc56edSDimitry Andric         SubRegsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(3)),
1881284c1978SDimitry Andric                                                  NewSubReg));
1882284c1978SDimitry Andric       } else // We need to abort on a user we don't understand.
1883284c1978SDimitry Andric         return false;
1884284c1978SDimitry Andric     }
1885d8866befSDimitry Andric   assert(!(Value != 0 && ShouldSwap) &&
1886d8866befSDimitry Andric          "Non-zero immediate support and ShouldSwap"
1887d8866befSDimitry Andric          "may conflict in updating predicate");
1888284c1978SDimitry Andric 
1889284c1978SDimitry Andric   // Create a new virtual register to hold the value of the CR set by the
1890284c1978SDimitry Andric   // record-form instruction. If the instruction was not previously in
1891284c1978SDimitry Andric   // record form, then set the kill flag on the CR.
18923ca95b02SDimitry Andric   CmpInstr.eraseFromParent();
1893284c1978SDimitry Andric 
1894284c1978SDimitry Andric   MachineBasicBlock::iterator MII = MI;
189591bc56edSDimitry Andric   BuildMI(*MI->getParent(), std::next(MII), MI->getDebugLoc(),
1896284c1978SDimitry Andric           get(TargetOpcode::COPY), CRReg)
1897284c1978SDimitry Andric     .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0);
1898284c1978SDimitry Andric 
18993ca95b02SDimitry Andric   // Even if CR0 register were dead before, it is alive now since the
19003ca95b02SDimitry Andric   // instruction we just built uses it.
19013ca95b02SDimitry Andric   MI->clearRegisterDeads(PPC::CR0);
19023ca95b02SDimitry Andric 
1903284c1978SDimitry Andric   if (MIOpC != NewOpC) {
1904284c1978SDimitry Andric     // We need to be careful here: we're replacing one instruction with
1905284c1978SDimitry Andric     // another, and we need to make sure that we get all of the right
1906284c1978SDimitry Andric     // implicit uses and defs. On the other hand, the caller may be holding
1907284c1978SDimitry Andric     // an iterator to this instruction, and so we can't delete it (this is
1908284c1978SDimitry Andric     // specifically the case if this is the instruction directly after the
1909284c1978SDimitry Andric     // compare).
1910284c1978SDimitry Andric 
19114ba319b5SDimitry Andric     // Rotates are expensive instructions. If we're emitting a record-form
1912*b5893f02SDimitry Andric     // rotate that can just be an andi/andis, we should just emit that.
1913*b5893f02SDimitry Andric     if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
1914*b5893f02SDimitry Andric       unsigned GPRRes = MI->getOperand(0).getReg();
1915*b5893f02SDimitry Andric       int64_t SH = MI->getOperand(2).getImm();
19164ba319b5SDimitry Andric       int64_t MB = MI->getOperand(3).getImm();
19174ba319b5SDimitry Andric       int64_t ME = MI->getOperand(4).getImm();
1918*b5893f02SDimitry Andric       // We can only do this if both the start and end of the mask are in the
1919*b5893f02SDimitry Andric       // same halfword.
1920*b5893f02SDimitry Andric       bool MBInLoHWord = MB >= 16;
1921*b5893f02SDimitry Andric       bool MEInLoHWord = ME >= 16;
1922*b5893f02SDimitry Andric       uint64_t Mask = ~0LLU;
1923*b5893f02SDimitry Andric 
1924*b5893f02SDimitry Andric       if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
1925*b5893f02SDimitry Andric         Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
1926*b5893f02SDimitry Andric         // The mask value needs to shift right 16 if we're emitting andis.
1927*b5893f02SDimitry Andric         Mask >>= MBInLoHWord ? 0 : 16;
1928*b5893f02SDimitry Andric         NewOpC = MIOpC == PPC::RLWINM ?
1929*b5893f02SDimitry Andric           (MBInLoHWord ? PPC::ANDIo : PPC::ANDISo) :
1930*b5893f02SDimitry Andric           (MBInLoHWord ? PPC::ANDIo8 :PPC::ANDISo8);
1931*b5893f02SDimitry Andric       } else if (MRI->use_empty(GPRRes) && (ME == 31) &&
1932*b5893f02SDimitry Andric                  (ME - MB + 1 == SH) && (MB >= 16)) {
1933*b5893f02SDimitry Andric         // If we are rotating by the exact number of bits as are in the mask
1934*b5893f02SDimitry Andric         // and the mask is in the least significant bits of the register,
1935*b5893f02SDimitry Andric         // that's just an andis. (as long as the GPR result has no uses).
1936*b5893f02SDimitry Andric         Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
1937*b5893f02SDimitry Andric         Mask >>= 16;
1938*b5893f02SDimitry Andric         NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDISo :PPC::ANDISo8;
1939*b5893f02SDimitry Andric       }
1940*b5893f02SDimitry Andric       // If we've set the mask, we can transform.
1941*b5893f02SDimitry Andric       if (Mask != ~0LLU) {
19424ba319b5SDimitry Andric         MI->RemoveOperand(4);
19434ba319b5SDimitry Andric         MI->RemoveOperand(3);
19444ba319b5SDimitry Andric         MI->getOperand(2).setImm(Mask);
19454ba319b5SDimitry Andric         NumRcRotatesConvertedToRcAnd++;
19464ba319b5SDimitry Andric       }
19474ba319b5SDimitry Andric     } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {
19484ba319b5SDimitry Andric       int64_t MB = MI->getOperand(3).getImm();
19494ba319b5SDimitry Andric       if (MB >= 48) {
19504ba319b5SDimitry Andric         uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
19514ba319b5SDimitry Andric         NewOpC = PPC::ANDIo8;
19524ba319b5SDimitry Andric         MI->RemoveOperand(3);
19534ba319b5SDimitry Andric         MI->getOperand(2).setImm(Mask);
19544ba319b5SDimitry Andric         NumRcRotatesConvertedToRcAnd++;
19554ba319b5SDimitry Andric       }
19564ba319b5SDimitry Andric     }
19574ba319b5SDimitry Andric 
1958284c1978SDimitry Andric     const MCInstrDesc &NewDesc = get(NewOpC);
1959284c1978SDimitry Andric     MI->setDesc(NewDesc);
1960284c1978SDimitry Andric 
1961284c1978SDimitry Andric     if (NewDesc.ImplicitDefs)
19627d523365SDimitry Andric       for (const MCPhysReg *ImpDefs = NewDesc.getImplicitDefs();
1963284c1978SDimitry Andric            *ImpDefs; ++ImpDefs)
1964284c1978SDimitry Andric         if (!MI->definesRegister(*ImpDefs))
1965284c1978SDimitry Andric           MI->addOperand(*MI->getParent()->getParent(),
1966284c1978SDimitry Andric                          MachineOperand::CreateReg(*ImpDefs, true, true));
1967284c1978SDimitry Andric     if (NewDesc.ImplicitUses)
19687d523365SDimitry Andric       for (const MCPhysReg *ImpUses = NewDesc.getImplicitUses();
1969284c1978SDimitry Andric            *ImpUses; ++ImpUses)
1970284c1978SDimitry Andric         if (!MI->readsRegister(*ImpUses))
1971284c1978SDimitry Andric           MI->addOperand(*MI->getParent()->getParent(),
1972284c1978SDimitry Andric                          MachineOperand::CreateReg(*ImpUses, false, true));
1973284c1978SDimitry Andric   }
19743ca95b02SDimitry Andric   assert(MI->definesRegister(PPC::CR0) &&
19753ca95b02SDimitry Andric          "Record-form instruction does not define cr0?");
1976284c1978SDimitry Andric 
1977284c1978SDimitry Andric   // Modify the condition code of operands in OperandsToUpdate.
1978284c1978SDimitry Andric   // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
1979284c1978SDimitry Andric   // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
1980284c1978SDimitry Andric   for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)
1981284c1978SDimitry Andric     PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
1982284c1978SDimitry Andric 
1983284c1978SDimitry Andric   for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)
1984284c1978SDimitry Andric     SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
1985284c1978SDimitry Andric 
1986284c1978SDimitry Andric   return true;
1987284c1978SDimitry Andric }
1988284c1978SDimitry Andric 
1989f22ef01cSRoman Divacky /// GetInstSize - Return the number of bytes of code the specified
1990f22ef01cSRoman Divacky /// instruction may be.  This returns the maximum number of bytes.
1991f22ef01cSRoman Divacky ///
getInstSizeInBytes(const MachineInstr & MI) const1992d88c1a5aSDimitry Andric unsigned PPCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
19933ca95b02SDimitry Andric   unsigned Opcode = MI.getOpcode();
199491bc56edSDimitry Andric 
199591bc56edSDimitry Andric   if (Opcode == PPC::INLINEASM) {
19963ca95b02SDimitry Andric     const MachineFunction *MF = MI.getParent()->getParent();
19973ca95b02SDimitry Andric     const char *AsmStr = MI.getOperand(0).getSymbolName();
1998f22ef01cSRoman Divacky     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
199939d628a0SDimitry Andric   } else if (Opcode == TargetOpcode::STACKMAP) {
2000d88c1a5aSDimitry Andric     StackMapOpers Opers(&MI);
2001d88c1a5aSDimitry Andric     return Opers.getNumPatchBytes();
200239d628a0SDimitry Andric   } else if (Opcode == TargetOpcode::PATCHPOINT) {
20033ca95b02SDimitry Andric     PatchPointOpers Opers(&MI);
2004d88c1a5aSDimitry Andric     return Opers.getNumPatchBytes();
200591bc56edSDimitry Andric   } else {
20067a7e6055SDimitry Andric     return get(Opcode).getSize();
2007f22ef01cSRoman Divacky   }
2008f22ef01cSRoman Divacky }
2009284c1978SDimitry Andric 
20107d523365SDimitry Andric std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const20117d523365SDimitry Andric PPCInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
20127d523365SDimitry Andric   const unsigned Mask = PPCII::MO_ACCESS_MASK;
20137d523365SDimitry Andric   return std::make_pair(TF & Mask, TF & ~Mask);
20147d523365SDimitry Andric }
20157d523365SDimitry Andric 
20167d523365SDimitry Andric ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const20177d523365SDimitry Andric PPCInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
20187d523365SDimitry Andric   using namespace PPCII;
20197d523365SDimitry Andric   static const std::pair<unsigned, const char *> TargetFlags[] = {
20207d523365SDimitry Andric       {MO_LO, "ppc-lo"},
20217d523365SDimitry Andric       {MO_HA, "ppc-ha"},
20227d523365SDimitry Andric       {MO_TPREL_LO, "ppc-tprel-lo"},
20237d523365SDimitry Andric       {MO_TPREL_HA, "ppc-tprel-ha"},
20247d523365SDimitry Andric       {MO_DTPREL_LO, "ppc-dtprel-lo"},
20257d523365SDimitry Andric       {MO_TLSLD_LO, "ppc-tlsld-lo"},
20267d523365SDimitry Andric       {MO_TOC_LO, "ppc-toc-lo"},
20277d523365SDimitry Andric       {MO_TLS, "ppc-tls"}};
20287d523365SDimitry Andric   return makeArrayRef(TargetFlags);
20297d523365SDimitry Andric }
20307d523365SDimitry Andric 
20317d523365SDimitry Andric ArrayRef<std::pair<unsigned, const char *>>
getSerializableBitmaskMachineOperandTargetFlags() const20327d523365SDimitry Andric PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
20337d523365SDimitry Andric   using namespace PPCII;
20347d523365SDimitry Andric   static const std::pair<unsigned, const char *> TargetFlags[] = {
20353ca95b02SDimitry Andric       {MO_PLT, "ppc-plt"},
20367d523365SDimitry Andric       {MO_PIC_FLAG, "ppc-pic"},
20377d523365SDimitry Andric       {MO_NLP_FLAG, "ppc-nlp"},
20387d523365SDimitry Andric       {MO_NLP_HIDDEN_FLAG, "ppc-nlp-hidden"}};
20397d523365SDimitry Andric   return makeArrayRef(TargetFlags);
20407d523365SDimitry Andric }
20417d523365SDimitry Andric 
20422cab237bSDimitry Andric // Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction.
20432cab237bSDimitry Andric // The VSX versions have the advantage of a full 64-register target whereas
20442cab237bSDimitry Andric // the FP ones have the advantage of lower latency and higher throughput. So
20452cab237bSDimitry Andric // what we are after is using the faster instructions in low register pressure
20462cab237bSDimitry Andric // situations and using the larger register file in high register pressure
20472cab237bSDimitry Andric // situations.
expandVSXMemPseudo(MachineInstr & MI) const20482cab237bSDimitry Andric bool PPCInstrInfo::expandVSXMemPseudo(MachineInstr &MI) const {
2049d88c1a5aSDimitry Andric     unsigned UpperOpcode, LowerOpcode;
2050d88c1a5aSDimitry Andric     switch (MI.getOpcode()) {
2051d88c1a5aSDimitry Andric     case PPC::DFLOADf32:
2052d88c1a5aSDimitry Andric       UpperOpcode = PPC::LXSSP;
2053d88c1a5aSDimitry Andric       LowerOpcode = PPC::LFS;
2054d88c1a5aSDimitry Andric       break;
2055d88c1a5aSDimitry Andric     case PPC::DFLOADf64:
2056d88c1a5aSDimitry Andric       UpperOpcode = PPC::LXSD;
2057d88c1a5aSDimitry Andric       LowerOpcode = PPC::LFD;
2058d88c1a5aSDimitry Andric       break;
2059d88c1a5aSDimitry Andric     case PPC::DFSTOREf32:
2060d88c1a5aSDimitry Andric       UpperOpcode = PPC::STXSSP;
2061d88c1a5aSDimitry Andric       LowerOpcode = PPC::STFS;
2062d88c1a5aSDimitry Andric       break;
2063d88c1a5aSDimitry Andric     case PPC::DFSTOREf64:
2064d88c1a5aSDimitry Andric       UpperOpcode = PPC::STXSD;
2065d88c1a5aSDimitry Andric       LowerOpcode = PPC::STFD;
2066d88c1a5aSDimitry Andric       break;
20672cab237bSDimitry Andric     case PPC::XFLOADf32:
20682cab237bSDimitry Andric       UpperOpcode = PPC::LXSSPX;
20692cab237bSDimitry Andric       LowerOpcode = PPC::LFSX;
20702cab237bSDimitry Andric       break;
20712cab237bSDimitry Andric     case PPC::XFLOADf64:
20722cab237bSDimitry Andric       UpperOpcode = PPC::LXSDX;
20732cab237bSDimitry Andric       LowerOpcode = PPC::LFDX;
20742cab237bSDimitry Andric       break;
20752cab237bSDimitry Andric     case PPC::XFSTOREf32:
20762cab237bSDimitry Andric       UpperOpcode = PPC::STXSSPX;
20772cab237bSDimitry Andric       LowerOpcode = PPC::STFSX;
20782cab237bSDimitry Andric       break;
20792cab237bSDimitry Andric     case PPC::XFSTOREf64:
20802cab237bSDimitry Andric       UpperOpcode = PPC::STXSDX;
20812cab237bSDimitry Andric       LowerOpcode = PPC::STFDX;
20822cab237bSDimitry Andric       break;
20832cab237bSDimitry Andric     case PPC::LIWAX:
20842cab237bSDimitry Andric       UpperOpcode = PPC::LXSIWAX;
20852cab237bSDimitry Andric       LowerOpcode = PPC::LFIWAX;
20862cab237bSDimitry Andric       break;
20872cab237bSDimitry Andric     case PPC::LIWZX:
20882cab237bSDimitry Andric       UpperOpcode = PPC::LXSIWZX;
20892cab237bSDimitry Andric       LowerOpcode = PPC::LFIWZX;
20902cab237bSDimitry Andric       break;
20912cab237bSDimitry Andric     case PPC::STIWX:
20922cab237bSDimitry Andric       UpperOpcode = PPC::STXSIWX;
20932cab237bSDimitry Andric       LowerOpcode = PPC::STFIWX;
20942cab237bSDimitry Andric       break;
20952cab237bSDimitry Andric     default:
20962cab237bSDimitry Andric       llvm_unreachable("Unknown Operation!");
2097d88c1a5aSDimitry Andric     }
20982cab237bSDimitry Andric 
2099d88c1a5aSDimitry Andric     unsigned TargetReg = MI.getOperand(0).getReg();
2100d88c1a5aSDimitry Andric     unsigned Opcode;
2101d88c1a5aSDimitry Andric     if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
2102d88c1a5aSDimitry Andric         (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
2103d88c1a5aSDimitry Andric       Opcode = LowerOpcode;
2104d88c1a5aSDimitry Andric     else
2105d88c1a5aSDimitry Andric       Opcode = UpperOpcode;
2106d88c1a5aSDimitry Andric     MI.setDesc(get(Opcode));
2107d88c1a5aSDimitry Andric     return true;
2108d88c1a5aSDimitry Andric }
21092cab237bSDimitry Andric 
isAnImmediateOperand(const MachineOperand & MO)21104ba319b5SDimitry Andric static bool isAnImmediateOperand(const MachineOperand &MO) {
21114ba319b5SDimitry Andric   return MO.isCPI() || MO.isGlobal() || MO.isImm();
21124ba319b5SDimitry Andric }
21134ba319b5SDimitry Andric 
expandPostRAPseudo(MachineInstr & MI) const21142cab237bSDimitry Andric bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
21152cab237bSDimitry Andric   auto &MBB = *MI.getParent();
21162cab237bSDimitry Andric   auto DL = MI.getDebugLoc();
21172cab237bSDimitry Andric 
21182cab237bSDimitry Andric   switch (MI.getOpcode()) {
21192cab237bSDimitry Andric   case TargetOpcode::LOAD_STACK_GUARD: {
21202cab237bSDimitry Andric     assert(Subtarget.isTargetLinux() &&
21212cab237bSDimitry Andric            "Only Linux target is expected to contain LOAD_STACK_GUARD");
21222cab237bSDimitry Andric     const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
21232cab237bSDimitry Andric     const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
21242cab237bSDimitry Andric     MI.setDesc(get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
21252cab237bSDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
21262cab237bSDimitry Andric         .addImm(Offset)
21272cab237bSDimitry Andric         .addReg(Reg);
21282cab237bSDimitry Andric     return true;
21292cab237bSDimitry Andric   }
21302cab237bSDimitry Andric   case PPC::DFLOADf32:
21312cab237bSDimitry Andric   case PPC::DFLOADf64:
21322cab237bSDimitry Andric   case PPC::DFSTOREf32:
21332cab237bSDimitry Andric   case PPC::DFSTOREf64: {
21342cab237bSDimitry Andric     assert(Subtarget.hasP9Vector() &&
21352cab237bSDimitry Andric            "Invalid D-Form Pseudo-ops on Pre-P9 target.");
21364ba319b5SDimitry Andric     assert(MI.getOperand(2).isReg() &&
21374ba319b5SDimitry Andric            isAnImmediateOperand(MI.getOperand(1)) &&
21382cab237bSDimitry Andric            "D-form op must have register and immediate operands");
21392cab237bSDimitry Andric     return expandVSXMemPseudo(MI);
21402cab237bSDimitry Andric   }
21412cab237bSDimitry Andric   case PPC::XFLOADf32:
21422cab237bSDimitry Andric   case PPC::XFSTOREf32:
21432cab237bSDimitry Andric   case PPC::LIWAX:
21442cab237bSDimitry Andric   case PPC::LIWZX:
21452cab237bSDimitry Andric   case PPC::STIWX: {
21462cab237bSDimitry Andric     assert(Subtarget.hasP8Vector() &&
21472cab237bSDimitry Andric            "Invalid X-Form Pseudo-ops on Pre-P8 target.");
21482cab237bSDimitry Andric     assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
21492cab237bSDimitry Andric            "X-form op must have register and register operands");
21502cab237bSDimitry Andric     return expandVSXMemPseudo(MI);
21512cab237bSDimitry Andric   }
21522cab237bSDimitry Andric   case PPC::XFLOADf64:
21532cab237bSDimitry Andric   case PPC::XFSTOREf64: {
21542cab237bSDimitry Andric     assert(Subtarget.hasVSX() &&
21552cab237bSDimitry Andric            "Invalid X-Form Pseudo-ops on target that has no VSX.");
21562cab237bSDimitry Andric     assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
21572cab237bSDimitry Andric            "X-form op must have register and register operands");
21582cab237bSDimitry Andric     return expandVSXMemPseudo(MI);
21592cab237bSDimitry Andric   }
21602cab237bSDimitry Andric   case PPC::SPILLTOVSR_LD: {
21612cab237bSDimitry Andric     unsigned TargetReg = MI.getOperand(0).getReg();
21622cab237bSDimitry Andric     if (PPC::VSFRCRegClass.contains(TargetReg)) {
21632cab237bSDimitry Andric       MI.setDesc(get(PPC::DFLOADf64));
21642cab237bSDimitry Andric       return expandPostRAPseudo(MI);
21652cab237bSDimitry Andric     }
21662cab237bSDimitry Andric     else
21672cab237bSDimitry Andric       MI.setDesc(get(PPC::LD));
21682cab237bSDimitry Andric     return true;
21692cab237bSDimitry Andric   }
21702cab237bSDimitry Andric   case PPC::SPILLTOVSR_ST: {
21712cab237bSDimitry Andric     unsigned SrcReg = MI.getOperand(0).getReg();
21722cab237bSDimitry Andric     if (PPC::VSFRCRegClass.contains(SrcReg)) {
21732cab237bSDimitry Andric       NumStoreSPILLVSRRCAsVec++;
21742cab237bSDimitry Andric       MI.setDesc(get(PPC::DFSTOREf64));
21752cab237bSDimitry Andric       return expandPostRAPseudo(MI);
21762cab237bSDimitry Andric     } else {
21772cab237bSDimitry Andric       NumStoreSPILLVSRRCAsGpr++;
21782cab237bSDimitry Andric       MI.setDesc(get(PPC::STD));
21792cab237bSDimitry Andric     }
21802cab237bSDimitry Andric     return true;
21812cab237bSDimitry Andric   }
21822cab237bSDimitry Andric   case PPC::SPILLTOVSR_LDX: {
21832cab237bSDimitry Andric     unsigned TargetReg = MI.getOperand(0).getReg();
21842cab237bSDimitry Andric     if (PPC::VSFRCRegClass.contains(TargetReg))
21852cab237bSDimitry Andric       MI.setDesc(get(PPC::LXSDX));
21862cab237bSDimitry Andric     else
21872cab237bSDimitry Andric       MI.setDesc(get(PPC::LDX));
21882cab237bSDimitry Andric     return true;
21892cab237bSDimitry Andric   }
21902cab237bSDimitry Andric   case PPC::SPILLTOVSR_STX: {
21912cab237bSDimitry Andric     unsigned SrcReg = MI.getOperand(0).getReg();
21922cab237bSDimitry Andric     if (PPC::VSFRCRegClass.contains(SrcReg)) {
21932cab237bSDimitry Andric       NumStoreSPILLVSRRCAsVec++;
21942cab237bSDimitry Andric       MI.setDesc(get(PPC::STXSDX));
21952cab237bSDimitry Andric     } else {
21962cab237bSDimitry Andric       NumStoreSPILLVSRRCAsGpr++;
21972cab237bSDimitry Andric       MI.setDesc(get(PPC::STDX));
21982cab237bSDimitry Andric     }
21992cab237bSDimitry Andric     return true;
22002cab237bSDimitry Andric   }
22012cab237bSDimitry Andric 
220260ff8e32SDimitry Andric   case PPC::CFENCE8: {
220360ff8e32SDimitry Andric     auto Val = MI.getOperand(0).getReg();
220424d58133SDimitry Andric     BuildMI(MBB, MI, DL, get(PPC::CMPD), PPC::CR7).addReg(Val).addReg(Val);
220560ff8e32SDimitry Andric     BuildMI(MBB, MI, DL, get(PPC::CTRL_DEP))
220660ff8e32SDimitry Andric         .addImm(PPC::PRED_NE_MINUS)
220760ff8e32SDimitry Andric         .addReg(PPC::CR7)
220860ff8e32SDimitry Andric         .addImm(1);
220960ff8e32SDimitry Andric     MI.setDesc(get(PPC::ISYNC));
221060ff8e32SDimitry Andric     MI.RemoveOperand(0);
221160ff8e32SDimitry Andric     return true;
221260ff8e32SDimitry Andric   }
22133ca95b02SDimitry Andric   }
22143ca95b02SDimitry Andric   return false;
22153ca95b02SDimitry Andric }
2216d88c1a5aSDimitry Andric 
22172cab237bSDimitry Andric // Essentially a compile-time implementation of a compare->isel sequence.
22182cab237bSDimitry Andric // It takes two constants to compare, along with the true/false registers
22192cab237bSDimitry Andric // and the comparison type (as a subreg to a CR field) and returns one
22202cab237bSDimitry Andric // of the true/false registers, depending on the comparison results.
selectReg(int64_t Imm1,int64_t Imm2,unsigned CompareOpc,unsigned TrueReg,unsigned FalseReg,unsigned CRSubReg)22212cab237bSDimitry Andric static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
22222cab237bSDimitry Andric                           unsigned TrueReg, unsigned FalseReg,
22232cab237bSDimitry Andric                           unsigned CRSubReg) {
22242cab237bSDimitry Andric   // Signed comparisons. The immediates are assumed to be sign-extended.
22252cab237bSDimitry Andric   if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
22262cab237bSDimitry Andric     switch (CRSubReg) {
22272cab237bSDimitry Andric     default: llvm_unreachable("Unknown integer comparison type.");
22282cab237bSDimitry Andric     case PPC::sub_lt:
22292cab237bSDimitry Andric       return Imm1 < Imm2 ? TrueReg : FalseReg;
22302cab237bSDimitry Andric     case PPC::sub_gt:
22312cab237bSDimitry Andric       return Imm1 > Imm2 ? TrueReg : FalseReg;
22322cab237bSDimitry Andric     case PPC::sub_eq:
22332cab237bSDimitry Andric       return Imm1 == Imm2 ? TrueReg : FalseReg;
22342cab237bSDimitry Andric     }
22352cab237bSDimitry Andric   }
22362cab237bSDimitry Andric   // Unsigned comparisons.
22372cab237bSDimitry Andric   else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
22382cab237bSDimitry Andric     switch (CRSubReg) {
22392cab237bSDimitry Andric     default: llvm_unreachable("Unknown integer comparison type.");
22402cab237bSDimitry Andric     case PPC::sub_lt:
22412cab237bSDimitry Andric       return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
22422cab237bSDimitry Andric     case PPC::sub_gt:
22432cab237bSDimitry Andric       return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
22442cab237bSDimitry Andric     case PPC::sub_eq:
22452cab237bSDimitry Andric       return Imm1 == Imm2 ? TrueReg : FalseReg;
22462cab237bSDimitry Andric     }
22472cab237bSDimitry Andric   }
22482cab237bSDimitry Andric   return PPC::NoRegister;
22492cab237bSDimitry Andric }
22502cab237bSDimitry Andric 
replaceInstrOperandWithImm(MachineInstr & MI,unsigned OpNo,int64_t Imm) const2251*b5893f02SDimitry Andric void PPCInstrInfo::replaceInstrOperandWithImm(MachineInstr &MI,
2252*b5893f02SDimitry Andric                                               unsigned OpNo,
2253*b5893f02SDimitry Andric                                               int64_t Imm) const {
2254*b5893f02SDimitry Andric   assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");
2255*b5893f02SDimitry Andric   // Replace the REG with the Immediate.
2256*b5893f02SDimitry Andric   unsigned InUseReg = MI.getOperand(OpNo).getReg();
2257*b5893f02SDimitry Andric   MI.getOperand(OpNo).ChangeToImmediate(Imm);
2258*b5893f02SDimitry Andric 
2259*b5893f02SDimitry Andric   if (empty(MI.implicit_operands()))
2260*b5893f02SDimitry Andric     return;
2261*b5893f02SDimitry Andric 
2262*b5893f02SDimitry Andric   // We need to make sure that the MI didn't have any implicit use
2263*b5893f02SDimitry Andric   // of this REG any more.
2264*b5893f02SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
2265*b5893f02SDimitry Andric   int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, false, TRI);
2266*b5893f02SDimitry Andric   if (UseOpIdx >= 0) {
2267*b5893f02SDimitry Andric     MachineOperand &MO = MI.getOperand(UseOpIdx);
2268*b5893f02SDimitry Andric     if (MO.isImplicit())
2269*b5893f02SDimitry Andric       // The operands must always be in the following order:
2270*b5893f02SDimitry Andric       // - explicit reg defs,
2271*b5893f02SDimitry Andric       // - other explicit operands (reg uses, immediates, etc.),
2272*b5893f02SDimitry Andric       // - implicit reg defs
2273*b5893f02SDimitry Andric       // - implicit reg uses
2274*b5893f02SDimitry Andric       // Therefore, removing the implicit operand won't change the explicit
2275*b5893f02SDimitry Andric       // operands layout.
2276*b5893f02SDimitry Andric       MI.RemoveOperand(UseOpIdx);
2277*b5893f02SDimitry Andric   }
2278*b5893f02SDimitry Andric }
2279*b5893f02SDimitry Andric 
22802cab237bSDimitry Andric // Replace an instruction with one that materializes a constant (and sets
22812cab237bSDimitry Andric // CR0 if the original instruction was a record-form instruction).
replaceInstrWithLI(MachineInstr & MI,const LoadImmediateInfo & LII) const22822cab237bSDimitry Andric void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI,
22832cab237bSDimitry Andric                                       const LoadImmediateInfo &LII) const {
22842cab237bSDimitry Andric   // Remove existing operands.
22852cab237bSDimitry Andric   int OperandToKeep = LII.SetCR ? 1 : 0;
22862cab237bSDimitry Andric   for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
22872cab237bSDimitry Andric     MI.RemoveOperand(i);
22882cab237bSDimitry Andric 
22892cab237bSDimitry Andric   // Replace the instruction.
22902cab237bSDimitry Andric   if (LII.SetCR) {
22912cab237bSDimitry Andric     MI.setDesc(get(LII.Is64Bit ? PPC::ANDIo8 : PPC::ANDIo));
22922cab237bSDimitry Andric     // Set the immediate.
22932cab237bSDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
22942cab237bSDimitry Andric         .addImm(LII.Imm).addReg(PPC::CR0, RegState::ImplicitDefine);
22952cab237bSDimitry Andric     return;
22962cab237bSDimitry Andric   }
22972cab237bSDimitry Andric   else
22982cab237bSDimitry Andric     MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));
22992cab237bSDimitry Andric 
23002cab237bSDimitry Andric   // Set the immediate.
23012cab237bSDimitry Andric   MachineInstrBuilder(*MI.getParent()->getParent(), MI)
23022cab237bSDimitry Andric       .addImm(LII.Imm);
23032cab237bSDimitry Andric }
23042cab237bSDimitry Andric 
getForwardingDefMI(MachineInstr & MI,unsigned & OpNoForForwarding,bool & SeenIntermediateUse) const2305*b5893f02SDimitry Andric MachineInstr *PPCInstrInfo::getForwardingDefMI(
2306*b5893f02SDimitry Andric   MachineInstr &MI,
2307*b5893f02SDimitry Andric   unsigned &OpNoForForwarding,
23082cab237bSDimitry Andric   bool &SeenIntermediateUse) const {
2309*b5893f02SDimitry Andric   OpNoForForwarding = ~0U;
23102cab237bSDimitry Andric   MachineInstr *DefMI = nullptr;
23112cab237bSDimitry Andric   MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
23124ba319b5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
23134ba319b5SDimitry Andric   // If we're in SSA, get the defs through the MRI. Otherwise, only look
23142cab237bSDimitry Andric   // within the basic block to see if the register is defined using an LI/LI8.
23152cab237bSDimitry Andric   if (MRI->isSSA()) {
23162cab237bSDimitry Andric     for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
23172cab237bSDimitry Andric       if (!MI.getOperand(i).isReg())
23182cab237bSDimitry Andric         continue;
23192cab237bSDimitry Andric       unsigned Reg = MI.getOperand(i).getReg();
23202cab237bSDimitry Andric       if (!TargetRegisterInfo::isVirtualRegister(Reg))
23212cab237bSDimitry Andric         continue;
23224ba319b5SDimitry Andric       unsigned TrueReg = TRI->lookThruCopyLike(Reg, MRI);
23232cab237bSDimitry Andric       if (TargetRegisterInfo::isVirtualRegister(TrueReg)) {
23242cab237bSDimitry Andric         DefMI = MRI->getVRegDef(TrueReg);
23252cab237bSDimitry Andric         if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8) {
2326*b5893f02SDimitry Andric           OpNoForForwarding = i;
23272cab237bSDimitry Andric           break;
23282cab237bSDimitry Andric         }
23292cab237bSDimitry Andric       }
23302cab237bSDimitry Andric     }
23312cab237bSDimitry Andric   } else {
23322cab237bSDimitry Andric     // Looking back through the definition for each operand could be expensive,
23332cab237bSDimitry Andric     // so exit early if this isn't an instruction that either has an immediate
23342cab237bSDimitry Andric     // form or is already an immediate form that we can handle.
23352cab237bSDimitry Andric     ImmInstrInfo III;
23362cab237bSDimitry Andric     unsigned Opc = MI.getOpcode();
23372cab237bSDimitry Andric     bool ConvertibleImmForm =
23382cab237bSDimitry Andric       Opc == PPC::CMPWI || Opc == PPC::CMPLWI ||
23392cab237bSDimitry Andric       Opc == PPC::CMPDI || Opc == PPC::CMPLDI ||
23402cab237bSDimitry Andric       Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
23412cab237bSDimitry Andric       Opc == PPC::ORI || Opc == PPC::ORI8 ||
23422cab237bSDimitry Andric       Opc == PPC::XORI || Opc == PPC::XORI8 ||
23432cab237bSDimitry Andric       Opc == PPC::RLDICL || Opc == PPC::RLDICLo ||
23442cab237bSDimitry Andric       Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
23452cab237bSDimitry Andric       Opc == PPC::RLWINM || Opc == PPC::RLWINMo ||
23462cab237bSDimitry Andric       Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
2347*b5893f02SDimitry Andric     if (!instrHasImmForm(MI, III, true) && !ConvertibleImmForm)
23482cab237bSDimitry Andric       return nullptr;
23492cab237bSDimitry Andric 
23502cab237bSDimitry Andric     // Don't convert or %X, %Y, %Y since that's just a register move.
23512cab237bSDimitry Andric     if ((Opc == PPC::OR || Opc == PPC::OR8) &&
23522cab237bSDimitry Andric         MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
23532cab237bSDimitry Andric       return nullptr;
23542cab237bSDimitry Andric     for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
23552cab237bSDimitry Andric       MachineOperand &MO = MI.getOperand(i);
23562cab237bSDimitry Andric       SeenIntermediateUse = false;
23572cab237bSDimitry Andric       if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {
23582cab237bSDimitry Andric         MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI;
23592cab237bSDimitry Andric         It++;
23602cab237bSDimitry Andric         unsigned Reg = MI.getOperand(i).getReg();
23612cab237bSDimitry Andric         // MachineInstr::readsRegister only returns true if the machine
23622cab237bSDimitry Andric         // instruction reads the exact register or its super-register. It
23632cab237bSDimitry Andric         // does not consider uses of sub-registers which seems like strange
23642cab237bSDimitry Andric         // behaviour. Nonetheless, if we end up with a 64-bit register here,
23652cab237bSDimitry Andric         // get the corresponding 32-bit register to check.
23662cab237bSDimitry Andric         if (PPC::G8RCRegClass.contains(Reg))
23672cab237bSDimitry Andric           Reg = Reg - PPC::X0 + PPC::R0;
23682cab237bSDimitry Andric 
2369*b5893f02SDimitry Andric         // Is this register defined by some form of add-immediate (including
2370*b5893f02SDimitry Andric         // load-immediate) within this basic block?
23712cab237bSDimitry Andric         for ( ; It != E; ++It) {
23722cab237bSDimitry Andric           if (It->modifiesRegister(Reg, &getRegisterInfo())) {
2373*b5893f02SDimitry Andric             switch (It->getOpcode()) {
2374*b5893f02SDimitry Andric             default: break;
2375*b5893f02SDimitry Andric             case PPC::LI:
2376*b5893f02SDimitry Andric             case PPC::LI8:
2377*b5893f02SDimitry Andric             case PPC::ADDItocL:
2378*b5893f02SDimitry Andric             case PPC::ADDI:
2379*b5893f02SDimitry Andric             case PPC::ADDI8:
2380*b5893f02SDimitry Andric               OpNoForForwarding = i;
23812cab237bSDimitry Andric               return &*It;
2382*b5893f02SDimitry Andric             }
23832cab237bSDimitry Andric             break;
23842cab237bSDimitry Andric           } else if (It->readsRegister(Reg, &getRegisterInfo()))
23852cab237bSDimitry Andric             // If we see another use of this reg between the def and the MI,
23862cab237bSDimitry Andric             // we want to flat it so the def isn't deleted.
23872cab237bSDimitry Andric             SeenIntermediateUse = true;
23882cab237bSDimitry Andric         }
23892cab237bSDimitry Andric       }
23902cab237bSDimitry Andric     }
23912cab237bSDimitry Andric   }
2392*b5893f02SDimitry Andric   return OpNoForForwarding == ~0U ? nullptr : DefMI;
23932cab237bSDimitry Andric }
23942cab237bSDimitry Andric 
getStoreOpcodesForSpillArray() const23954ba319b5SDimitry Andric const unsigned *PPCInstrInfo::getStoreOpcodesForSpillArray() const {
23964ba319b5SDimitry Andric   static const unsigned OpcodesForSpill[2][SOK_LastOpcodeSpill] = {
23974ba319b5SDimitry Andric       // Power 8
23984ba319b5SDimitry Andric       {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR,
23994ba319b5SDimitry Andric        PPC::SPILL_CRBIT, PPC::STVX, PPC::STXVD2X, PPC::STXSDX, PPC::STXSSPX,
24004ba319b5SDimitry Andric        PPC::SPILL_VRSAVE, PPC::QVSTFDX, PPC::QVSTFSXs, PPC::QVSTFDXb,
24014ba319b5SDimitry Andric        PPC::SPILLTOVSR_ST, PPC::EVSTDD, PPC::SPESTW},
24024ba319b5SDimitry Andric       // Power 9
24034ba319b5SDimitry Andric       {PPC::STW, PPC::STD, PPC::STFD, PPC::STFS, PPC::SPILL_CR,
24044ba319b5SDimitry Andric        PPC::SPILL_CRBIT, PPC::STVX, PPC::STXV, PPC::DFSTOREf64, PPC::DFSTOREf32,
24054ba319b5SDimitry Andric        PPC::SPILL_VRSAVE, PPC::QVSTFDX, PPC::QVSTFSXs, PPC::QVSTFDXb,
24064ba319b5SDimitry Andric        PPC::SPILLTOVSR_ST}};
24074ba319b5SDimitry Andric 
24084ba319b5SDimitry Andric   return OpcodesForSpill[(Subtarget.hasP9Vector()) ? 1 : 0];
24094ba319b5SDimitry Andric }
24104ba319b5SDimitry Andric 
getLoadOpcodesForSpillArray() const24114ba319b5SDimitry Andric const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const {
24124ba319b5SDimitry Andric   static const unsigned OpcodesForSpill[2][SOK_LastOpcodeSpill] = {
24134ba319b5SDimitry Andric       // Power 8
24144ba319b5SDimitry Andric       {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR,
24154ba319b5SDimitry Andric        PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXVD2X, PPC::LXSDX, PPC::LXSSPX,
24164ba319b5SDimitry Andric        PPC::RESTORE_VRSAVE, PPC::QVLFDX, PPC::QVLFSXs, PPC::QVLFDXb,
24174ba319b5SDimitry Andric        PPC::SPILLTOVSR_LD, PPC::EVLDD, PPC::SPELWZ},
24184ba319b5SDimitry Andric       // Power 9
24194ba319b5SDimitry Andric       {PPC::LWZ, PPC::LD, PPC::LFD, PPC::LFS, PPC::RESTORE_CR,
24204ba319b5SDimitry Andric        PPC::RESTORE_CRBIT, PPC::LVX, PPC::LXV, PPC::DFLOADf64, PPC::DFLOADf32,
24214ba319b5SDimitry Andric        PPC::RESTORE_VRSAVE, PPC::QVLFDX, PPC::QVLFSXs, PPC::QVLFDXb,
24224ba319b5SDimitry Andric        PPC::SPILLTOVSR_LD}};
24234ba319b5SDimitry Andric 
24244ba319b5SDimitry Andric   return OpcodesForSpill[(Subtarget.hasP9Vector()) ? 1 : 0];
24254ba319b5SDimitry Andric }
24264ba319b5SDimitry Andric 
24272cab237bSDimitry Andric // If this instruction has an immediate form and one of its operands is a
2428*b5893f02SDimitry Andric // result of a load-immediate or an add-immediate, convert it to
2429*b5893f02SDimitry Andric // the immediate form if the constant is in range.
convertToImmediateForm(MachineInstr & MI,MachineInstr ** KilledDef) const24302cab237bSDimitry Andric bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
24312cab237bSDimitry Andric                                           MachineInstr **KilledDef) const {
24322cab237bSDimitry Andric   MachineFunction *MF = MI.getParent()->getParent();
24332cab237bSDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
24342cab237bSDimitry Andric   bool PostRA = !MRI->isSSA();
24352cab237bSDimitry Andric   bool SeenIntermediateUse = true;
2436*b5893f02SDimitry Andric   unsigned ForwardingOperand = ~0U;
2437*b5893f02SDimitry Andric   MachineInstr *DefMI = getForwardingDefMI(MI, ForwardingOperand,
24382cab237bSDimitry Andric                                            SeenIntermediateUse);
2439*b5893f02SDimitry Andric   if (!DefMI)
24402cab237bSDimitry Andric     return false;
2441*b5893f02SDimitry Andric   assert(ForwardingOperand < MI.getNumOperands() &&
2442*b5893f02SDimitry Andric          "The forwarding operand needs to be valid at this point");
2443*b5893f02SDimitry Andric   bool KillFwdDefMI = !SeenIntermediateUse &&
2444*b5893f02SDimitry Andric     MI.getOperand(ForwardingOperand).isKill();
2445*b5893f02SDimitry Andric   if (KilledDef && KillFwdDefMI)
2446*b5893f02SDimitry Andric     *KilledDef = DefMI;
2447*b5893f02SDimitry Andric 
2448*b5893f02SDimitry Andric   ImmInstrInfo III;
2449*b5893f02SDimitry Andric   bool HasImmForm = instrHasImmForm(MI, III, PostRA);
2450*b5893f02SDimitry Andric   // If this is a reg+reg instruction that has a reg+imm form,
2451*b5893f02SDimitry Andric   // and one of the operands is produced by an add-immediate,
2452*b5893f02SDimitry Andric   // try to convert it.
2453*b5893f02SDimitry Andric   if (HasImmForm && transformToImmFormFedByAdd(MI, III, ForwardingOperand,
2454*b5893f02SDimitry Andric                                                *DefMI, KillFwdDefMI))
2455*b5893f02SDimitry Andric     return true;
2456*b5893f02SDimitry Andric 
2457*b5893f02SDimitry Andric   if ((DefMI->getOpcode() != PPC::LI && DefMI->getOpcode() != PPC::LI8) ||
2458*b5893f02SDimitry Andric       !DefMI->getOperand(1).isImm())
2459*b5893f02SDimitry Andric     return false;
24602cab237bSDimitry Andric 
24612cab237bSDimitry Andric   int64_t Immediate = DefMI->getOperand(1).getImm();
24622cab237bSDimitry Andric   // Sign-extend to 64-bits.
24632cab237bSDimitry Andric   int64_t SExtImm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?
24642cab237bSDimitry Andric     (Immediate | 0xFFFFFFFFFFFF0000) : Immediate;
24652cab237bSDimitry Andric 
2466*b5893f02SDimitry Andric   // If this is a reg+reg instruction that has a reg+imm form,
2467*b5893f02SDimitry Andric   // and one of the operands is produced by LI, convert it now.
2468*b5893f02SDimitry Andric   if (HasImmForm)
2469*b5893f02SDimitry Andric     return transformToImmFormFedByLI(MI, III, ForwardingOperand, SExtImm);
24702cab237bSDimitry Andric 
24712cab237bSDimitry Andric   bool ReplaceWithLI = false;
24722cab237bSDimitry Andric   bool Is64BitLI = false;
24732cab237bSDimitry Andric   int64_t NewImm = 0;
24742cab237bSDimitry Andric   bool SetCR = false;
24752cab237bSDimitry Andric   unsigned Opc = MI.getOpcode();
24762cab237bSDimitry Andric   switch (Opc) {
24772cab237bSDimitry Andric   default: return false;
24782cab237bSDimitry Andric 
24792cab237bSDimitry Andric   // FIXME: Any branches conditional on such a comparison can be made
24802cab237bSDimitry Andric   // unconditional. At this time, this happens too infrequently to be worth
24812cab237bSDimitry Andric   // the implementation effort, but if that ever changes, we could convert
24822cab237bSDimitry Andric   // such a pattern here.
24832cab237bSDimitry Andric   case PPC::CMPWI:
24842cab237bSDimitry Andric   case PPC::CMPLWI:
24852cab237bSDimitry Andric   case PPC::CMPDI:
24862cab237bSDimitry Andric   case PPC::CMPLDI: {
24872cab237bSDimitry Andric     // Doing this post-RA would require dataflow analysis to reliably find uses
24882cab237bSDimitry Andric     // of the CR register set by the compare.
24892cab237bSDimitry Andric     if (PostRA)
24902cab237bSDimitry Andric       return false;
24912cab237bSDimitry Andric     // If a compare-immediate is fed by an immediate and is itself an input of
24922cab237bSDimitry Andric     // an ISEL (the most common case) into a COPY of the correct register.
24932cab237bSDimitry Andric     bool Changed = false;
24942cab237bSDimitry Andric     unsigned DefReg = MI.getOperand(0).getReg();
24952cab237bSDimitry Andric     int64_t Comparand = MI.getOperand(2).getImm();
24962cab237bSDimitry Andric     int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0 ?
24972cab237bSDimitry Andric       (Comparand | 0xFFFFFFFFFFFF0000) : Comparand;
24982cab237bSDimitry Andric 
24992cab237bSDimitry Andric     for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
25002cab237bSDimitry Andric       unsigned UseOpc = CompareUseMI.getOpcode();
25012cab237bSDimitry Andric       if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
25022cab237bSDimitry Andric         continue;
25032cab237bSDimitry Andric       unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
25042cab237bSDimitry Andric       unsigned TrueReg = CompareUseMI.getOperand(1).getReg();
25052cab237bSDimitry Andric       unsigned FalseReg = CompareUseMI.getOperand(2).getReg();
25062cab237bSDimitry Andric       unsigned RegToCopy = selectReg(SExtImm, SExtComparand, Opc, TrueReg,
25072cab237bSDimitry Andric                                      FalseReg, CRSubReg);
25082cab237bSDimitry Andric       if (RegToCopy == PPC::NoRegister)
25092cab237bSDimitry Andric         continue;
25102cab237bSDimitry Andric       // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
25112cab237bSDimitry Andric       if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
25122cab237bSDimitry Andric         CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
2513*b5893f02SDimitry Andric         replaceInstrOperandWithImm(CompareUseMI, 1, 0);
25142cab237bSDimitry Andric         CompareUseMI.RemoveOperand(3);
25152cab237bSDimitry Andric         CompareUseMI.RemoveOperand(2);
25162cab237bSDimitry Andric         continue;
25172cab237bSDimitry Andric       }
25184ba319b5SDimitry Andric       LLVM_DEBUG(
25194ba319b5SDimitry Andric           dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
25204ba319b5SDimitry Andric       LLVM_DEBUG(DefMI->dump(); MI.dump(); CompareUseMI.dump());
25214ba319b5SDimitry Andric       LLVM_DEBUG(dbgs() << "Is converted to:\n");
25222cab237bSDimitry Andric       // Convert to copy and remove unneeded operands.
25232cab237bSDimitry Andric       CompareUseMI.setDesc(get(PPC::COPY));
25242cab237bSDimitry Andric       CompareUseMI.RemoveOperand(3);
25252cab237bSDimitry Andric       CompareUseMI.RemoveOperand(RegToCopy == TrueReg ? 2 : 1);
25262cab237bSDimitry Andric       CmpIselsConverted++;
25272cab237bSDimitry Andric       Changed = true;
25284ba319b5SDimitry Andric       LLVM_DEBUG(CompareUseMI.dump());
25292cab237bSDimitry Andric     }
25302cab237bSDimitry Andric     if (Changed)
25312cab237bSDimitry Andric       return true;
25322cab237bSDimitry Andric     // This may end up incremented multiple times since this function is called
25332cab237bSDimitry Andric     // during a fixed-point transformation, but it is only meant to indicate the
25342cab237bSDimitry Andric     // presence of this opportunity.
25352cab237bSDimitry Andric     MissedConvertibleImmediateInstrs++;
25362cab237bSDimitry Andric     return false;
25372cab237bSDimitry Andric   }
25382cab237bSDimitry Andric 
25392cab237bSDimitry Andric   // Immediate forms - may simply be convertable to an LI.
25402cab237bSDimitry Andric   case PPC::ADDI:
25412cab237bSDimitry Andric   case PPC::ADDI8: {
25422cab237bSDimitry Andric     // Does the sum fit in a 16-bit signed field?
25432cab237bSDimitry Andric     int64_t Addend = MI.getOperand(2).getImm();
25442cab237bSDimitry Andric     if (isInt<16>(Addend + SExtImm)) {
25452cab237bSDimitry Andric       ReplaceWithLI = true;
25462cab237bSDimitry Andric       Is64BitLI = Opc == PPC::ADDI8;
25472cab237bSDimitry Andric       NewImm = Addend + SExtImm;
25482cab237bSDimitry Andric       break;
25492cab237bSDimitry Andric     }
25502cab237bSDimitry Andric     return false;
25512cab237bSDimitry Andric   }
25522cab237bSDimitry Andric   case PPC::RLDICL:
25532cab237bSDimitry Andric   case PPC::RLDICLo:
25542cab237bSDimitry Andric   case PPC::RLDICL_32:
25552cab237bSDimitry Andric   case PPC::RLDICL_32_64: {
25562cab237bSDimitry Andric     // Use APInt's rotate function.
25572cab237bSDimitry Andric     int64_t SH = MI.getOperand(2).getImm();
25582cab237bSDimitry Andric     int64_t MB = MI.getOperand(3).getImm();
25596ccc06f6SDimitry Andric     APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICLo) ?
25606ccc06f6SDimitry Andric                 64 : 32, SExtImm, true);
25612cab237bSDimitry Andric     InVal = InVal.rotl(SH);
256230785c0eSDimitry Andric     uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
25632cab237bSDimitry Andric     InVal &= Mask;
25642cab237bSDimitry Andric     // Can't replace negative values with an LI as that will sign-extend
25652cab237bSDimitry Andric     // and not clear the left bits. If we're setting the CR bit, we will use
25662cab237bSDimitry Andric     // ANDIo which won't sign extend, so that's safe.
25672cab237bSDimitry Andric     if (isUInt<15>(InVal.getSExtValue()) ||
25682cab237bSDimitry Andric         (Opc == PPC::RLDICLo && isUInt<16>(InVal.getSExtValue()))) {
25692cab237bSDimitry Andric       ReplaceWithLI = true;
25702cab237bSDimitry Andric       Is64BitLI = Opc != PPC::RLDICL_32;
25712cab237bSDimitry Andric       NewImm = InVal.getSExtValue();
25722cab237bSDimitry Andric       SetCR = Opc == PPC::RLDICLo;
25732cab237bSDimitry Andric       break;
25742cab237bSDimitry Andric     }
25752cab237bSDimitry Andric     return false;
25762cab237bSDimitry Andric   }
25772cab237bSDimitry Andric   case PPC::RLWINM:
25782cab237bSDimitry Andric   case PPC::RLWINM8:
25792cab237bSDimitry Andric   case PPC::RLWINMo:
25802cab237bSDimitry Andric   case PPC::RLWINM8o: {
25812cab237bSDimitry Andric     int64_t SH = MI.getOperand(2).getImm();
25822cab237bSDimitry Andric     int64_t MB = MI.getOperand(3).getImm();
25832cab237bSDimitry Andric     int64_t ME = MI.getOperand(4).getImm();
25842cab237bSDimitry Andric     APInt InVal(32, SExtImm, true);
25852cab237bSDimitry Andric     InVal = InVal.rotl(SH);
25862cab237bSDimitry Andric     // Set the bits (        MB + 32        ) to (        ME + 32        ).
258730785c0eSDimitry Andric     uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
25882cab237bSDimitry Andric     InVal &= Mask;
25892cab237bSDimitry Andric     // Can't replace negative values with an LI as that will sign-extend
25902cab237bSDimitry Andric     // and not clear the left bits. If we're setting the CR bit, we will use
25912cab237bSDimitry Andric     // ANDIo which won't sign extend, so that's safe.
25922cab237bSDimitry Andric     bool ValueFits = isUInt<15>(InVal.getSExtValue());
25932cab237bSDimitry Andric     ValueFits |= ((Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o) &&
25942cab237bSDimitry Andric                   isUInt<16>(InVal.getSExtValue()));
25952cab237bSDimitry Andric     if (ValueFits) {
25962cab237bSDimitry Andric       ReplaceWithLI = true;
25972cab237bSDimitry Andric       Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
25982cab237bSDimitry Andric       NewImm = InVal.getSExtValue();
25992cab237bSDimitry Andric       SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;
26002cab237bSDimitry Andric       break;
26012cab237bSDimitry Andric     }
26022cab237bSDimitry Andric     return false;
26032cab237bSDimitry Andric   }
26042cab237bSDimitry Andric   case PPC::ORI:
26052cab237bSDimitry Andric   case PPC::ORI8:
26062cab237bSDimitry Andric   case PPC::XORI:
26072cab237bSDimitry Andric   case PPC::XORI8: {
26082cab237bSDimitry Andric     int64_t LogicalImm = MI.getOperand(2).getImm();
26092cab237bSDimitry Andric     int64_t Result = 0;
26102cab237bSDimitry Andric     if (Opc == PPC::ORI || Opc == PPC::ORI8)
26112cab237bSDimitry Andric       Result = LogicalImm | SExtImm;
26122cab237bSDimitry Andric     else
26132cab237bSDimitry Andric       Result = LogicalImm ^ SExtImm;
26142cab237bSDimitry Andric     if (isInt<16>(Result)) {
26152cab237bSDimitry Andric       ReplaceWithLI = true;
26162cab237bSDimitry Andric       Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
26172cab237bSDimitry Andric       NewImm = Result;
26182cab237bSDimitry Andric       break;
26192cab237bSDimitry Andric     }
26202cab237bSDimitry Andric     return false;
26212cab237bSDimitry Andric   }
26222cab237bSDimitry Andric   }
26232cab237bSDimitry Andric 
26242cab237bSDimitry Andric   if (ReplaceWithLI) {
26254ba319b5SDimitry Andric     // We need to be careful with CR-setting instructions we're replacing.
26264ba319b5SDimitry Andric     if (SetCR) {
26274ba319b5SDimitry Andric       // We don't know anything about uses when we're out of SSA, so only
26284ba319b5SDimitry Andric       // replace if the new immediate will be reproduced.
26294ba319b5SDimitry Andric       bool ImmChanged = (SExtImm & NewImm) != NewImm;
26304ba319b5SDimitry Andric       if (PostRA && ImmChanged)
26314ba319b5SDimitry Andric         return false;
26324ba319b5SDimitry Andric 
26334ba319b5SDimitry Andric       if (!PostRA) {
26344ba319b5SDimitry Andric         // If the defining load-immediate has no other uses, we can just replace
26354ba319b5SDimitry Andric         // the immediate with the new immediate.
26364ba319b5SDimitry Andric         if (MRI->hasOneUse(DefMI->getOperand(0).getReg()))
26374ba319b5SDimitry Andric           DefMI->getOperand(1).setImm(NewImm);
26384ba319b5SDimitry Andric 
26394ba319b5SDimitry Andric         // If we're not using the GPR result of the CR-setting instruction, we
26404ba319b5SDimitry Andric         // just need to and with zero/non-zero depending on the new immediate.
26414ba319b5SDimitry Andric         else if (MRI->use_empty(MI.getOperand(0).getReg())) {
26424ba319b5SDimitry Andric           if (NewImm) {
26434ba319b5SDimitry Andric             assert(Immediate && "Transformation converted zero to non-zero?");
26444ba319b5SDimitry Andric             NewImm = Immediate;
26454ba319b5SDimitry Andric           }
26464ba319b5SDimitry Andric         }
26474ba319b5SDimitry Andric         else if (ImmChanged)
26484ba319b5SDimitry Andric           return false;
26494ba319b5SDimitry Andric       }
26504ba319b5SDimitry Andric     }
26514ba319b5SDimitry Andric 
26524ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
26534ba319b5SDimitry Andric     LLVM_DEBUG(MI.dump());
26544ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "Fed by:\n");
26554ba319b5SDimitry Andric     LLVM_DEBUG(DefMI->dump());
26562cab237bSDimitry Andric     LoadImmediateInfo LII;
26572cab237bSDimitry Andric     LII.Imm = NewImm;
26582cab237bSDimitry Andric     LII.Is64Bit = Is64BitLI;
26592cab237bSDimitry Andric     LII.SetCR = SetCR;
26602cab237bSDimitry Andric     // If we're setting the CR, the original load-immediate must be kept (as an
26612cab237bSDimitry Andric     // operand to ANDIo/ANDI8o).
26622cab237bSDimitry Andric     if (KilledDef && SetCR)
26632cab237bSDimitry Andric       *KilledDef = nullptr;
26642cab237bSDimitry Andric     replaceInstrWithLI(MI, LII);
26654ba319b5SDimitry Andric     LLVM_DEBUG(dbgs() << "With:\n");
26664ba319b5SDimitry Andric     LLVM_DEBUG(MI.dump());
26672cab237bSDimitry Andric     return true;
26682cab237bSDimitry Andric   }
26692cab237bSDimitry Andric   return false;
26702cab237bSDimitry Andric }
26712cab237bSDimitry Andric 
isVFReg(unsigned Reg)2672*b5893f02SDimitry Andric static bool isVFReg(unsigned Reg) {
2673*b5893f02SDimitry Andric   return PPC::VFRCRegClass.contains(Reg);
2674*b5893f02SDimitry Andric }
2675*b5893f02SDimitry Andric 
instrHasImmForm(const MachineInstr & MI,ImmInstrInfo & III,bool PostRA) const26762cab237bSDimitry Andric bool PPCInstrInfo::instrHasImmForm(const MachineInstr &MI,
2677*b5893f02SDimitry Andric                                    ImmInstrInfo &III, bool PostRA) const {
26782cab237bSDimitry Andric   unsigned Opc = MI.getOpcode();
26792cab237bSDimitry Andric   // The vast majority of the instructions would need their operand 2 replaced
26802cab237bSDimitry Andric   // with an immediate when switching to the reg+imm form. A marked exception
26812cab237bSDimitry Andric   // are the update form loads/stores for which a constant operand 2 would need
26822cab237bSDimitry Andric   // to turn into a displacement and move operand 1 to the operand 2 position.
26832cab237bSDimitry Andric   III.ImmOpNo = 2;
2684*b5893f02SDimitry Andric   III.OpNoForForwarding = 2;
26852cab237bSDimitry Andric   III.ImmWidth = 16;
26862cab237bSDimitry Andric   III.ImmMustBeMultipleOf = 1;
268730785c0eSDimitry Andric   III.TruncateImmTo = 0;
2688*b5893f02SDimitry Andric   III.IsSummingOperands = false;
26892cab237bSDimitry Andric   switch (Opc) {
26902cab237bSDimitry Andric   default: return false;
26912cab237bSDimitry Andric   case PPC::ADD4:
26922cab237bSDimitry Andric   case PPC::ADD8:
26932cab237bSDimitry Andric     III.SignedImm = true;
26942cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
26952cab237bSDimitry Andric     III.ZeroIsSpecialNew = 1;
26962cab237bSDimitry Andric     III.IsCommutative = true;
2697*b5893f02SDimitry Andric     III.IsSummingOperands = true;
26982cab237bSDimitry Andric     III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
26992cab237bSDimitry Andric     break;
27002cab237bSDimitry Andric   case PPC::ADDC:
27012cab237bSDimitry Andric   case PPC::ADDC8:
27022cab237bSDimitry Andric     III.SignedImm = true;
27032cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27042cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27052cab237bSDimitry Andric     III.IsCommutative = true;
2706*b5893f02SDimitry Andric     III.IsSummingOperands = true;
27072cab237bSDimitry Andric     III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
27082cab237bSDimitry Andric     break;
27092cab237bSDimitry Andric   case PPC::ADDCo:
27102cab237bSDimitry Andric     III.SignedImm = true;
27112cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27122cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27132cab237bSDimitry Andric     III.IsCommutative = true;
2714*b5893f02SDimitry Andric     III.IsSummingOperands = true;
27152cab237bSDimitry Andric     III.ImmOpcode = PPC::ADDICo;
27162cab237bSDimitry Andric     break;
27172cab237bSDimitry Andric   case PPC::SUBFC:
27182cab237bSDimitry Andric   case PPC::SUBFC8:
27192cab237bSDimitry Andric     III.SignedImm = true;
27202cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27212cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27222cab237bSDimitry Andric     III.IsCommutative = false;
27232cab237bSDimitry Andric     III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
27242cab237bSDimitry Andric     break;
27252cab237bSDimitry Andric   case PPC::CMPW:
27262cab237bSDimitry Andric   case PPC::CMPD:
27272cab237bSDimitry Andric     III.SignedImm = true;
27282cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27292cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27302cab237bSDimitry Andric     III.IsCommutative = false;
27312cab237bSDimitry Andric     III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
27322cab237bSDimitry Andric     break;
27332cab237bSDimitry Andric   case PPC::CMPLW:
27342cab237bSDimitry Andric   case PPC::CMPLD:
27352cab237bSDimitry Andric     III.SignedImm = false;
27362cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27372cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27382cab237bSDimitry Andric     III.IsCommutative = false;
27392cab237bSDimitry Andric     III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
27402cab237bSDimitry Andric     break;
27412cab237bSDimitry Andric   case PPC::ANDo:
27422cab237bSDimitry Andric   case PPC::AND8o:
27432cab237bSDimitry Andric   case PPC::OR:
27442cab237bSDimitry Andric   case PPC::OR8:
27452cab237bSDimitry Andric   case PPC::XOR:
27462cab237bSDimitry Andric   case PPC::XOR8:
27472cab237bSDimitry Andric     III.SignedImm = false;
27482cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
27492cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
27502cab237bSDimitry Andric     III.IsCommutative = true;
27512cab237bSDimitry Andric     switch(Opc) {
27522cab237bSDimitry Andric     default: llvm_unreachable("Unknown opcode");
27532cab237bSDimitry Andric     case PPC::ANDo: III.ImmOpcode = PPC::ANDIo; break;
27542cab237bSDimitry Andric     case PPC::AND8o: III.ImmOpcode = PPC::ANDIo8; break;
27552cab237bSDimitry Andric     case PPC::OR: III.ImmOpcode = PPC::ORI; break;
27562cab237bSDimitry Andric     case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
27572cab237bSDimitry Andric     case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
27582cab237bSDimitry Andric     case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
27592cab237bSDimitry Andric     }
27602cab237bSDimitry Andric     break;
27612cab237bSDimitry Andric   case PPC::RLWNM:
27622cab237bSDimitry Andric   case PPC::RLWNM8:
27632cab237bSDimitry Andric   case PPC::RLWNMo:
27642cab237bSDimitry Andric   case PPC::RLWNM8o:
27652cab237bSDimitry Andric   case PPC::SLW:
27662cab237bSDimitry Andric   case PPC::SLW8:
27672cab237bSDimitry Andric   case PPC::SLWo:
27682cab237bSDimitry Andric   case PPC::SLW8o:
27692cab237bSDimitry Andric   case PPC::SRW:
27702cab237bSDimitry Andric   case PPC::SRW8:
27712cab237bSDimitry Andric   case PPC::SRWo:
27722cab237bSDimitry Andric   case PPC::SRW8o:
27732cab237bSDimitry Andric   case PPC::SRAW:
27742cab237bSDimitry Andric   case PPC::SRAWo:
277530785c0eSDimitry Andric     III.SignedImm = false;
277630785c0eSDimitry Andric     III.ZeroIsSpecialOrig = 0;
277730785c0eSDimitry Andric     III.ZeroIsSpecialNew = 0;
277830785c0eSDimitry Andric     III.IsCommutative = false;
277930785c0eSDimitry Andric     // This isn't actually true, but the instructions ignore any of the
278030785c0eSDimitry Andric     // upper bits, so any immediate loaded with an LI is acceptable.
278130785c0eSDimitry Andric     // This does not apply to shift right algebraic because a value
278230785c0eSDimitry Andric     // out of range will produce a -1/0.
278330785c0eSDimitry Andric     III.ImmWidth = 16;
278430785c0eSDimitry Andric     if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 ||
278530785c0eSDimitry Andric         Opc == PPC::RLWNMo || Opc == PPC::RLWNM8o)
278630785c0eSDimitry Andric       III.TruncateImmTo = 5;
278730785c0eSDimitry Andric     else
278830785c0eSDimitry Andric       III.TruncateImmTo = 6;
278930785c0eSDimitry Andric     switch(Opc) {
279030785c0eSDimitry Andric     default: llvm_unreachable("Unknown opcode");
279130785c0eSDimitry Andric     case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
279230785c0eSDimitry Andric     case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
279330785c0eSDimitry Andric     case PPC::RLWNMo: III.ImmOpcode = PPC::RLWINMo; break;
279430785c0eSDimitry Andric     case PPC::RLWNM8o: III.ImmOpcode = PPC::RLWINM8o; break;
279530785c0eSDimitry Andric     case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
279630785c0eSDimitry Andric     case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
279730785c0eSDimitry Andric     case PPC::SLWo: III.ImmOpcode = PPC::RLWINMo; break;
279830785c0eSDimitry Andric     case PPC::SLW8o: III.ImmOpcode = PPC::RLWINM8o; break;
279930785c0eSDimitry Andric     case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
280030785c0eSDimitry Andric     case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
280130785c0eSDimitry Andric     case PPC::SRWo: III.ImmOpcode = PPC::RLWINMo; break;
280230785c0eSDimitry Andric     case PPC::SRW8o: III.ImmOpcode = PPC::RLWINM8o; break;
280330785c0eSDimitry Andric     case PPC::SRAW:
280430785c0eSDimitry Andric       III.ImmWidth = 5;
280530785c0eSDimitry Andric       III.TruncateImmTo = 0;
280630785c0eSDimitry Andric       III.ImmOpcode = PPC::SRAWI;
280730785c0eSDimitry Andric       break;
280830785c0eSDimitry Andric     case PPC::SRAWo:
280930785c0eSDimitry Andric       III.ImmWidth = 5;
281030785c0eSDimitry Andric       III.TruncateImmTo = 0;
281130785c0eSDimitry Andric       III.ImmOpcode = PPC::SRAWIo;
281230785c0eSDimitry Andric       break;
281330785c0eSDimitry Andric     }
281430785c0eSDimitry Andric     break;
281530785c0eSDimitry Andric   case PPC::RLDCL:
281630785c0eSDimitry Andric   case PPC::RLDCLo:
281730785c0eSDimitry Andric   case PPC::RLDCR:
281830785c0eSDimitry Andric   case PPC::RLDCRo:
28192cab237bSDimitry Andric   case PPC::SLD:
28202cab237bSDimitry Andric   case PPC::SLDo:
28212cab237bSDimitry Andric   case PPC::SRD:
28222cab237bSDimitry Andric   case PPC::SRDo:
28232cab237bSDimitry Andric   case PPC::SRAD:
28242cab237bSDimitry Andric   case PPC::SRADo:
28252cab237bSDimitry Andric     III.SignedImm = false;
28262cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 0;
28272cab237bSDimitry Andric     III.ZeroIsSpecialNew = 0;
28282cab237bSDimitry Andric     III.IsCommutative = false;
28292cab237bSDimitry Andric     // This isn't actually true, but the instructions ignore any of the
28302cab237bSDimitry Andric     // upper bits, so any immediate loaded with an LI is acceptable.
283130785c0eSDimitry Andric     // This does not apply to shift right algebraic because a value
283230785c0eSDimitry Andric     // out of range will produce a -1/0.
28332cab237bSDimitry Andric     III.ImmWidth = 16;
283430785c0eSDimitry Andric     if (Opc == PPC::RLDCL || Opc == PPC::RLDCLo ||
283530785c0eSDimitry Andric         Opc == PPC::RLDCR || Opc == PPC::RLDCRo)
283630785c0eSDimitry Andric       III.TruncateImmTo = 6;
283730785c0eSDimitry Andric     else
283830785c0eSDimitry Andric       III.TruncateImmTo = 7;
28392cab237bSDimitry Andric     switch(Opc) {
28402cab237bSDimitry Andric     default: llvm_unreachable("Unknown opcode");
28412cab237bSDimitry Andric     case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
28422cab237bSDimitry Andric     case PPC::RLDCLo: III.ImmOpcode = PPC::RLDICLo; break;
28432cab237bSDimitry Andric     case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
28442cab237bSDimitry Andric     case PPC::RLDCRo: III.ImmOpcode = PPC::RLDICRo; break;
28452cab237bSDimitry Andric     case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
28462cab237bSDimitry Andric     case PPC::SLDo: III.ImmOpcode = PPC::RLDICRo; break;
28472cab237bSDimitry Andric     case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
28482cab237bSDimitry Andric     case PPC::SRDo: III.ImmOpcode = PPC::RLDICLo; break;
284930785c0eSDimitry Andric     case PPC::SRAD:
285030785c0eSDimitry Andric       III.ImmWidth = 6;
285130785c0eSDimitry Andric       III.TruncateImmTo = 0;
285230785c0eSDimitry Andric       III.ImmOpcode = PPC::SRADI;
285330785c0eSDimitry Andric        break;
285430785c0eSDimitry Andric     case PPC::SRADo:
285530785c0eSDimitry Andric       III.ImmWidth = 6;
285630785c0eSDimitry Andric       III.TruncateImmTo = 0;
285730785c0eSDimitry Andric       III.ImmOpcode = PPC::SRADIo;
285830785c0eSDimitry Andric       break;
28592cab237bSDimitry Andric     }
28602cab237bSDimitry Andric     break;
28612cab237bSDimitry Andric   // Loads and stores:
28622cab237bSDimitry Andric   case PPC::LBZX:
28632cab237bSDimitry Andric   case PPC::LBZX8:
28642cab237bSDimitry Andric   case PPC::LHZX:
28652cab237bSDimitry Andric   case PPC::LHZX8:
28662cab237bSDimitry Andric   case PPC::LHAX:
28672cab237bSDimitry Andric   case PPC::LHAX8:
28682cab237bSDimitry Andric   case PPC::LWZX:
28692cab237bSDimitry Andric   case PPC::LWZX8:
28702cab237bSDimitry Andric   case PPC::LWAX:
28712cab237bSDimitry Andric   case PPC::LDX:
28722cab237bSDimitry Andric   case PPC::LFSX:
28732cab237bSDimitry Andric   case PPC::LFDX:
28742cab237bSDimitry Andric   case PPC::STBX:
28752cab237bSDimitry Andric   case PPC::STBX8:
28762cab237bSDimitry Andric   case PPC::STHX:
28772cab237bSDimitry Andric   case PPC::STHX8:
28782cab237bSDimitry Andric   case PPC::STWX:
28792cab237bSDimitry Andric   case PPC::STWX8:
28802cab237bSDimitry Andric   case PPC::STDX:
28812cab237bSDimitry Andric   case PPC::STFSX:
28822cab237bSDimitry Andric   case PPC::STFDX:
28832cab237bSDimitry Andric     III.SignedImm = true;
28842cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 1;
28852cab237bSDimitry Andric     III.ZeroIsSpecialNew = 2;
28862cab237bSDimitry Andric     III.IsCommutative = true;
2887*b5893f02SDimitry Andric     III.IsSummingOperands = true;
28882cab237bSDimitry Andric     III.ImmOpNo = 1;
2889*b5893f02SDimitry Andric     III.OpNoForForwarding = 2;
28902cab237bSDimitry Andric     switch(Opc) {
28912cab237bSDimitry Andric     default: llvm_unreachable("Unknown opcode");
28922cab237bSDimitry Andric     case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
28932cab237bSDimitry Andric     case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
28942cab237bSDimitry Andric     case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
28952cab237bSDimitry Andric     case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
28962cab237bSDimitry Andric     case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
28972cab237bSDimitry Andric     case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
28982cab237bSDimitry Andric     case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
28992cab237bSDimitry Andric     case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
29002cab237bSDimitry Andric     case PPC::LWAX:
29012cab237bSDimitry Andric       III.ImmOpcode = PPC::LWA;
29022cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 4;
29032cab237bSDimitry Andric       break;
29042cab237bSDimitry Andric     case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;
29052cab237bSDimitry Andric     case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
29062cab237bSDimitry Andric     case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
29072cab237bSDimitry Andric     case PPC::STBX: III.ImmOpcode = PPC::STB; break;
29082cab237bSDimitry Andric     case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
29092cab237bSDimitry Andric     case PPC::STHX: III.ImmOpcode = PPC::STH; break;
29102cab237bSDimitry Andric     case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
29112cab237bSDimitry Andric     case PPC::STWX: III.ImmOpcode = PPC::STW; break;
29122cab237bSDimitry Andric     case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
29132cab237bSDimitry Andric     case PPC::STDX:
29142cab237bSDimitry Andric       III.ImmOpcode = PPC::STD;
29152cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 4;
29162cab237bSDimitry Andric       break;
29172cab237bSDimitry Andric     case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
29182cab237bSDimitry Andric     case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
29192cab237bSDimitry Andric     }
29202cab237bSDimitry Andric     break;
29212cab237bSDimitry Andric   case PPC::LBZUX:
29222cab237bSDimitry Andric   case PPC::LBZUX8:
29232cab237bSDimitry Andric   case PPC::LHZUX:
29242cab237bSDimitry Andric   case PPC::LHZUX8:
29252cab237bSDimitry Andric   case PPC::LHAUX:
29262cab237bSDimitry Andric   case PPC::LHAUX8:
29272cab237bSDimitry Andric   case PPC::LWZUX:
29282cab237bSDimitry Andric   case PPC::LWZUX8:
29292cab237bSDimitry Andric   case PPC::LDUX:
29302cab237bSDimitry Andric   case PPC::LFSUX:
29312cab237bSDimitry Andric   case PPC::LFDUX:
29322cab237bSDimitry Andric   case PPC::STBUX:
29332cab237bSDimitry Andric   case PPC::STBUX8:
29342cab237bSDimitry Andric   case PPC::STHUX:
29352cab237bSDimitry Andric   case PPC::STHUX8:
29362cab237bSDimitry Andric   case PPC::STWUX:
29372cab237bSDimitry Andric   case PPC::STWUX8:
29382cab237bSDimitry Andric   case PPC::STDUX:
29392cab237bSDimitry Andric   case PPC::STFSUX:
29402cab237bSDimitry Andric   case PPC::STFDUX:
29412cab237bSDimitry Andric     III.SignedImm = true;
29422cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 2;
29432cab237bSDimitry Andric     III.ZeroIsSpecialNew = 3;
29442cab237bSDimitry Andric     III.IsCommutative = false;
2945*b5893f02SDimitry Andric     III.IsSummingOperands = true;
29462cab237bSDimitry Andric     III.ImmOpNo = 2;
2947*b5893f02SDimitry Andric     III.OpNoForForwarding = 3;
29482cab237bSDimitry Andric     switch(Opc) {
29492cab237bSDimitry Andric     default: llvm_unreachable("Unknown opcode");
29502cab237bSDimitry Andric     case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
29512cab237bSDimitry Andric     case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
29522cab237bSDimitry Andric     case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
29532cab237bSDimitry Andric     case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
29542cab237bSDimitry Andric     case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
29552cab237bSDimitry Andric     case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
29562cab237bSDimitry Andric     case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
29572cab237bSDimitry Andric     case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
29582cab237bSDimitry Andric     case PPC::LDUX:
29592cab237bSDimitry Andric       III.ImmOpcode = PPC::LDU;
29602cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 4;
29612cab237bSDimitry Andric       break;
29622cab237bSDimitry Andric     case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
29632cab237bSDimitry Andric     case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
29642cab237bSDimitry Andric     case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
29652cab237bSDimitry Andric     case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
29662cab237bSDimitry Andric     case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
29672cab237bSDimitry Andric     case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
29682cab237bSDimitry Andric     case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
29692cab237bSDimitry Andric     case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
29702cab237bSDimitry Andric     case PPC::STDUX:
29712cab237bSDimitry Andric       III.ImmOpcode = PPC::STDU;
29722cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 4;
29732cab237bSDimitry Andric       break;
29742cab237bSDimitry Andric     case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
29752cab237bSDimitry Andric     case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
29762cab237bSDimitry Andric     }
29772cab237bSDimitry Andric     break;
2978*b5893f02SDimitry Andric   // Power9 and up only. For some of these, the X-Form version has access to all
2979*b5893f02SDimitry Andric   // 64 VSR's whereas the D-Form only has access to the VR's. We replace those
2980*b5893f02SDimitry Andric   // with pseudo-ops pre-ra and for post-ra, we check that the register loaded
2981*b5893f02SDimitry Andric   // into or stored from is one of the VR registers.
29822cab237bSDimitry Andric   case PPC::LXVX:
29832cab237bSDimitry Andric   case PPC::LXSSPX:
29842cab237bSDimitry Andric   case PPC::LXSDX:
29852cab237bSDimitry Andric   case PPC::STXVX:
29862cab237bSDimitry Andric   case PPC::STXSSPX:
29872cab237bSDimitry Andric   case PPC::STXSDX:
2988*b5893f02SDimitry Andric   case PPC::XFLOADf32:
2989*b5893f02SDimitry Andric   case PPC::XFLOADf64:
2990*b5893f02SDimitry Andric   case PPC::XFSTOREf32:
2991*b5893f02SDimitry Andric   case PPC::XFSTOREf64:
29922cab237bSDimitry Andric     if (!Subtarget.hasP9Vector())
29932cab237bSDimitry Andric       return false;
29942cab237bSDimitry Andric     III.SignedImm = true;
29952cab237bSDimitry Andric     III.ZeroIsSpecialOrig = 1;
29962cab237bSDimitry Andric     III.ZeroIsSpecialNew = 2;
29972cab237bSDimitry Andric     III.IsCommutative = true;
2998*b5893f02SDimitry Andric     III.IsSummingOperands = true;
29992cab237bSDimitry Andric     III.ImmOpNo = 1;
3000*b5893f02SDimitry Andric     III.OpNoForForwarding = 2;
3001*b5893f02SDimitry Andric     III.ImmMustBeMultipleOf = 4;
30022cab237bSDimitry Andric     switch(Opc) {
30032cab237bSDimitry Andric     default: llvm_unreachable("Unknown opcode");
30042cab237bSDimitry Andric     case PPC::LXVX:
30052cab237bSDimitry Andric       III.ImmOpcode = PPC::LXV;
30062cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 16;
30072cab237bSDimitry Andric       break;
30082cab237bSDimitry Andric     case PPC::LXSSPX:
3009*b5893f02SDimitry Andric       if (PostRA) {
3010*b5893f02SDimitry Andric         if (isVFReg(MI.getOperand(0).getReg()))
30112cab237bSDimitry Andric           III.ImmOpcode = PPC::LXSSP;
3012*b5893f02SDimitry Andric         else {
3013*b5893f02SDimitry Andric           III.ImmOpcode = PPC::LFS;
3014*b5893f02SDimitry Andric           III.ImmMustBeMultipleOf = 1;
3015*b5893f02SDimitry Andric         }
3016*b5893f02SDimitry Andric         break;
3017*b5893f02SDimitry Andric       }
3018*b5893f02SDimitry Andric       LLVM_FALLTHROUGH;
3019*b5893f02SDimitry Andric     case PPC::XFLOADf32:
3020*b5893f02SDimitry Andric       III.ImmOpcode = PPC::DFLOADf32;
30212cab237bSDimitry Andric       break;
30222cab237bSDimitry Andric     case PPC::LXSDX:
3023*b5893f02SDimitry Andric       if (PostRA) {
3024*b5893f02SDimitry Andric         if (isVFReg(MI.getOperand(0).getReg()))
30252cab237bSDimitry Andric           III.ImmOpcode = PPC::LXSD;
3026*b5893f02SDimitry Andric         else {
3027*b5893f02SDimitry Andric           III.ImmOpcode = PPC::LFD;
3028*b5893f02SDimitry Andric           III.ImmMustBeMultipleOf = 1;
3029*b5893f02SDimitry Andric         }
3030*b5893f02SDimitry Andric         break;
3031*b5893f02SDimitry Andric       }
3032*b5893f02SDimitry Andric       LLVM_FALLTHROUGH;
3033*b5893f02SDimitry Andric     case PPC::XFLOADf64:
3034*b5893f02SDimitry Andric       III.ImmOpcode = PPC::DFLOADf64;
30352cab237bSDimitry Andric       break;
30362cab237bSDimitry Andric     case PPC::STXVX:
30372cab237bSDimitry Andric       III.ImmOpcode = PPC::STXV;
30382cab237bSDimitry Andric       III.ImmMustBeMultipleOf = 16;
30392cab237bSDimitry Andric       break;
30402cab237bSDimitry Andric     case PPC::STXSSPX:
3041*b5893f02SDimitry Andric       if (PostRA) {
3042*b5893f02SDimitry Andric         if (isVFReg(MI.getOperand(0).getReg()))
30432cab237bSDimitry Andric           III.ImmOpcode = PPC::STXSSP;
3044*b5893f02SDimitry Andric         else {
3045*b5893f02SDimitry Andric           III.ImmOpcode = PPC::STFS;
3046*b5893f02SDimitry Andric           III.ImmMustBeMultipleOf = 1;
3047*b5893f02SDimitry Andric         }
3048*b5893f02SDimitry Andric         break;
3049*b5893f02SDimitry Andric       }
3050*b5893f02SDimitry Andric       LLVM_FALLTHROUGH;
3051*b5893f02SDimitry Andric     case PPC::XFSTOREf32:
3052*b5893f02SDimitry Andric       III.ImmOpcode = PPC::DFSTOREf32;
30532cab237bSDimitry Andric       break;
30542cab237bSDimitry Andric     case PPC::STXSDX:
3055*b5893f02SDimitry Andric       if (PostRA) {
3056*b5893f02SDimitry Andric         if (isVFReg(MI.getOperand(0).getReg()))
30572cab237bSDimitry Andric           III.ImmOpcode = PPC::STXSD;
3058*b5893f02SDimitry Andric         else {
3059*b5893f02SDimitry Andric           III.ImmOpcode = PPC::STFD;
3060*b5893f02SDimitry Andric           III.ImmMustBeMultipleOf = 1;
3061*b5893f02SDimitry Andric         }
3062*b5893f02SDimitry Andric         break;
3063*b5893f02SDimitry Andric       }
3064*b5893f02SDimitry Andric       LLVM_FALLTHROUGH;
3065*b5893f02SDimitry Andric     case PPC::XFSTOREf64:
3066*b5893f02SDimitry Andric       III.ImmOpcode = PPC::DFSTOREf64;
30672cab237bSDimitry Andric       break;
30682cab237bSDimitry Andric     }
30692cab237bSDimitry Andric     break;
30702cab237bSDimitry Andric   }
30712cab237bSDimitry Andric   return true;
30722cab237bSDimitry Andric }
30732cab237bSDimitry Andric 
30742cab237bSDimitry Andric // Utility function for swaping two arbitrary operands of an instruction.
swapMIOperands(MachineInstr & MI,unsigned Op1,unsigned Op2)30752cab237bSDimitry Andric static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {
30762cab237bSDimitry Andric   assert(Op1 != Op2 && "Cannot swap operand with itself.");
30772cab237bSDimitry Andric 
30782cab237bSDimitry Andric   unsigned MaxOp = std::max(Op1, Op2);
30792cab237bSDimitry Andric   unsigned MinOp = std::min(Op1, Op2);
30802cab237bSDimitry Andric   MachineOperand MOp1 = MI.getOperand(MinOp);
30812cab237bSDimitry Andric   MachineOperand MOp2 = MI.getOperand(MaxOp);
30822cab237bSDimitry Andric   MI.RemoveOperand(std::max(Op1, Op2));
30832cab237bSDimitry Andric   MI.RemoveOperand(std::min(Op1, Op2));
30842cab237bSDimitry Andric 
30852cab237bSDimitry Andric   // If the operands we are swapping are the two at the end (the common case)
30862cab237bSDimitry Andric   // we can just remove both and add them in the opposite order.
30872cab237bSDimitry Andric   if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
30882cab237bSDimitry Andric     MI.addOperand(MOp2);
30892cab237bSDimitry Andric     MI.addOperand(MOp1);
30902cab237bSDimitry Andric   } else {
30912cab237bSDimitry Andric     // Store all operands in a temporary vector, remove them and re-add in the
30922cab237bSDimitry Andric     // right order.
30932cab237bSDimitry Andric     SmallVector<MachineOperand, 2> MOps;
30942cab237bSDimitry Andric     unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.
30952cab237bSDimitry Andric     for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
30962cab237bSDimitry Andric       MOps.push_back(MI.getOperand(i));
30972cab237bSDimitry Andric       MI.RemoveOperand(i);
30982cab237bSDimitry Andric     }
30992cab237bSDimitry Andric     // MOp2 needs to be added next.
31002cab237bSDimitry Andric     MI.addOperand(MOp2);
31012cab237bSDimitry Andric     // Now add the rest.
31022cab237bSDimitry Andric     for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
31032cab237bSDimitry Andric       if (i == MaxOp)
31042cab237bSDimitry Andric         MI.addOperand(MOp1);
31052cab237bSDimitry Andric       else {
31062cab237bSDimitry Andric         MI.addOperand(MOps.back());
31072cab237bSDimitry Andric         MOps.pop_back();
31082cab237bSDimitry Andric       }
31092cab237bSDimitry Andric     }
31102cab237bSDimitry Andric   }
31112cab237bSDimitry Andric }
31122cab237bSDimitry Andric 
3113*b5893f02SDimitry Andric // Check if the 'MI' that has the index OpNoForForwarding
3114*b5893f02SDimitry Andric // meets the requirement described in the ImmInstrInfo.
isUseMIElgibleForForwarding(MachineInstr & MI,const ImmInstrInfo & III,unsigned OpNoForForwarding) const3115*b5893f02SDimitry Andric bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
3116*b5893f02SDimitry Andric                                                const ImmInstrInfo &III,
3117*b5893f02SDimitry Andric                                                unsigned OpNoForForwarding
3118*b5893f02SDimitry Andric                                                ) const {
3119*b5893f02SDimitry Andric   // As the algorithm of checking for PPC::ZERO/PPC::ZERO8
3120*b5893f02SDimitry Andric   // would not work pre-RA, we can only do the check post RA.
3121*b5893f02SDimitry Andric   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3122*b5893f02SDimitry Andric   if (MRI.isSSA())
3123*b5893f02SDimitry Andric     return false;
3124*b5893f02SDimitry Andric 
3125*b5893f02SDimitry Andric   // Cannot do the transform if MI isn't summing the operands.
3126*b5893f02SDimitry Andric   if (!III.IsSummingOperands)
3127*b5893f02SDimitry Andric     return false;
3128*b5893f02SDimitry Andric 
3129*b5893f02SDimitry Andric   // The instruction we are trying to replace must have the ZeroIsSpecialOrig set.
3130*b5893f02SDimitry Andric   if (!III.ZeroIsSpecialOrig)
3131*b5893f02SDimitry Andric     return false;
3132*b5893f02SDimitry Andric 
3133*b5893f02SDimitry Andric   // We cannot do the transform if the operand we are trying to replace
3134*b5893f02SDimitry Andric   // isn't the same as the operand the instruction allows.
3135*b5893f02SDimitry Andric   if (OpNoForForwarding != III.OpNoForForwarding)
3136*b5893f02SDimitry Andric     return false;
3137*b5893f02SDimitry Andric 
3138*b5893f02SDimitry Andric   // Check if the instruction we are trying to transform really has
3139*b5893f02SDimitry Andric   // the special zero register as its operand.
3140*b5893f02SDimitry Andric   if (MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO &&
3141*b5893f02SDimitry Andric       MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO8)
3142*b5893f02SDimitry Andric     return false;
3143*b5893f02SDimitry Andric 
3144*b5893f02SDimitry Andric   // This machine instruction is convertible if it is,
3145*b5893f02SDimitry Andric   // 1. summing the operands.
3146*b5893f02SDimitry Andric   // 2. one of the operands is special zero register.
3147*b5893f02SDimitry Andric   // 3. the operand we are trying to replace is allowed by the MI.
3148*b5893f02SDimitry Andric   return true;
3149*b5893f02SDimitry Andric }
3150*b5893f02SDimitry Andric 
3151*b5893f02SDimitry Andric // Check if the DefMI is the add inst and set the ImmMO and RegMO
3152*b5893f02SDimitry Andric // accordingly.
isDefMIElgibleForForwarding(MachineInstr & DefMI,const ImmInstrInfo & III,MachineOperand * & ImmMO,MachineOperand * & RegMO) const3153*b5893f02SDimitry Andric bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
3154*b5893f02SDimitry Andric                                                const ImmInstrInfo &III,
3155*b5893f02SDimitry Andric                                                MachineOperand *&ImmMO,
3156*b5893f02SDimitry Andric                                                MachineOperand *&RegMO) const {
3157*b5893f02SDimitry Andric   unsigned Opc = DefMI.getOpcode();
3158*b5893f02SDimitry Andric   if (Opc != PPC::ADDItocL && Opc != PPC::ADDI && Opc != PPC::ADDI8)
3159*b5893f02SDimitry Andric     return false;
3160*b5893f02SDimitry Andric 
3161*b5893f02SDimitry Andric   assert(DefMI.getNumOperands() >= 3 &&
3162*b5893f02SDimitry Andric          "Add inst must have at least three operands");
3163*b5893f02SDimitry Andric   RegMO = &DefMI.getOperand(1);
3164*b5893f02SDimitry Andric   ImmMO = &DefMI.getOperand(2);
3165*b5893f02SDimitry Andric 
3166*b5893f02SDimitry Andric   // This DefMI is elgible for forwarding if it is:
3167*b5893f02SDimitry Andric   // 1. add inst
3168*b5893f02SDimitry Andric   // 2. one of the operands is Imm/CPI/Global.
3169*b5893f02SDimitry Andric   return isAnImmediateOperand(*ImmMO);
3170*b5893f02SDimitry Andric }
3171*b5893f02SDimitry Andric 
isRegElgibleForForwarding(const MachineOperand & RegMO,const MachineInstr & DefMI,const MachineInstr & MI,bool KillDefMI) const3172*b5893f02SDimitry Andric bool PPCInstrInfo::isRegElgibleForForwarding(const MachineOperand &RegMO,
3173*b5893f02SDimitry Andric                                              const MachineInstr &DefMI,
3174*b5893f02SDimitry Andric                                              const MachineInstr &MI,
3175*b5893f02SDimitry Andric                                              bool KillDefMI
3176*b5893f02SDimitry Andric                                              ) const {
3177*b5893f02SDimitry Andric   // x = addi y, imm
3178*b5893f02SDimitry Andric   // ...
3179*b5893f02SDimitry Andric   // z = lfdx 0, x   -> z = lfd imm(y)
3180*b5893f02SDimitry Andric   // The Reg "y" can be forwarded to the MI(z) only when there is no DEF
3181*b5893f02SDimitry Andric   // of "y" between the DEF of "x" and "z".
3182*b5893f02SDimitry Andric   // The query is only valid post RA.
3183*b5893f02SDimitry Andric   const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3184*b5893f02SDimitry Andric   if (MRI.isSSA())
3185*b5893f02SDimitry Andric     return false;
3186*b5893f02SDimitry Andric 
3187*b5893f02SDimitry Andric   // MachineInstr::readsRegister only returns true if the machine
3188*b5893f02SDimitry Andric   // instruction reads the exact register or its super-register. It
3189*b5893f02SDimitry Andric   // does not consider uses of sub-registers which seems like strange
3190*b5893f02SDimitry Andric   // behaviour. Nonetheless, if we end up with a 64-bit register here,
3191*b5893f02SDimitry Andric   // get the corresponding 32-bit register to check.
3192*b5893f02SDimitry Andric   unsigned Reg = RegMO.getReg();
3193*b5893f02SDimitry Andric   if (PPC::G8RCRegClass.contains(Reg))
3194*b5893f02SDimitry Andric     Reg = Reg - PPC::X0 + PPC::R0;
3195*b5893f02SDimitry Andric 
3196*b5893f02SDimitry Andric   // Walking the inst in reverse(MI-->DefMI) to get the last DEF of the Reg.
3197*b5893f02SDimitry Andric   MachineBasicBlock::const_reverse_iterator It = MI;
3198*b5893f02SDimitry Andric   MachineBasicBlock::const_reverse_iterator E = MI.getParent()->rend();
3199*b5893f02SDimitry Andric   It++;
3200*b5893f02SDimitry Andric   for (; It != E; ++It) {
3201*b5893f02SDimitry Andric     if (It->modifiesRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
3202*b5893f02SDimitry Andric       return false;
3203*b5893f02SDimitry Andric     // Made it to DefMI without encountering a clobber.
3204*b5893f02SDimitry Andric     if ((&*It) == &DefMI)
3205*b5893f02SDimitry Andric       break;
3206*b5893f02SDimitry Andric   }
3207*b5893f02SDimitry Andric   assert((&*It) == &DefMI && "DefMI is missing");
3208*b5893f02SDimitry Andric 
3209*b5893f02SDimitry Andric   // If DefMI also uses the register to be forwarded, we can only forward it
3210*b5893f02SDimitry Andric   // if DefMI is being erased.
3211*b5893f02SDimitry Andric   if (DefMI.readsRegister(Reg, &getRegisterInfo()))
3212*b5893f02SDimitry Andric     return KillDefMI;
3213*b5893f02SDimitry Andric 
3214*b5893f02SDimitry Andric   return true;
3215*b5893f02SDimitry Andric }
3216*b5893f02SDimitry Andric 
isImmElgibleForForwarding(const MachineOperand & ImmMO,const MachineInstr & DefMI,const ImmInstrInfo & III,int64_t & Imm) const3217*b5893f02SDimitry Andric bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
3218*b5893f02SDimitry Andric                                              const MachineInstr &DefMI,
3219*b5893f02SDimitry Andric                                              const ImmInstrInfo &III,
3220*b5893f02SDimitry Andric                                              int64_t &Imm) const {
3221*b5893f02SDimitry Andric   assert(isAnImmediateOperand(ImmMO) && "ImmMO is NOT an immediate");
3222*b5893f02SDimitry Andric   if (DefMI.getOpcode() == PPC::ADDItocL) {
3223*b5893f02SDimitry Andric     // The operand for ADDItocL is CPI, which isn't imm at compiling time,
3224*b5893f02SDimitry Andric     // However, we know that, it is 16-bit width, and has the alignment of 4.
3225*b5893f02SDimitry Andric     // Check if the instruction met the requirement.
3226*b5893f02SDimitry Andric     if (III.ImmMustBeMultipleOf > 4 ||
3227*b5893f02SDimitry Andric        III.TruncateImmTo || III.ImmWidth != 16)
3228*b5893f02SDimitry Andric       return false;
3229*b5893f02SDimitry Andric 
3230*b5893f02SDimitry Andric     // Going from XForm to DForm loads means that the displacement needs to be
3231*b5893f02SDimitry Andric     // not just an immediate but also a multiple of 4, or 16 depending on the
3232*b5893f02SDimitry Andric     // load. A DForm load cannot be represented if it is a multiple of say 2.
3233*b5893f02SDimitry Andric     // XForm loads do not have this restriction.
3234*b5893f02SDimitry Andric     if (ImmMO.isGlobal() &&
3235*b5893f02SDimitry Andric         ImmMO.getGlobal()->getAlignment() < III.ImmMustBeMultipleOf)
3236*b5893f02SDimitry Andric       return false;
3237*b5893f02SDimitry Andric 
3238*b5893f02SDimitry Andric     return true;
3239*b5893f02SDimitry Andric   }
3240*b5893f02SDimitry Andric 
3241*b5893f02SDimitry Andric   if (ImmMO.isImm()) {
3242*b5893f02SDimitry Andric     // It is Imm, we need to check if the Imm fit the range.
3243*b5893f02SDimitry Andric     int64_t Immediate = ImmMO.getImm();
3244*b5893f02SDimitry Andric     // Sign-extend to 64-bits.
3245*b5893f02SDimitry Andric     Imm = ((uint64_t)Immediate & ~0x7FFFuLL) != 0 ?
3246*b5893f02SDimitry Andric       (Immediate | 0xFFFFFFFFFFFF0000) : Immediate;
3247*b5893f02SDimitry Andric 
3248*b5893f02SDimitry Andric     if (Imm % III.ImmMustBeMultipleOf)
3249*b5893f02SDimitry Andric       return false;
3250*b5893f02SDimitry Andric     if (III.TruncateImmTo)
3251*b5893f02SDimitry Andric       Imm &= ((1 << III.TruncateImmTo) - 1);
3252*b5893f02SDimitry Andric     if (III.SignedImm) {
3253*b5893f02SDimitry Andric       APInt ActualValue(64, Imm, true);
3254*b5893f02SDimitry Andric       if (!ActualValue.isSignedIntN(III.ImmWidth))
3255*b5893f02SDimitry Andric         return false;
3256*b5893f02SDimitry Andric     } else {
3257*b5893f02SDimitry Andric       uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
3258*b5893f02SDimitry Andric       if ((uint64_t)Imm > UnsignedMax)
3259*b5893f02SDimitry Andric         return false;
3260*b5893f02SDimitry Andric     }
3261*b5893f02SDimitry Andric   }
3262*b5893f02SDimitry Andric   else
3263*b5893f02SDimitry Andric     return false;
3264*b5893f02SDimitry Andric 
3265*b5893f02SDimitry Andric   // This ImmMO is forwarded if it meets the requriement describle
3266*b5893f02SDimitry Andric   // in ImmInstrInfo
3267*b5893f02SDimitry Andric   return true;
3268*b5893f02SDimitry Andric }
3269*b5893f02SDimitry Andric 
3270*b5893f02SDimitry Andric // If an X-Form instruction is fed by an add-immediate and one of its operands
3271*b5893f02SDimitry Andric // is the literal zero, attempt to forward the source of the add-immediate to
3272*b5893f02SDimitry Andric // the corresponding D-Form instruction with the displacement coming from
3273*b5893f02SDimitry Andric // the immediate being added.
transformToImmFormFedByAdd(MachineInstr & MI,const ImmInstrInfo & III,unsigned OpNoForForwarding,MachineInstr & DefMI,bool KillDefMI) const3274*b5893f02SDimitry Andric bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI,
3275*b5893f02SDimitry Andric                                               const ImmInstrInfo &III,
3276*b5893f02SDimitry Andric                                               unsigned OpNoForForwarding,
3277*b5893f02SDimitry Andric                                               MachineInstr &DefMI,
3278*b5893f02SDimitry Andric                                               bool KillDefMI) const {
3279*b5893f02SDimitry Andric   //         RegMO ImmMO
3280*b5893f02SDimitry Andric   //           |    |
3281*b5893f02SDimitry Andric   // x = addi reg, imm  <----- DefMI
3282*b5893f02SDimitry Andric   // y = op    0 ,  x   <----- MI
3283*b5893f02SDimitry Andric   //                |
3284*b5893f02SDimitry Andric   //         OpNoForForwarding
3285*b5893f02SDimitry Andric   // Check if the MI meet the requirement described in the III.
3286*b5893f02SDimitry Andric   if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))
3287*b5893f02SDimitry Andric     return false;
3288*b5893f02SDimitry Andric 
3289*b5893f02SDimitry Andric   // Check if the DefMI meet the requirement
3290*b5893f02SDimitry Andric   // described in the III. If yes, set the ImmMO and RegMO accordingly.
3291*b5893f02SDimitry Andric   MachineOperand *ImmMO = nullptr;
3292*b5893f02SDimitry Andric   MachineOperand *RegMO = nullptr;
3293*b5893f02SDimitry Andric   if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
3294*b5893f02SDimitry Andric     return false;
3295*b5893f02SDimitry Andric   assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
3296*b5893f02SDimitry Andric 
3297*b5893f02SDimitry Andric   // As we get the Imm operand now, we need to check if the ImmMO meet
3298*b5893f02SDimitry Andric   // the requirement described in the III. If yes set the Imm.
3299*b5893f02SDimitry Andric   int64_t Imm = 0;
3300*b5893f02SDimitry Andric   if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
3301*b5893f02SDimitry Andric     return false;
3302*b5893f02SDimitry Andric 
3303*b5893f02SDimitry Andric   // Check if the RegMO can be forwarded to MI.
3304*b5893f02SDimitry Andric   if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI))
3305*b5893f02SDimitry Andric     return false;
3306*b5893f02SDimitry Andric 
3307*b5893f02SDimitry Andric   // We know that, the MI and DefMI both meet the pattern, and
3308*b5893f02SDimitry Andric   // the Imm also meet the requirement with the new Imm-form.
3309*b5893f02SDimitry Andric   // It is safe to do the transformation now.
3310*b5893f02SDimitry Andric   LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
3311*b5893f02SDimitry Andric   LLVM_DEBUG(MI.dump());
3312*b5893f02SDimitry Andric   LLVM_DEBUG(dbgs() << "Fed by:\n");
3313*b5893f02SDimitry Andric   LLVM_DEBUG(DefMI.dump());
3314*b5893f02SDimitry Andric 
3315*b5893f02SDimitry Andric   // Update the base reg first.
3316*b5893f02SDimitry Andric   MI.getOperand(III.OpNoForForwarding).ChangeToRegister(RegMO->getReg(),
3317*b5893f02SDimitry Andric                                                         false, false,
3318*b5893f02SDimitry Andric                                                         RegMO->isKill());
3319*b5893f02SDimitry Andric 
3320*b5893f02SDimitry Andric   // Then, update the imm.
3321*b5893f02SDimitry Andric   if (ImmMO->isImm()) {
3322*b5893f02SDimitry Andric     // If the ImmMO is Imm, change the operand that has ZERO to that Imm
3323*b5893f02SDimitry Andric     // directly.
3324*b5893f02SDimitry Andric     replaceInstrOperandWithImm(MI, III.ZeroIsSpecialOrig, Imm);
3325*b5893f02SDimitry Andric   }
3326*b5893f02SDimitry Andric   else {
3327*b5893f02SDimitry Andric     // Otherwise, it is Constant Pool Index(CPI) or Global,
3328*b5893f02SDimitry Andric     // which is relocation in fact. We need to replace the special zero
3329*b5893f02SDimitry Andric     // register with ImmMO.
3330*b5893f02SDimitry Andric     // Before that, we need to fixup the target flags for imm.
3331*b5893f02SDimitry Andric     // For some reason, we miss to set the flag for the ImmMO if it is CPI.
3332*b5893f02SDimitry Andric     if (DefMI.getOpcode() == PPC::ADDItocL)
3333*b5893f02SDimitry Andric       ImmMO->setTargetFlags(PPCII::MO_TOC_LO);
3334*b5893f02SDimitry Andric 
3335*b5893f02SDimitry Andric     // MI didn't have the interface such as MI.setOperand(i) though
3336*b5893f02SDimitry Andric     // it has MI.getOperand(i). To repalce the ZERO MachineOperand with
3337*b5893f02SDimitry Andric     // ImmMO, we need to remove ZERO operand and all the operands behind it,
3338*b5893f02SDimitry Andric     // and, add the ImmMO, then, move back all the operands behind ZERO.
3339*b5893f02SDimitry Andric     SmallVector<MachineOperand, 2> MOps;
3340*b5893f02SDimitry Andric     for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {
3341*b5893f02SDimitry Andric       MOps.push_back(MI.getOperand(i));
3342*b5893f02SDimitry Andric       MI.RemoveOperand(i);
3343*b5893f02SDimitry Andric     }
3344*b5893f02SDimitry Andric 
3345*b5893f02SDimitry Andric     // Remove the last MO in the list, which is ZERO operand in fact.
3346*b5893f02SDimitry Andric     MOps.pop_back();
3347*b5893f02SDimitry Andric     // Add the imm operand.
3348*b5893f02SDimitry Andric     MI.addOperand(*ImmMO);
3349*b5893f02SDimitry Andric     // Now add the rest back.
3350*b5893f02SDimitry Andric     for (auto &MO : MOps)
3351*b5893f02SDimitry Andric       MI.addOperand(MO);
3352*b5893f02SDimitry Andric   }
3353*b5893f02SDimitry Andric 
3354*b5893f02SDimitry Andric   // Update the opcode.
3355*b5893f02SDimitry Andric   MI.setDesc(get(III.ImmOpcode));
3356*b5893f02SDimitry Andric 
3357*b5893f02SDimitry Andric   LLVM_DEBUG(dbgs() << "With:\n");
3358*b5893f02SDimitry Andric   LLVM_DEBUG(MI.dump());
3359*b5893f02SDimitry Andric 
3360*b5893f02SDimitry Andric   return true;
3361*b5893f02SDimitry Andric }
3362*b5893f02SDimitry Andric 
transformToImmFormFedByLI(MachineInstr & MI,const ImmInstrInfo & III,unsigned ConstantOpNo,int64_t Imm) const3363*b5893f02SDimitry Andric bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
3364*b5893f02SDimitry Andric                                              const ImmInstrInfo &III,
33652cab237bSDimitry Andric                                              unsigned ConstantOpNo,
33662cab237bSDimitry Andric                                              int64_t Imm) const {
33672cab237bSDimitry Andric   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
33682cab237bSDimitry Andric   bool PostRA = !MRI.isSSA();
33692cab237bSDimitry Andric   // Exit early if we can't convert this.
3370*b5893f02SDimitry Andric   if ((ConstantOpNo != III.OpNoForForwarding) && !III.IsCommutative)
33712cab237bSDimitry Andric     return false;
33722cab237bSDimitry Andric   if (Imm % III.ImmMustBeMultipleOf)
33732cab237bSDimitry Andric     return false;
337430785c0eSDimitry Andric   if (III.TruncateImmTo)
337530785c0eSDimitry Andric     Imm &= ((1 << III.TruncateImmTo) - 1);
33762cab237bSDimitry Andric   if (III.SignedImm) {
33772cab237bSDimitry Andric     APInt ActualValue(64, Imm, true);
33782cab237bSDimitry Andric     if (!ActualValue.isSignedIntN(III.ImmWidth))
33792cab237bSDimitry Andric       return false;
33802cab237bSDimitry Andric   } else {
33812cab237bSDimitry Andric     uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
33822cab237bSDimitry Andric     if ((uint64_t)Imm > UnsignedMax)
33832cab237bSDimitry Andric       return false;
33842cab237bSDimitry Andric   }
33852cab237bSDimitry Andric 
33862cab237bSDimitry Andric   // If we're post-RA, the instructions don't agree on whether register zero is
33872cab237bSDimitry Andric   // special, we can transform this as long as the register operand that will
33882cab237bSDimitry Andric   // end up in the location where zero is special isn't R0.
33892cab237bSDimitry Andric   if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
33902cab237bSDimitry Andric     unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :
33912cab237bSDimitry Andric       III.ZeroIsSpecialNew + 1;
33922cab237bSDimitry Andric     unsigned OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
33932cab237bSDimitry Andric     unsigned NewZeroReg = MI.getOperand(III.ZeroIsSpecialNew).getReg();
33942cab237bSDimitry Andric     // If R0 is in the operand where zero is special for the new instruction,
33952cab237bSDimitry Andric     // it is unsafe to transform if the constant operand isn't that operand.
33962cab237bSDimitry Andric     if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
33972cab237bSDimitry Andric         ConstantOpNo != III.ZeroIsSpecialNew)
33982cab237bSDimitry Andric       return false;
33992cab237bSDimitry Andric     if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
34002cab237bSDimitry Andric         ConstantOpNo != PosForOrigZero)
34012cab237bSDimitry Andric       return false;
34022cab237bSDimitry Andric   }
34032cab237bSDimitry Andric 
34042cab237bSDimitry Andric   unsigned Opc = MI.getOpcode();
34052cab237bSDimitry Andric   bool SpecialShift32 =
34062cab237bSDimitry Andric     Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo;
34072cab237bSDimitry Andric   bool SpecialShift64 =
34082cab237bSDimitry Andric     Opc == PPC::SLD || Opc == PPC::SLDo || Opc == PPC::SRD || Opc == PPC::SRDo;
34092cab237bSDimitry Andric   bool SetCR = Opc == PPC::SLWo || Opc == PPC::SRWo ||
34102cab237bSDimitry Andric     Opc == PPC::SLDo || Opc == PPC::SRDo;
34112cab237bSDimitry Andric   bool RightShift =
34122cab237bSDimitry Andric     Opc == PPC::SRW || Opc == PPC::SRWo || Opc == PPC::SRD || Opc == PPC::SRDo;
34132cab237bSDimitry Andric 
34142cab237bSDimitry Andric   MI.setDesc(get(III.ImmOpcode));
3415*b5893f02SDimitry Andric   if (ConstantOpNo == III.OpNoForForwarding) {
34162cab237bSDimitry Andric     // Converting shifts to immediate form is a bit tricky since they may do
34172cab237bSDimitry Andric     // one of three things:
34182cab237bSDimitry Andric     // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero
34192cab237bSDimitry Andric     // 2. If the shift amount is zero, the result is unchanged (save for maybe
34202cab237bSDimitry Andric     //    setting CR0)
34212cab237bSDimitry Andric     // 3. If the shift amount is in [1, OpSize), it's just a shift
34222cab237bSDimitry Andric     if (SpecialShift32 || SpecialShift64) {
34232cab237bSDimitry Andric       LoadImmediateInfo LII;
34242cab237bSDimitry Andric       LII.Imm = 0;
34252cab237bSDimitry Andric       LII.SetCR = SetCR;
34262cab237bSDimitry Andric       LII.Is64Bit = SpecialShift64;
34272cab237bSDimitry Andric       uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
34282cab237bSDimitry Andric       if (Imm & (SpecialShift32 ? 0x20 : 0x40))
34292cab237bSDimitry Andric         replaceInstrWithLI(MI, LII);
34302cab237bSDimitry Andric       // Shifts by zero don't change the value. If we don't need to set CR0,
34312cab237bSDimitry Andric       // just convert this to a COPY. Can't do this post-RA since we've already
34322cab237bSDimitry Andric       // cleaned up the copies.
34332cab237bSDimitry Andric       else if (!SetCR && ShAmt == 0 && !PostRA) {
34342cab237bSDimitry Andric         MI.RemoveOperand(2);
34352cab237bSDimitry Andric         MI.setDesc(get(PPC::COPY));
34362cab237bSDimitry Andric       } else {
34372cab237bSDimitry Andric         // The 32 bit and 64 bit instructions are quite different.
34382cab237bSDimitry Andric         if (SpecialShift32) {
34392cab237bSDimitry Andric           // Left shifts use (N, 0, 31-N), right shifts use (32-N, N, 31).
34402cab237bSDimitry Andric           uint64_t SH = RightShift ? 32 - ShAmt : ShAmt;
34412cab237bSDimitry Andric           uint64_t MB = RightShift ? ShAmt : 0;
34422cab237bSDimitry Andric           uint64_t ME = RightShift ? 31 : 31 - ShAmt;
3443*b5893f02SDimitry Andric           replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
34442cab237bSDimitry Andric           MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
34452cab237bSDimitry Andric             .addImm(ME);
34462cab237bSDimitry Andric         } else {
34472cab237bSDimitry Andric           // Left shifts use (N, 63-N), right shifts use (64-N, N).
34482cab237bSDimitry Andric           uint64_t SH = RightShift ? 64 - ShAmt : ShAmt;
34492cab237bSDimitry Andric           uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
3450*b5893f02SDimitry Andric           replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
34512cab237bSDimitry Andric           MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
34522cab237bSDimitry Andric         }
34532cab237bSDimitry Andric       }
34542cab237bSDimitry Andric     } else
3455*b5893f02SDimitry Andric       replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
34562cab237bSDimitry Andric   }
34572cab237bSDimitry Andric   // Convert commutative instructions (switch the operands and convert the
34582cab237bSDimitry Andric   // desired one to an immediate.
34592cab237bSDimitry Andric   else if (III.IsCommutative) {
3460*b5893f02SDimitry Andric     replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
3461*b5893f02SDimitry Andric     swapMIOperands(MI, ConstantOpNo, III.OpNoForForwarding);
34622cab237bSDimitry Andric   } else
34632cab237bSDimitry Andric     llvm_unreachable("Should have exited early!");
34642cab237bSDimitry Andric 
34652cab237bSDimitry Andric   // For instructions for which the constant register replaces a different
34662cab237bSDimitry Andric   // operand than where the immediate goes, we need to swap them.
3467*b5893f02SDimitry Andric   if (III.OpNoForForwarding != III.ImmOpNo)
3468*b5893f02SDimitry Andric     swapMIOperands(MI, III.OpNoForForwarding, III.ImmOpNo);
34692cab237bSDimitry Andric 
3470*b5893f02SDimitry Andric   // If the special R0/X0 register index are different for original instruction
3471*b5893f02SDimitry Andric   // and new instruction, we need to fix up the register class in new
3472*b5893f02SDimitry Andric   // instruction.
34732cab237bSDimitry Andric   if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
3474*b5893f02SDimitry Andric     if (III.ZeroIsSpecialNew) {
3475*b5893f02SDimitry Andric       // If operand at III.ZeroIsSpecialNew is physical reg(eg: ZERO/ZERO8), no
3476*b5893f02SDimitry Andric       // need to fix up register class.
34772cab237bSDimitry Andric       unsigned RegToModify = MI.getOperand(III.ZeroIsSpecialNew).getReg();
3478*b5893f02SDimitry Andric       if (TargetRegisterInfo::isVirtualRegister(RegToModify)) {
34792cab237bSDimitry Andric         const TargetRegisterClass *NewRC =
34802cab237bSDimitry Andric           MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
34812cab237bSDimitry Andric           &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
34822cab237bSDimitry Andric         MRI.setRegClass(RegToModify, NewRC);
34832cab237bSDimitry Andric       }
34842cab237bSDimitry Andric     }
3485*b5893f02SDimitry Andric   }
34862cab237bSDimitry Andric   return true;
34872cab237bSDimitry Andric }
34882cab237bSDimitry Andric 
3489d88c1a5aSDimitry Andric const TargetRegisterClass *
updatedRC(const TargetRegisterClass * RC) const3490d88c1a5aSDimitry Andric PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {
3491d88c1a5aSDimitry Andric   if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
3492d88c1a5aSDimitry Andric     return &PPC::VSRCRegClass;
3493d88c1a5aSDimitry Andric   return RC;
3494d88c1a5aSDimitry Andric }
3495f9448bf3SDimitry Andric 
getRecordFormOpcode(unsigned Opcode)3496f9448bf3SDimitry Andric int PPCInstrInfo::getRecordFormOpcode(unsigned Opcode) {
3497f9448bf3SDimitry Andric   return PPC::getRecordFormOpcode(Opcode);
3498f9448bf3SDimitry Andric }
34992cab237bSDimitry Andric 
35002cab237bSDimitry Andric // This function returns true if the machine instruction
35012cab237bSDimitry Andric // always outputs a value by sign-extending a 32 bit value,
35022cab237bSDimitry Andric // i.e. 0 to 31-th bits are same as 32-th bit.
isSignExtendingOp(const MachineInstr & MI)35032cab237bSDimitry Andric static bool isSignExtendingOp(const MachineInstr &MI) {
35042cab237bSDimitry Andric   int Opcode = MI.getOpcode();
35052cab237bSDimitry Andric   if (Opcode == PPC::LI     || Opcode == PPC::LI8     ||
35062cab237bSDimitry Andric       Opcode == PPC::LIS    || Opcode == PPC::LIS8    ||
35072cab237bSDimitry Andric       Opcode == PPC::SRAW   || Opcode == PPC::SRAWo   ||
35082cab237bSDimitry Andric       Opcode == PPC::SRAWI  || Opcode == PPC::SRAWIo  ||
35092cab237bSDimitry Andric       Opcode == PPC::LWA    || Opcode == PPC::LWAX    ||
35102cab237bSDimitry Andric       Opcode == PPC::LWA_32 || Opcode == PPC::LWAX_32 ||
35112cab237bSDimitry Andric       Opcode == PPC::LHA    || Opcode == PPC::LHAX    ||
35122cab237bSDimitry Andric       Opcode == PPC::LHA8   || Opcode == PPC::LHAX8   ||
35132cab237bSDimitry Andric       Opcode == PPC::LBZ    || Opcode == PPC::LBZX    ||
35142cab237bSDimitry Andric       Opcode == PPC::LBZ8   || Opcode == PPC::LBZX8   ||
35152cab237bSDimitry Andric       Opcode == PPC::LBZU   || Opcode == PPC::LBZUX   ||
35162cab237bSDimitry Andric       Opcode == PPC::LBZU8  || Opcode == PPC::LBZUX8  ||
35172cab237bSDimitry Andric       Opcode == PPC::LHZ    || Opcode == PPC::LHZX    ||
35182cab237bSDimitry Andric       Opcode == PPC::LHZ8   || Opcode == PPC::LHZX8   ||
35192cab237bSDimitry Andric       Opcode == PPC::LHZU   || Opcode == PPC::LHZUX   ||
35202cab237bSDimitry Andric       Opcode == PPC::LHZU8  || Opcode == PPC::LHZUX8  ||
35212cab237bSDimitry Andric       Opcode == PPC::EXTSB  || Opcode == PPC::EXTSBo  ||
35222cab237bSDimitry Andric       Opcode == PPC::EXTSH  || Opcode == PPC::EXTSHo  ||
35232cab237bSDimitry Andric       Opcode == PPC::EXTSB8 || Opcode == PPC::EXTSH8  ||
35242cab237bSDimitry Andric       Opcode == PPC::EXTSW  || Opcode == PPC::EXTSWo  ||
3525*b5893f02SDimitry Andric       Opcode == PPC::SETB   || Opcode == PPC::SETB8   ||
35262cab237bSDimitry Andric       Opcode == PPC::EXTSH8_32_64 || Opcode == PPC::EXTSW_32_64 ||
35272cab237bSDimitry Andric       Opcode == PPC::EXTSB8_32_64)
35282cab237bSDimitry Andric     return true;
35292cab237bSDimitry Andric 
35302cab237bSDimitry Andric   if (Opcode == PPC::RLDICL && MI.getOperand(3).getImm() >= 33)
35312cab237bSDimitry Andric     return true;
35322cab237bSDimitry Andric 
35332cab237bSDimitry Andric   if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINMo ||
35342cab237bSDimitry Andric        Opcode == PPC::RLWNM  || Opcode == PPC::RLWNMo) &&
35352cab237bSDimitry Andric       MI.getOperand(3).getImm() > 0 &&
35362cab237bSDimitry Andric       MI.getOperand(3).getImm() <= MI.getOperand(4).getImm())
35372cab237bSDimitry Andric     return true;
35382cab237bSDimitry Andric 
35392cab237bSDimitry Andric   return false;
35402cab237bSDimitry Andric }
35412cab237bSDimitry Andric 
35422cab237bSDimitry Andric // This function returns true if the machine instruction
35432cab237bSDimitry Andric // always outputs zeros in higher 32 bits.
isZeroExtendingOp(const MachineInstr & MI)35442cab237bSDimitry Andric static bool isZeroExtendingOp(const MachineInstr &MI) {
35452cab237bSDimitry Andric   int Opcode = MI.getOpcode();
35462cab237bSDimitry Andric   // The 16-bit immediate is sign-extended in li/lis.
35472cab237bSDimitry Andric   // If the most significant bit is zero, all higher bits are zero.
35482cab237bSDimitry Andric   if (Opcode == PPC::LI  || Opcode == PPC::LI8 ||
35492cab237bSDimitry Andric       Opcode == PPC::LIS || Opcode == PPC::LIS8) {
35502cab237bSDimitry Andric     int64_t Imm = MI.getOperand(1).getImm();
35512cab237bSDimitry Andric     if (((uint64_t)Imm & ~0x7FFFuLL) == 0)
35522cab237bSDimitry Andric       return true;
35532cab237bSDimitry Andric   }
35542cab237bSDimitry Andric 
35552cab237bSDimitry Andric   // We have some variations of rotate-and-mask instructions
35562cab237bSDimitry Andric   // that clear higher 32-bits.
35572cab237bSDimitry Andric   if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICLo ||
35582cab237bSDimitry Andric        Opcode == PPC::RLDCL  || Opcode == PPC::RLDCLo  ||
35592cab237bSDimitry Andric        Opcode == PPC::RLDICL_32_64) &&
35602cab237bSDimitry Andric       MI.getOperand(3).getImm() >= 32)
35612cab237bSDimitry Andric     return true;
35622cab237bSDimitry Andric 
35632cab237bSDimitry Andric   if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDICo) &&
35642cab237bSDimitry Andric       MI.getOperand(3).getImm() >= 32 &&
35652cab237bSDimitry Andric       MI.getOperand(3).getImm() <= 63 - MI.getOperand(2).getImm())
35662cab237bSDimitry Andric     return true;
35672cab237bSDimitry Andric 
35682cab237bSDimitry Andric   if ((Opcode == PPC::RLWINM  || Opcode == PPC::RLWINMo ||
35692cab237bSDimitry Andric        Opcode == PPC::RLWNM   || Opcode == PPC::RLWNMo  ||
35702cab237bSDimitry Andric        Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
35712cab237bSDimitry Andric       MI.getOperand(3).getImm() <= MI.getOperand(4).getImm())
35722cab237bSDimitry Andric     return true;
35732cab237bSDimitry Andric 
35742cab237bSDimitry Andric   // There are other instructions that clear higher 32-bits.
35752cab237bSDimitry Andric   if (Opcode == PPC::CNTLZW  || Opcode == PPC::CNTLZWo ||
35762cab237bSDimitry Andric       Opcode == PPC::CNTTZW  || Opcode == PPC::CNTTZWo ||
35772cab237bSDimitry Andric       Opcode == PPC::CNTLZW8 || Opcode == PPC::CNTTZW8 ||
35782cab237bSDimitry Andric       Opcode == PPC::CNTLZD  || Opcode == PPC::CNTLZDo ||
35792cab237bSDimitry Andric       Opcode == PPC::CNTTZD  || Opcode == PPC::CNTTZDo ||
35802cab237bSDimitry Andric       Opcode == PPC::POPCNTD || Opcode == PPC::POPCNTW ||
35812cab237bSDimitry Andric       Opcode == PPC::SLW     || Opcode == PPC::SLWo    ||
35822cab237bSDimitry Andric       Opcode == PPC::SRW     || Opcode == PPC::SRWo    ||
35832cab237bSDimitry Andric       Opcode == PPC::SLW8    || Opcode == PPC::SRW8    ||
35842cab237bSDimitry Andric       Opcode == PPC::SLWI    || Opcode == PPC::SLWIo   ||
35852cab237bSDimitry Andric       Opcode == PPC::SRWI    || Opcode == PPC::SRWIo   ||
35862cab237bSDimitry Andric       Opcode == PPC::LWZ     || Opcode == PPC::LWZX    ||
35872cab237bSDimitry Andric       Opcode == PPC::LWZU    || Opcode == PPC::LWZUX   ||
35882cab237bSDimitry Andric       Opcode == PPC::LWBRX   || Opcode == PPC::LHBRX   ||
35892cab237bSDimitry Andric       Opcode == PPC::LHZ     || Opcode == PPC::LHZX    ||
35902cab237bSDimitry Andric       Opcode == PPC::LHZU    || Opcode == PPC::LHZUX   ||
35912cab237bSDimitry Andric       Opcode == PPC::LBZ     || Opcode == PPC::LBZX    ||
35922cab237bSDimitry Andric       Opcode == PPC::LBZU    || Opcode == PPC::LBZUX   ||
35932cab237bSDimitry Andric       Opcode == PPC::LWZ8    || Opcode == PPC::LWZX8   ||
35942cab237bSDimitry Andric       Opcode == PPC::LWZU8   || Opcode == PPC::LWZUX8  ||
35952cab237bSDimitry Andric       Opcode == PPC::LWBRX8  || Opcode == PPC::LHBRX8  ||
35962cab237bSDimitry Andric       Opcode == PPC::LHZ8    || Opcode == PPC::LHZX8   ||
35972cab237bSDimitry Andric       Opcode == PPC::LHZU8   || Opcode == PPC::LHZUX8  ||
35982cab237bSDimitry Andric       Opcode == PPC::LBZ8    || Opcode == PPC::LBZX8   ||
35992cab237bSDimitry Andric       Opcode == PPC::LBZU8   || Opcode == PPC::LBZUX8  ||
36002cab237bSDimitry Andric       Opcode == PPC::ANDIo   || Opcode == PPC::ANDISo  ||
36012cab237bSDimitry Andric       Opcode == PPC::ROTRWI  || Opcode == PPC::ROTRWIo ||
36022cab237bSDimitry Andric       Opcode == PPC::EXTLWI  || Opcode == PPC::EXTLWIo ||
36032cab237bSDimitry Andric       Opcode == PPC::MFVSRWZ)
36042cab237bSDimitry Andric     return true;
36052cab237bSDimitry Andric 
36062cab237bSDimitry Andric   return false;
36072cab237bSDimitry Andric }
36082cab237bSDimitry Andric 
36092cab237bSDimitry Andric // This function returns true if the input MachineInstr is a TOC save
36102cab237bSDimitry Andric // instruction.
isTOCSaveMI(const MachineInstr & MI) const36112cab237bSDimitry Andric bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
36122cab237bSDimitry Andric   if (!MI.getOperand(1).isImm() || !MI.getOperand(2).isReg())
36132cab237bSDimitry Andric     return false;
36142cab237bSDimitry Andric   unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
36152cab237bSDimitry Andric   unsigned StackOffset = MI.getOperand(1).getImm();
36162cab237bSDimitry Andric   unsigned StackReg = MI.getOperand(2).getReg();
36172cab237bSDimitry Andric   if (StackReg == PPC::X1 && StackOffset == TOCSaveOffset)
36182cab237bSDimitry Andric     return true;
36192cab237bSDimitry Andric 
36202cab237bSDimitry Andric   return false;
36212cab237bSDimitry Andric }
36222cab237bSDimitry Andric 
36232cab237bSDimitry Andric // We limit the max depth to track incoming values of PHIs or binary ops
36244ba319b5SDimitry Andric // (e.g. AND) to avoid excessive cost.
36252cab237bSDimitry Andric const unsigned MAX_DEPTH = 1;
36262cab237bSDimitry Andric 
36272cab237bSDimitry Andric bool
isSignOrZeroExtended(const MachineInstr & MI,bool SignExt,const unsigned Depth) const36282cab237bSDimitry Andric PPCInstrInfo::isSignOrZeroExtended(const MachineInstr &MI, bool SignExt,
36292cab237bSDimitry Andric                                    const unsigned Depth) const {
36302cab237bSDimitry Andric   const MachineFunction *MF = MI.getParent()->getParent();
36312cab237bSDimitry Andric   const MachineRegisterInfo *MRI = &MF->getRegInfo();
36322cab237bSDimitry Andric 
36332cab237bSDimitry Andric   // If we know this instruction returns sign- or zero-extended result,
36342cab237bSDimitry Andric   // return true.
36352cab237bSDimitry Andric   if (SignExt ? isSignExtendingOp(MI):
36362cab237bSDimitry Andric                 isZeroExtendingOp(MI))
36372cab237bSDimitry Andric     return true;
36382cab237bSDimitry Andric 
36392cab237bSDimitry Andric   switch (MI.getOpcode()) {
36402cab237bSDimitry Andric   case PPC::COPY: {
36412cab237bSDimitry Andric     unsigned SrcReg = MI.getOperand(1).getReg();
36422cab237bSDimitry Andric 
36432cab237bSDimitry Andric     // In both ELFv1 and v2 ABI, method parameters and the return value
36442cab237bSDimitry Andric     // are sign- or zero-extended.
36452cab237bSDimitry Andric     if (MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
36462cab237bSDimitry Andric       const PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
36472cab237bSDimitry Andric       // We check the ZExt/SExt flags for a method parameter.
36482cab237bSDimitry Andric       if (MI.getParent()->getBasicBlock() ==
36492cab237bSDimitry Andric           &MF->getFunction().getEntryBlock()) {
36502cab237bSDimitry Andric         unsigned VReg = MI.getOperand(0).getReg();
36512cab237bSDimitry Andric         if (MF->getRegInfo().isLiveIn(VReg))
36522cab237bSDimitry Andric           return SignExt ? FuncInfo->isLiveInSExt(VReg) :
36532cab237bSDimitry Andric                            FuncInfo->isLiveInZExt(VReg);
36542cab237bSDimitry Andric       }
36552cab237bSDimitry Andric 
36562cab237bSDimitry Andric       // For a method return value, we check the ZExt/SExt flags in attribute.
36572cab237bSDimitry Andric       // We assume the following code sequence for method call.
36582cab237bSDimitry Andric       //   ADJCALLSTACKDOWN 32, implicit dead %r1, implicit %r1
36592cab237bSDimitry Andric       //   BL8_NOP @func,...
36602cab237bSDimitry Andric       //   ADJCALLSTACKUP 32, 0, implicit dead %r1, implicit %r1
36612cab237bSDimitry Andric       //   %5 = COPY %x3; G8RC:%5
36622cab237bSDimitry Andric       if (SrcReg == PPC::X3) {
36632cab237bSDimitry Andric         const MachineBasicBlock *MBB = MI.getParent();
36642cab237bSDimitry Andric         MachineBasicBlock::const_instr_iterator II =
36652cab237bSDimitry Andric           MachineBasicBlock::const_instr_iterator(&MI);
36662cab237bSDimitry Andric         if (II != MBB->instr_begin() &&
36672cab237bSDimitry Andric             (--II)->getOpcode() == PPC::ADJCALLSTACKUP) {
36682cab237bSDimitry Andric           const MachineInstr &CallMI = *(--II);
36692cab237bSDimitry Andric           if (CallMI.isCall() && CallMI.getOperand(0).isGlobal()) {
36702cab237bSDimitry Andric             const Function *CalleeFn =
36712cab237bSDimitry Andric               dyn_cast<Function>(CallMI.getOperand(0).getGlobal());
36722cab237bSDimitry Andric             if (!CalleeFn)
36732cab237bSDimitry Andric               return false;
36742cab237bSDimitry Andric             const IntegerType *IntTy =
36752cab237bSDimitry Andric               dyn_cast<IntegerType>(CalleeFn->getReturnType());
36762cab237bSDimitry Andric             const AttributeSet &Attrs =
36772cab237bSDimitry Andric               CalleeFn->getAttributes().getRetAttributes();
36782cab237bSDimitry Andric             if (IntTy && IntTy->getBitWidth() <= 32)
36792cab237bSDimitry Andric               return Attrs.hasAttribute(SignExt ? Attribute::SExt :
36802cab237bSDimitry Andric                                                   Attribute::ZExt);
36812cab237bSDimitry Andric           }
36822cab237bSDimitry Andric         }
36832cab237bSDimitry Andric       }
36842cab237bSDimitry Andric     }
36852cab237bSDimitry Andric 
36862cab237bSDimitry Andric     // If this is a copy from another register, we recursively check source.
36872cab237bSDimitry Andric     if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
36882cab237bSDimitry Andric       return false;
36892cab237bSDimitry Andric     const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
36902cab237bSDimitry Andric     if (SrcMI != NULL)
36912cab237bSDimitry Andric       return isSignOrZeroExtended(*SrcMI, SignExt, Depth);
36922cab237bSDimitry Andric 
36932cab237bSDimitry Andric     return false;
36942cab237bSDimitry Andric   }
36952cab237bSDimitry Andric 
36962cab237bSDimitry Andric   case PPC::ANDIo:
36972cab237bSDimitry Andric   case PPC::ANDISo:
36982cab237bSDimitry Andric   case PPC::ORI:
36992cab237bSDimitry Andric   case PPC::ORIS:
37002cab237bSDimitry Andric   case PPC::XORI:
37012cab237bSDimitry Andric   case PPC::XORIS:
37022cab237bSDimitry Andric   case PPC::ANDIo8:
37032cab237bSDimitry Andric   case PPC::ANDISo8:
37042cab237bSDimitry Andric   case PPC::ORI8:
37052cab237bSDimitry Andric   case PPC::ORIS8:
37062cab237bSDimitry Andric   case PPC::XORI8:
37072cab237bSDimitry Andric   case PPC::XORIS8: {
37082cab237bSDimitry Andric     // logical operation with 16-bit immediate does not change the upper bits.
37092cab237bSDimitry Andric     // So, we track the operand register as we do for register copy.
37102cab237bSDimitry Andric     unsigned SrcReg = MI.getOperand(1).getReg();
37112cab237bSDimitry Andric     if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
37122cab237bSDimitry Andric       return false;
37132cab237bSDimitry Andric     const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
37142cab237bSDimitry Andric     if (SrcMI != NULL)
37152cab237bSDimitry Andric       return isSignOrZeroExtended(*SrcMI, SignExt, Depth);
37162cab237bSDimitry Andric 
37172cab237bSDimitry Andric     return false;
37182cab237bSDimitry Andric   }
37192cab237bSDimitry Andric 
37202cab237bSDimitry Andric   // If all incoming values are sign-/zero-extended,
37212cab237bSDimitry Andric   // the output of OR, ISEL or PHI is also sign-/zero-extended.
37222cab237bSDimitry Andric   case PPC::OR:
37232cab237bSDimitry Andric   case PPC::OR8:
37242cab237bSDimitry Andric   case PPC::ISEL:
37252cab237bSDimitry Andric   case PPC::PHI: {
37262cab237bSDimitry Andric     if (Depth >= MAX_DEPTH)
37272cab237bSDimitry Andric       return false;
37282cab237bSDimitry Andric 
37292cab237bSDimitry Andric     // The input registers for PHI are operand 1, 3, ...
37302cab237bSDimitry Andric     // The input registers for others are operand 1 and 2.
37312cab237bSDimitry Andric     unsigned E = 3, D = 1;
37322cab237bSDimitry Andric     if (MI.getOpcode() == PPC::PHI) {
37332cab237bSDimitry Andric       E = MI.getNumOperands();
37342cab237bSDimitry Andric       D = 2;
37352cab237bSDimitry Andric     }
37362cab237bSDimitry Andric 
37372cab237bSDimitry Andric     for (unsigned I = 1; I != E; I += D) {
37382cab237bSDimitry Andric       if (MI.getOperand(I).isReg()) {
37392cab237bSDimitry Andric         unsigned SrcReg = MI.getOperand(I).getReg();
37402cab237bSDimitry Andric         if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
37412cab237bSDimitry Andric           return false;
37422cab237bSDimitry Andric         const MachineInstr *SrcMI = MRI->getVRegDef(SrcReg);
37432cab237bSDimitry Andric         if (SrcMI == NULL || !isSignOrZeroExtended(*SrcMI, SignExt, Depth+1))
37442cab237bSDimitry Andric           return false;
37452cab237bSDimitry Andric       }
37462cab237bSDimitry Andric       else
37472cab237bSDimitry Andric         return false;
37482cab237bSDimitry Andric     }
37492cab237bSDimitry Andric     return true;
37502cab237bSDimitry Andric   }
37512cab237bSDimitry Andric 
37522cab237bSDimitry Andric   // If at least one of the incoming values of an AND is zero extended
37532cab237bSDimitry Andric   // then the output is also zero-extended. If both of the incoming values
37542cab237bSDimitry Andric   // are sign-extended then the output is also sign extended.
37552cab237bSDimitry Andric   case PPC::AND:
37562cab237bSDimitry Andric   case PPC::AND8: {
37572cab237bSDimitry Andric     if (Depth >= MAX_DEPTH)
37582cab237bSDimitry Andric        return false;
37592cab237bSDimitry Andric 
37602cab237bSDimitry Andric     assert(MI.getOperand(1).isReg() && MI.getOperand(2).isReg());
37612cab237bSDimitry Andric 
37622cab237bSDimitry Andric     unsigned SrcReg1 = MI.getOperand(1).getReg();
37632cab237bSDimitry Andric     unsigned SrcReg2 = MI.getOperand(2).getReg();
37642cab237bSDimitry Andric 
37652cab237bSDimitry Andric     if (!TargetRegisterInfo::isVirtualRegister(SrcReg1) ||
37662cab237bSDimitry Andric         !TargetRegisterInfo::isVirtualRegister(SrcReg2))
37672cab237bSDimitry Andric        return false;
37682cab237bSDimitry Andric 
37692cab237bSDimitry Andric     const MachineInstr *MISrc1 = MRI->getVRegDef(SrcReg1);
37702cab237bSDimitry Andric     const MachineInstr *MISrc2 = MRI->getVRegDef(SrcReg2);
37712cab237bSDimitry Andric     if (!MISrc1 || !MISrc2)
37722cab237bSDimitry Andric         return false;
37732cab237bSDimitry Andric 
37742cab237bSDimitry Andric     if(SignExt)
37752cab237bSDimitry Andric         return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) &&
37762cab237bSDimitry Andric                isSignOrZeroExtended(*MISrc2, SignExt, Depth+1);
37772cab237bSDimitry Andric     else
37782cab237bSDimitry Andric         return isSignOrZeroExtended(*MISrc1, SignExt, Depth+1) ||
37792cab237bSDimitry Andric                isSignOrZeroExtended(*MISrc2, SignExt, Depth+1);
37802cab237bSDimitry Andric   }
37812cab237bSDimitry Andric 
37822cab237bSDimitry Andric   default:
37832cab237bSDimitry Andric     break;
37842cab237bSDimitry Andric   }
37852cab237bSDimitry Andric   return false;
37862cab237bSDimitry Andric }
3787