xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp (revision 36b606ae6aa4b24061096ba18582e0a08ccd5dba)
10b57cec5SDimitry Andric //===-- PPCInstrInfo.cpp - PowerPC Instruction Information ----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains the PowerPC implementation of the TargetInstrInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "PPCInstrInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
150b57cec5SDimitry Andric #include "PPC.h"
160b57cec5SDimitry Andric #include "PPCHazardRecognizers.h"
170b57cec5SDimitry Andric #include "PPCInstrBuilder.h"
180b57cec5SDimitry Andric #include "PPCMachineFunctionInfo.h"
190b57cec5SDimitry Andric #include "PPCTargetMachine.h"
200b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
210b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
225ffd83dbSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
245f757f3fSDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h"
25bdd1243dSDimitry Andric #include "llvm/CodeGen/MachineCombinerPattern.h"
26e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
33e8d8bef9SDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h"
34e8d8bef9SDimitry Andric #include "llvm/CodeGen/RegisterPressure.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/ScheduleDAG.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/StackMaps.h"
380b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
390b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
40349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
410b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
420b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
430b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
440b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric using namespace llvm;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric #define DEBUG_TYPE "ppc-instr-info"
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric #define GET_INSTRMAP_INFO
510b57cec5SDimitry Andric #define GET_INSTRINFO_CTOR_DTOR
520b57cec5SDimitry Andric #include "PPCGenInstrInfo.inc"
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric STATISTIC(NumStoreSPILLVSRRCAsVec,
550b57cec5SDimitry Andric           "Number of spillvsrrc spilled to stack as vec");
560b57cec5SDimitry Andric STATISTIC(NumStoreSPILLVSRRCAsGpr,
570b57cec5SDimitry Andric           "Number of spillvsrrc spilled to stack as gpr");
580b57cec5SDimitry Andric STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");
590b57cec5SDimitry Andric STATISTIC(CmpIselsConverted,
600b57cec5SDimitry Andric           "Number of ISELs that depend on comparison of constants converted");
610b57cec5SDimitry Andric STATISTIC(MissedConvertibleImmediateInstrs,
620b57cec5SDimitry Andric           "Number of compare-immediate instructions fed by constants");
630b57cec5SDimitry Andric STATISTIC(NumRcRotatesConvertedToRcAnd,
640b57cec5SDimitry Andric           "Number of record-form rotates converted to record-form andi");
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric static cl::
670b57cec5SDimitry Andric opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
680b57cec5SDimitry Andric             cl::desc("Disable analysis for CTR loops"));
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric static cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt",
710b57cec5SDimitry Andric cl::desc("Disable compare instruction optimization"), cl::Hidden);
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric static cl::opt<bool> VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy",
740b57cec5SDimitry Andric cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),
750b57cec5SDimitry Andric cl::Hidden);
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric static cl::opt<bool>
780b57cec5SDimitry Andric UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden,
790b57cec5SDimitry Andric   cl::desc("Use the old (incorrect) instruction latency calculation"));
800b57cec5SDimitry Andric 
81e8d8bef9SDimitry Andric static cl::opt<float>
82e8d8bef9SDimitry Andric     FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5),
83e8d8bef9SDimitry Andric                 cl::desc("register pressure factor for the transformations."));
84e8d8bef9SDimitry Andric 
85e8d8bef9SDimitry Andric static cl::opt<bool> EnableFMARegPressureReduction(
86e8d8bef9SDimitry Andric     "ppc-fma-rp-reduction", cl::Hidden, cl::init(true),
87e8d8bef9SDimitry Andric     cl::desc("enable register pressure reduce in machine combiner pass."));
88e8d8bef9SDimitry Andric 
890b57cec5SDimitry Andric // Pin the vtable to this file.
900b57cec5SDimitry Andric void PPCInstrInfo::anchor() {}
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric PPCInstrInfo::PPCInstrInfo(PPCSubtarget &STI)
930b57cec5SDimitry Andric     : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP,
940b57cec5SDimitry Andric                       /* CatchRetOpcode */ -1,
950b57cec5SDimitry Andric                       STI.isPPC64() ? PPC::BLR8 : PPC::BLR),
960b57cec5SDimitry Andric       Subtarget(STI), RI(STI.getTargetMachine()) {}
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric /// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
990b57cec5SDimitry Andric /// this target when scheduling the DAG.
1000b57cec5SDimitry Andric ScheduleHazardRecognizer *
1010b57cec5SDimitry Andric PPCInstrInfo::CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI,
1020b57cec5SDimitry Andric                                            const ScheduleDAG *DAG) const {
1030b57cec5SDimitry Andric   unsigned Directive =
104480093f4SDimitry Andric       static_cast<const PPCSubtarget *>(STI)->getCPUDirective();
1050b57cec5SDimitry Andric   if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 ||
1060b57cec5SDimitry Andric       Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) {
1070b57cec5SDimitry Andric     const InstrItineraryData *II =
1080b57cec5SDimitry Andric         static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData();
1090b57cec5SDimitry Andric     return new ScoreboardHazardRecognizer(II, DAG);
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   return TargetInstrInfo::CreateTargetHazardRecognizer(STI, DAG);
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric /// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer
1160b57cec5SDimitry Andric /// to use for this target when scheduling the DAG.
1170b57cec5SDimitry Andric ScheduleHazardRecognizer *
1180b57cec5SDimitry Andric PPCInstrInfo::CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
1190b57cec5SDimitry Andric                                                  const ScheduleDAG *DAG) const {
1200b57cec5SDimitry Andric   unsigned Directive =
121480093f4SDimitry Andric       DAG->MF.getSubtarget<PPCSubtarget>().getCPUDirective();
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // FIXME: Leaving this as-is until we have POWER9 scheduling info
1240b57cec5SDimitry Andric   if (Directive == PPC::DIR_PWR7 || Directive == PPC::DIR_PWR8)
1250b57cec5SDimitry Andric     return new PPCDispatchGroupSBHazardRecognizer(II, DAG);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   // Most subtargets use a PPC970 recognizer.
1280b57cec5SDimitry Andric   if (Directive != PPC::DIR_440 && Directive != PPC::DIR_A2 &&
1290b57cec5SDimitry Andric       Directive != PPC::DIR_E500mc && Directive != PPC::DIR_E5500) {
1300b57cec5SDimitry Andric     assert(DAG->TII && "No InstrInfo?");
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric     return new PPCHazardRecognizer970(*DAG);
1330b57cec5SDimitry Andric   }
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   return new ScoreboardHazardRecognizer(II, DAG);
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric unsigned PPCInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1390b57cec5SDimitry Andric                                        const MachineInstr &MI,
1400b57cec5SDimitry Andric                                        unsigned *PredCost) const {
1410b57cec5SDimitry Andric   if (!ItinData || UseOldLatencyCalc)
1420b57cec5SDimitry Andric     return PPCGenInstrInfo::getInstrLatency(ItinData, MI, PredCost);
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   // The default implementation of getInstrLatency calls getStageLatency, but
1450b57cec5SDimitry Andric   // getStageLatency does not do the right thing for us. While we have
1460b57cec5SDimitry Andric   // itinerary, most cores are fully pipelined, and so the itineraries only
1470b57cec5SDimitry Andric   // express the first part of the pipeline, not every stage. Instead, we need
1480b57cec5SDimitry Andric   // to use the listed output operand cycle number (using operand 0 here, which
1490b57cec5SDimitry Andric   // is an output).
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   unsigned Latency = 1;
1520b57cec5SDimitry Andric   unsigned DefClass = MI.getDesc().getSchedClass();
1530b57cec5SDimitry Andric   for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
1540b57cec5SDimitry Andric     const MachineOperand &MO = MI.getOperand(i);
1550b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
1560b57cec5SDimitry Andric       continue;
1570b57cec5SDimitry Andric 
1585f757f3fSDimitry Andric     std::optional<unsigned> Cycle = ItinData->getOperandCycle(DefClass, i);
1595f757f3fSDimitry Andric     if (!Cycle)
1600b57cec5SDimitry Andric       continue;
1610b57cec5SDimitry Andric 
1625f757f3fSDimitry Andric     Latency = std::max(Latency, *Cycle);
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   return Latency;
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1685f757f3fSDimitry Andric std::optional<unsigned> PPCInstrInfo::getOperandLatency(
1695f757f3fSDimitry Andric     const InstrItineraryData *ItinData, const MachineInstr &DefMI,
1705f757f3fSDimitry Andric     unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {
1715f757f3fSDimitry Andric   std::optional<unsigned> Latency = PPCGenInstrInfo::getOperandLatency(
1725f757f3fSDimitry Andric       ItinData, DefMI, DefIdx, UseMI, UseIdx);
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   if (!DefMI.getParent())
1750b57cec5SDimitry Andric     return Latency;
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   const MachineOperand &DefMO = DefMI.getOperand(DefIdx);
1788bcb0991SDimitry Andric   Register Reg = DefMO.getReg();
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   bool IsRegCR;
181bdd1243dSDimitry Andric   if (Reg.isVirtual()) {
1820b57cec5SDimitry Andric     const MachineRegisterInfo *MRI =
1830b57cec5SDimitry Andric         &DefMI.getParent()->getParent()->getRegInfo();
1840b57cec5SDimitry Andric     IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
1850b57cec5SDimitry Andric               MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
1860b57cec5SDimitry Andric   } else {
1870b57cec5SDimitry Andric     IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
1880b57cec5SDimitry Andric               PPC::CRBITRCRegClass.contains(Reg);
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   if (UseMI.isBranch() && IsRegCR) {
1925f757f3fSDimitry Andric     if (!Latency)
1930b57cec5SDimitry Andric       Latency = getInstrLatency(ItinData, DefMI);
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric     // On some cores, there is an additional delay between writing to a condition
1960b57cec5SDimitry Andric     // register, and using it from a branch.
197480093f4SDimitry Andric     unsigned Directive = Subtarget.getCPUDirective();
1980b57cec5SDimitry Andric     switch (Directive) {
1990b57cec5SDimitry Andric     default: break;
2000b57cec5SDimitry Andric     case PPC::DIR_7400:
2010b57cec5SDimitry Andric     case PPC::DIR_750:
2020b57cec5SDimitry Andric     case PPC::DIR_970:
2030b57cec5SDimitry Andric     case PPC::DIR_E5500:
2040b57cec5SDimitry Andric     case PPC::DIR_PWR4:
2050b57cec5SDimitry Andric     case PPC::DIR_PWR5:
2060b57cec5SDimitry Andric     case PPC::DIR_PWR5X:
2070b57cec5SDimitry Andric     case PPC::DIR_PWR6:
2080b57cec5SDimitry Andric     case PPC::DIR_PWR6X:
2090b57cec5SDimitry Andric     case PPC::DIR_PWR7:
2100b57cec5SDimitry Andric     case PPC::DIR_PWR8:
2110b57cec5SDimitry Andric     // FIXME: Is this needed for POWER9?
2125f757f3fSDimitry Andric     Latency = *Latency + 2;
2130b57cec5SDimitry Andric     break;
2140b57cec5SDimitry Andric     }
2150b57cec5SDimitry Andric   }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   return Latency;
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
2205ffd83dbSDimitry Andric void PPCInstrInfo::setSpecialOperandAttr(MachineInstr &MI,
22106c3fb27SDimitry Andric                                          uint32_t Flags) const {
2225ffd83dbSDimitry Andric   MI.setFlags(Flags);
2235ffd83dbSDimitry Andric   MI.clearFlag(MachineInstr::MIFlag::NoSWrap);
2245ffd83dbSDimitry Andric   MI.clearFlag(MachineInstr::MIFlag::NoUWrap);
2255ffd83dbSDimitry Andric   MI.clearFlag(MachineInstr::MIFlag::IsExact);
2265ffd83dbSDimitry Andric }
2275ffd83dbSDimitry Andric 
2280b57cec5SDimitry Andric // This function does not list all associative and commutative operations, but
2290b57cec5SDimitry Andric // only those worth feeding through the machine combiner in an attempt to
2300b57cec5SDimitry Andric // reduce the critical path. Mostly, this means floating-point operations,
2315ffd83dbSDimitry Andric // because they have high latencies(>=5) (compared to other operations, such as
2320b57cec5SDimitry Andric // and/or, which are also associative and commutative, but have low latencies).
233bdd1243dSDimitry Andric bool PPCInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
234bdd1243dSDimitry Andric                                                bool Invert) const {
235bdd1243dSDimitry Andric   if (Invert)
236bdd1243dSDimitry Andric     return false;
2370b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
2385ffd83dbSDimitry Andric   // Floating point:
2390b57cec5SDimitry Andric   // FP Add:
2400b57cec5SDimitry Andric   case PPC::FADD:
2410b57cec5SDimitry Andric   case PPC::FADDS:
2420b57cec5SDimitry Andric   // FP Multiply:
2430b57cec5SDimitry Andric   case PPC::FMUL:
2440b57cec5SDimitry Andric   case PPC::FMULS:
2450b57cec5SDimitry Andric   // Altivec Add:
2460b57cec5SDimitry Andric   case PPC::VADDFP:
2470b57cec5SDimitry Andric   // VSX Add:
2480b57cec5SDimitry Andric   case PPC::XSADDDP:
2490b57cec5SDimitry Andric   case PPC::XVADDDP:
2500b57cec5SDimitry Andric   case PPC::XVADDSP:
2510b57cec5SDimitry Andric   case PPC::XSADDSP:
2520b57cec5SDimitry Andric   // VSX Multiply:
2530b57cec5SDimitry Andric   case PPC::XSMULDP:
2540b57cec5SDimitry Andric   case PPC::XVMULDP:
2550b57cec5SDimitry Andric   case PPC::XVMULSP:
2560b57cec5SDimitry Andric   case PPC::XSMULSP:
2575ffd83dbSDimitry Andric     return Inst.getFlag(MachineInstr::MIFlag::FmReassoc) &&
2585ffd83dbSDimitry Andric            Inst.getFlag(MachineInstr::MIFlag::FmNsz);
2595ffd83dbSDimitry Andric   // Fixed point:
2605ffd83dbSDimitry Andric   // Multiply:
2615ffd83dbSDimitry Andric   case PPC::MULHD:
2625ffd83dbSDimitry Andric   case PPC::MULLD:
2635ffd83dbSDimitry Andric   case PPC::MULHW:
2645ffd83dbSDimitry Andric   case PPC::MULLW:
2650b57cec5SDimitry Andric     return true;
2660b57cec5SDimitry Andric   default:
2670b57cec5SDimitry Andric     return false;
2680b57cec5SDimitry Andric   }
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
2715ffd83dbSDimitry Andric #define InfoArrayIdxFMAInst 0
2725ffd83dbSDimitry Andric #define InfoArrayIdxFAddInst 1
2735ffd83dbSDimitry Andric #define InfoArrayIdxFMULInst 2
2745ffd83dbSDimitry Andric #define InfoArrayIdxAddOpIdx 3
2755ffd83dbSDimitry Andric #define InfoArrayIdxMULOpIdx 4
276e8d8bef9SDimitry Andric #define InfoArrayIdxFSubInst 5
2775ffd83dbSDimitry Andric // Array keeps info for FMA instructions:
2785ffd83dbSDimitry Andric // Index 0(InfoArrayIdxFMAInst): FMA instruction;
279e8d8bef9SDimitry Andric // Index 1(InfoArrayIdxFAddInst): ADD instruction associated with FMA;
280e8d8bef9SDimitry Andric // Index 2(InfoArrayIdxFMULInst): MUL instruction associated with FMA;
2815ffd83dbSDimitry Andric // Index 3(InfoArrayIdxAddOpIdx): ADD operand index in FMA operands;
2825ffd83dbSDimitry Andric // Index 4(InfoArrayIdxMULOpIdx): first MUL operand index in FMA operands;
283e8d8bef9SDimitry Andric //                                second MUL operand index is plus 1;
284e8d8bef9SDimitry Andric // Index 5(InfoArrayIdxFSubInst): SUB instruction associated with FMA.
285e8d8bef9SDimitry Andric static const uint16_t FMAOpIdxInfo[][6] = {
2865ffd83dbSDimitry Andric     // FIXME: Add more FMA instructions like XSNMADDADP and so on.
287e8d8bef9SDimitry Andric     {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
288e8d8bef9SDimitry Andric     {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
289e8d8bef9SDimitry Andric     {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
290e8d8bef9SDimitry Andric     {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
291e8d8bef9SDimitry Andric     {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
292e8d8bef9SDimitry Andric     {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
2935ffd83dbSDimitry Andric 
2945ffd83dbSDimitry Andric // Check if an opcode is a FMA instruction. If it is, return the index in array
2955ffd83dbSDimitry Andric // FMAOpIdxInfo. Otherwise, return -1.
2965ffd83dbSDimitry Andric int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {
297bdd1243dSDimitry Andric   for (unsigned I = 0; I < std::size(FMAOpIdxInfo); I++)
2985ffd83dbSDimitry Andric     if (FMAOpIdxInfo[I][InfoArrayIdxFMAInst] == Opcode)
2995ffd83dbSDimitry Andric       return I;
3005ffd83dbSDimitry Andric   return -1;
3015ffd83dbSDimitry Andric }
3025ffd83dbSDimitry Andric 
303e8d8bef9SDimitry Andric // On PowerPC target, we have two kinds of patterns related to FMA:
304e8d8bef9SDimitry Andric // 1: Improve ILP.
3055ffd83dbSDimitry Andric // Try to reassociate FMA chains like below:
3065ffd83dbSDimitry Andric //
3075ffd83dbSDimitry Andric // Pattern 1:
3085ffd83dbSDimitry Andric //   A =  FADD X,  Y          (Leaf)
3095ffd83dbSDimitry Andric //   B =  FMA  A,  M21,  M22  (Prev)
3105ffd83dbSDimitry Andric //   C =  FMA  B,  M31,  M32  (Root)
3115ffd83dbSDimitry Andric // -->
3125ffd83dbSDimitry Andric //   A =  FMA  X,  M21,  M22
3135ffd83dbSDimitry Andric //   B =  FMA  Y,  M31,  M32
3145ffd83dbSDimitry Andric //   C =  FADD A,  B
3155ffd83dbSDimitry Andric //
3165ffd83dbSDimitry Andric // Pattern 2:
3175ffd83dbSDimitry Andric //   A =  FMA  X,  M11,  M12  (Leaf)
3185ffd83dbSDimitry Andric //   B =  FMA  A,  M21,  M22  (Prev)
3195ffd83dbSDimitry Andric //   C =  FMA  B,  M31,  M32  (Root)
3205ffd83dbSDimitry Andric // -->
3215ffd83dbSDimitry Andric //   A =  FMUL M11,  M12
3225ffd83dbSDimitry Andric //   B =  FMA  X,  M21,  M22
3235ffd83dbSDimitry Andric //   D =  FMA  A,  M31,  M32
3245ffd83dbSDimitry Andric //   C =  FADD B,  D
3255ffd83dbSDimitry Andric //
3265ffd83dbSDimitry Andric // breaking the dependency between A and B, allowing FMA to be executed in
3275ffd83dbSDimitry Andric // parallel (or back-to-back in a pipeline) instead of depending on each other.
328e8d8bef9SDimitry Andric //
329e8d8bef9SDimitry Andric // 2: Reduce register pressure.
330e8d8bef9SDimitry Andric // Try to reassociate FMA with FSUB and a constant like below:
331fe6060f1SDimitry Andric // C is a floating point const.
332e8d8bef9SDimitry Andric //
333e8d8bef9SDimitry Andric // Pattern 1:
334e8d8bef9SDimitry Andric //   A = FSUB  X,  Y      (Leaf)
335e8d8bef9SDimitry Andric //   D = FMA   B,  C,  A  (Root)
336e8d8bef9SDimitry Andric // -->
337e8d8bef9SDimitry Andric //   A = FMA   B,  Y,  -C
338e8d8bef9SDimitry Andric //   D = FMA   A,  X,  C
339e8d8bef9SDimitry Andric //
340e8d8bef9SDimitry Andric // Pattern 2:
341e8d8bef9SDimitry Andric //   A = FSUB  X,  Y      (Leaf)
342e8d8bef9SDimitry Andric //   D = FMA   B,  A,  C  (Root)
343e8d8bef9SDimitry Andric // -->
344e8d8bef9SDimitry Andric //   A = FMA   B,  Y,  -C
345e8d8bef9SDimitry Andric //   D = FMA   A,  X,  C
346e8d8bef9SDimitry Andric //
347e8d8bef9SDimitry Andric //  Before the transformation, A must be assigned with different hardware
348e8d8bef9SDimitry Andric //  register with D. After the transformation, A and D must be assigned with
349fe6060f1SDimitry Andric //  same hardware register due to TIE attribute of FMA instructions.
350e8d8bef9SDimitry Andric //
3510fca6ea1SDimitry Andric bool PPCInstrInfo::getFMAPatterns(MachineInstr &Root,
3520fca6ea1SDimitry Andric                                   SmallVectorImpl<unsigned> &Patterns,
353e8d8bef9SDimitry Andric                                   bool DoRegPressureReduce) const {
3545ffd83dbSDimitry Andric   MachineBasicBlock *MBB = Root.getParent();
355e8d8bef9SDimitry Andric   const MachineRegisterInfo *MRI = &MBB->getParent()->getRegInfo();
356e8d8bef9SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
3575ffd83dbSDimitry Andric 
3585ffd83dbSDimitry Andric   auto IsAllOpsVirtualReg = [](const MachineInstr &Instr) {
3595ffd83dbSDimitry Andric     for (const auto &MO : Instr.explicit_operands())
360bdd1243dSDimitry Andric       if (!(MO.isReg() && MO.getReg().isVirtual()))
3615ffd83dbSDimitry Andric         return false;
3625ffd83dbSDimitry Andric     return true;
3635ffd83dbSDimitry Andric   };
3645ffd83dbSDimitry Andric 
365e8d8bef9SDimitry Andric   auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,
366e8d8bef9SDimitry Andric                                     unsigned OpType) {
367e8d8bef9SDimitry Andric     if (Instr.getOpcode() !=
368e8d8bef9SDimitry Andric         FMAOpIdxInfo[getFMAOpIdxInfo(Root.getOpcode())][OpType])
3695ffd83dbSDimitry Andric       return false;
3705ffd83dbSDimitry Andric 
3715ffd83dbSDimitry Andric     // Instruction can be reassociated.
3725ffd83dbSDimitry Andric     // fast math flags may prohibit reassociation.
3735ffd83dbSDimitry Andric     if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
3745ffd83dbSDimitry Andric           Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
3755ffd83dbSDimitry Andric       return false;
3765ffd83dbSDimitry Andric 
3775ffd83dbSDimitry Andric     // Instruction operands are virtual registers for reassociation.
3785ffd83dbSDimitry Andric     if (!IsAllOpsVirtualReg(Instr))
3795ffd83dbSDimitry Andric       return false;
3805ffd83dbSDimitry Andric 
381e8d8bef9SDimitry Andric     // For register pressure reassociation, the FSub must have only one use as
382e8d8bef9SDimitry Andric     // we want to delete the sub to save its def.
383e8d8bef9SDimitry Andric     if (OpType == InfoArrayIdxFSubInst &&
384e8d8bef9SDimitry Andric         !MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
385e8d8bef9SDimitry Andric       return false;
386e8d8bef9SDimitry Andric 
387e8d8bef9SDimitry Andric     return true;
388e8d8bef9SDimitry Andric   };
389e8d8bef9SDimitry Andric 
390e8d8bef9SDimitry Andric   auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,
391e8d8bef9SDimitry Andric                                int16_t &MulOpIdx, bool IsLeaf) {
392e8d8bef9SDimitry Andric     int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
393e8d8bef9SDimitry Andric     if (Idx < 0)
394e8d8bef9SDimitry Andric       return false;
395e8d8bef9SDimitry Andric 
396e8d8bef9SDimitry Andric     // Instruction can be reassociated.
397e8d8bef9SDimitry Andric     // fast math flags may prohibit reassociation.
398e8d8bef9SDimitry Andric     if (!(Instr.getFlag(MachineInstr::MIFlag::FmReassoc) &&
399e8d8bef9SDimitry Andric           Instr.getFlag(MachineInstr::MIFlag::FmNsz)))
400e8d8bef9SDimitry Andric       return false;
401e8d8bef9SDimitry Andric 
402e8d8bef9SDimitry Andric     // Instruction operands are virtual registers for reassociation.
403e8d8bef9SDimitry Andric     if (!IsAllOpsVirtualReg(Instr))
404e8d8bef9SDimitry Andric       return false;
405e8d8bef9SDimitry Andric 
406e8d8bef9SDimitry Andric     MulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
407e8d8bef9SDimitry Andric     if (IsLeaf)
4085ffd83dbSDimitry Andric       return true;
4095ffd83dbSDimitry Andric 
4105ffd83dbSDimitry Andric     AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];
4115ffd83dbSDimitry Andric 
4125ffd83dbSDimitry Andric     const MachineOperand &OpAdd = Instr.getOperand(AddOpIdx);
413e8d8bef9SDimitry Andric     MachineInstr *MIAdd = MRI->getUniqueVRegDef(OpAdd.getReg());
4145ffd83dbSDimitry Andric     // If 'add' operand's def is not in current block, don't do ILP related opt.
4155ffd83dbSDimitry Andric     if (!MIAdd || MIAdd->getParent() != MBB)
4165ffd83dbSDimitry Andric       return false;
4175ffd83dbSDimitry Andric 
4185ffd83dbSDimitry Andric     // If this is not Leaf FMA Instr, its 'add' operand should only have one use
4195ffd83dbSDimitry Andric     // as this fma will be changed later.
420e8d8bef9SDimitry Andric     return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());
4215ffd83dbSDimitry Andric   };
4225ffd83dbSDimitry Andric 
4235ffd83dbSDimitry Andric   int16_t AddOpIdx = -1;
424e8d8bef9SDimitry Andric   int16_t MulOpIdx = -1;
425e8d8bef9SDimitry Andric 
426e8d8bef9SDimitry Andric   bool IsUsedOnceL = false;
427e8d8bef9SDimitry Andric   bool IsUsedOnceR = false;
428e8d8bef9SDimitry Andric   MachineInstr *MULInstrL = nullptr;
429e8d8bef9SDimitry Andric   MachineInstr *MULInstrR = nullptr;
430e8d8bef9SDimitry Andric 
431e8d8bef9SDimitry Andric   auto IsRPReductionCandidate = [&]() {
432e8d8bef9SDimitry Andric     // Currently, we only support float and double.
433e8d8bef9SDimitry Andric     // FIXME: add support for other types.
434e8d8bef9SDimitry Andric     unsigned Opcode = Root.getOpcode();
435e8d8bef9SDimitry Andric     if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
436e8d8bef9SDimitry Andric       return false;
437e8d8bef9SDimitry Andric 
4385ffd83dbSDimitry Andric     // Root must be a valid FMA like instruction.
439e8d8bef9SDimitry Andric     // Treat it as leaf as we don't care its add operand.
440e8d8bef9SDimitry Andric     if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {
441e8d8bef9SDimitry Andric       assert((MulOpIdx >= 0) && "mul operand index not right!");
442e8d8bef9SDimitry Andric       Register MULRegL = TRI->lookThruSingleUseCopyChain(
443e8d8bef9SDimitry Andric           Root.getOperand(MulOpIdx).getReg(), MRI);
444e8d8bef9SDimitry Andric       Register MULRegR = TRI->lookThruSingleUseCopyChain(
445e8d8bef9SDimitry Andric           Root.getOperand(MulOpIdx + 1).getReg(), MRI);
446e8d8bef9SDimitry Andric       if (!MULRegL && !MULRegR)
447e8d8bef9SDimitry Andric         return false;
448e8d8bef9SDimitry Andric 
449e8d8bef9SDimitry Andric       if (MULRegL && !MULRegR) {
450e8d8bef9SDimitry Andric         MULRegR =
451e8d8bef9SDimitry Andric             TRI->lookThruCopyLike(Root.getOperand(MulOpIdx + 1).getReg(), MRI);
452e8d8bef9SDimitry Andric         IsUsedOnceL = true;
453e8d8bef9SDimitry Andric       } else if (!MULRegL && MULRegR) {
454e8d8bef9SDimitry Andric         MULRegL =
455e8d8bef9SDimitry Andric             TRI->lookThruCopyLike(Root.getOperand(MulOpIdx).getReg(), MRI);
456e8d8bef9SDimitry Andric         IsUsedOnceR = true;
457e8d8bef9SDimitry Andric       } else {
458e8d8bef9SDimitry Andric         IsUsedOnceL = true;
459e8d8bef9SDimitry Andric         IsUsedOnceR = true;
460e8d8bef9SDimitry Andric       }
461e8d8bef9SDimitry Andric 
462bdd1243dSDimitry Andric       if (!MULRegL.isVirtual() || !MULRegR.isVirtual())
463e8d8bef9SDimitry Andric         return false;
464e8d8bef9SDimitry Andric 
465e8d8bef9SDimitry Andric       MULInstrL = MRI->getVRegDef(MULRegL);
466e8d8bef9SDimitry Andric       MULInstrR = MRI->getVRegDef(MULRegR);
467e8d8bef9SDimitry Andric       return true;
468e8d8bef9SDimitry Andric     }
469e8d8bef9SDimitry Andric     return false;
470e8d8bef9SDimitry Andric   };
471e8d8bef9SDimitry Andric 
472e8d8bef9SDimitry Andric   // Register pressure fma reassociation patterns.
473e8d8bef9SDimitry Andric   if (DoRegPressureReduce && IsRPReductionCandidate()) {
474e8d8bef9SDimitry Andric     assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");
475e8d8bef9SDimitry Andric     // Register pressure pattern 1
476e8d8bef9SDimitry Andric     if (isLoadFromConstantPool(MULInstrL) && IsUsedOnceR &&
477e8d8bef9SDimitry Andric         IsReassociableAddOrSub(*MULInstrR, InfoArrayIdxFSubInst)) {
478e8d8bef9SDimitry Andric       LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");
4790fca6ea1SDimitry Andric       Patterns.push_back(PPCMachineCombinerPattern::REASSOC_XY_BCA);
480e8d8bef9SDimitry Andric       return true;
481e8d8bef9SDimitry Andric     }
482e8d8bef9SDimitry Andric 
483e8d8bef9SDimitry Andric     // Register pressure pattern 2
484e8d8bef9SDimitry Andric     if ((isLoadFromConstantPool(MULInstrR) && IsUsedOnceL &&
485e8d8bef9SDimitry Andric          IsReassociableAddOrSub(*MULInstrL, InfoArrayIdxFSubInst))) {
486e8d8bef9SDimitry Andric       LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");
4870fca6ea1SDimitry Andric       Patterns.push_back(PPCMachineCombinerPattern::REASSOC_XY_BAC);
488e8d8bef9SDimitry Andric       return true;
489e8d8bef9SDimitry Andric     }
490e8d8bef9SDimitry Andric   }
491e8d8bef9SDimitry Andric 
492e8d8bef9SDimitry Andric   // ILP fma reassociation patterns.
493e8d8bef9SDimitry Andric   // Root must be a valid FMA like instruction.
494e8d8bef9SDimitry Andric   AddOpIdx = -1;
495e8d8bef9SDimitry Andric   if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))
4965ffd83dbSDimitry Andric     return false;
4975ffd83dbSDimitry Andric 
4985ffd83dbSDimitry Andric   assert((AddOpIdx >= 0) && "add operand index not right!");
4995ffd83dbSDimitry Andric 
5005ffd83dbSDimitry Andric   Register RegB = Root.getOperand(AddOpIdx).getReg();
501e8d8bef9SDimitry Andric   MachineInstr *Prev = MRI->getUniqueVRegDef(RegB);
5025ffd83dbSDimitry Andric 
5035ffd83dbSDimitry Andric   // Prev must be a valid FMA like instruction.
5045ffd83dbSDimitry Andric   AddOpIdx = -1;
505e8d8bef9SDimitry Andric   if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))
5065ffd83dbSDimitry Andric     return false;
5075ffd83dbSDimitry Andric 
5085ffd83dbSDimitry Andric   assert((AddOpIdx >= 0) && "add operand index not right!");
5095ffd83dbSDimitry Andric 
5105ffd83dbSDimitry Andric   Register RegA = Prev->getOperand(AddOpIdx).getReg();
511e8d8bef9SDimitry Andric   MachineInstr *Leaf = MRI->getUniqueVRegDef(RegA);
5125ffd83dbSDimitry Andric   AddOpIdx = -1;
513e8d8bef9SDimitry Andric   if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {
5140fca6ea1SDimitry Andric     Patterns.push_back(PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM);
515e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");
5165ffd83dbSDimitry Andric     return true;
5175ffd83dbSDimitry Andric   }
518e8d8bef9SDimitry Andric   if (IsReassociableAddOrSub(*Leaf, InfoArrayIdxFAddInst)) {
5190fca6ea1SDimitry Andric     Patterns.push_back(PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM);
520e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");
5215ffd83dbSDimitry Andric     return true;
5225ffd83dbSDimitry Andric   }
5235ffd83dbSDimitry Andric   return false;
5245ffd83dbSDimitry Andric }
5255ffd83dbSDimitry Andric 
526e8d8bef9SDimitry Andric void PPCInstrInfo::finalizeInsInstrs(
5270fca6ea1SDimitry Andric     MachineInstr &Root, unsigned &Pattern,
528e8d8bef9SDimitry Andric     SmallVectorImpl<MachineInstr *> &InsInstrs) const {
529e8d8bef9SDimitry Andric   assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");
530e8d8bef9SDimitry Andric 
531e8d8bef9SDimitry Andric   MachineFunction *MF = Root.getMF();
532e8d8bef9SDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
533e8d8bef9SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
534e8d8bef9SDimitry Andric   MachineConstantPool *MCP = MF->getConstantPool();
535e8d8bef9SDimitry Andric 
536e8d8bef9SDimitry Andric   int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());
537e8d8bef9SDimitry Andric   if (Idx < 0)
538e8d8bef9SDimitry Andric     return;
539e8d8bef9SDimitry Andric 
540e8d8bef9SDimitry Andric   uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
541e8d8bef9SDimitry Andric 
542e8d8bef9SDimitry Andric   // For now we only need to fix up placeholder for register pressure reduce
543e8d8bef9SDimitry Andric   // patterns.
544e8d8bef9SDimitry Andric   Register ConstReg = 0;
5450fca6ea1SDimitry Andric   switch (Pattern) {
5460fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BCA:
547e8d8bef9SDimitry Andric     ConstReg =
548e8d8bef9SDimitry Andric         TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), MRI);
549e8d8bef9SDimitry Andric     break;
5500fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BAC:
551e8d8bef9SDimitry Andric     ConstReg =
552e8d8bef9SDimitry Andric         TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx + 1).getReg(), MRI);
553e8d8bef9SDimitry Andric     break;
554e8d8bef9SDimitry Andric   default:
555e8d8bef9SDimitry Andric     // Not register pressure reduce patterns.
556e8d8bef9SDimitry Andric     return;
557e8d8bef9SDimitry Andric   }
558e8d8bef9SDimitry Andric 
559e8d8bef9SDimitry Andric   MachineInstr *ConstDefInstr = MRI->getVRegDef(ConstReg);
560e8d8bef9SDimitry Andric   // Get const value from const pool.
561e8d8bef9SDimitry Andric   const Constant *C = getConstantFromConstantPool(ConstDefInstr);
562e8d8bef9SDimitry Andric   assert(isa<llvm::ConstantFP>(C) && "not a valid constant!");
563e8d8bef9SDimitry Andric 
564e8d8bef9SDimitry Andric   // Get negative fp const.
565e8d8bef9SDimitry Andric   APFloat F1((dyn_cast<ConstantFP>(C))->getValueAPF());
566e8d8bef9SDimitry Andric   F1.changeSign();
567e8d8bef9SDimitry Andric   Constant *NegC = ConstantFP::get(dyn_cast<ConstantFP>(C)->getContext(), F1);
568e8d8bef9SDimitry Andric   Align Alignment = MF->getDataLayout().getPrefTypeAlign(C->getType());
569e8d8bef9SDimitry Andric 
570e8d8bef9SDimitry Andric   // Put negative fp const into constant pool.
571e8d8bef9SDimitry Andric   unsigned ConstPoolIdx = MCP->getConstantPoolIndex(NegC, Alignment);
572e8d8bef9SDimitry Andric 
573e8d8bef9SDimitry Andric   MachineOperand *Placeholder = nullptr;
574e8d8bef9SDimitry Andric   // Record the placeholder PPC::ZERO8 we add in reassociateFMA.
575e8d8bef9SDimitry Andric   for (auto *Inst : InsInstrs) {
576e8d8bef9SDimitry Andric     for (MachineOperand &Operand : Inst->explicit_operands()) {
577e8d8bef9SDimitry Andric       assert(Operand.isReg() && "Invalid instruction in InsInstrs!");
578e8d8bef9SDimitry Andric       if (Operand.getReg() == PPC::ZERO8) {
579e8d8bef9SDimitry Andric         Placeholder = &Operand;
580e8d8bef9SDimitry Andric         break;
581e8d8bef9SDimitry Andric       }
582e8d8bef9SDimitry Andric     }
583e8d8bef9SDimitry Andric   }
584e8d8bef9SDimitry Andric 
585e8d8bef9SDimitry Andric   assert(Placeholder && "Placeholder does not exist!");
586e8d8bef9SDimitry Andric 
587e8d8bef9SDimitry Andric   // Generate instructions to load the const fp from constant pool.
588e8d8bef9SDimitry Andric   // We only support PPC64 and medium code model.
589e8d8bef9SDimitry Andric   Register LoadNewConst =
590e8d8bef9SDimitry Andric       generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);
591e8d8bef9SDimitry Andric 
592e8d8bef9SDimitry Andric   // Fill the placeholder with the new load from constant pool.
593e8d8bef9SDimitry Andric   Placeholder->setReg(LoadNewConst);
594e8d8bef9SDimitry Andric }
595e8d8bef9SDimitry Andric 
596e8d8bef9SDimitry Andric bool PPCInstrInfo::shouldReduceRegisterPressure(
597bdd1243dSDimitry Andric     const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const {
598e8d8bef9SDimitry Andric 
599e8d8bef9SDimitry Andric   if (!EnableFMARegPressureReduction)
600e8d8bef9SDimitry Andric     return false;
601e8d8bef9SDimitry Andric 
602e8d8bef9SDimitry Andric   // Currently, we only enable register pressure reducing in machine combiner
603e8d8bef9SDimitry Andric   // for: 1: PPC64; 2: Code Model is Medium; 3: Power9 which also has vector
604e8d8bef9SDimitry Andric   // support.
605e8d8bef9SDimitry Andric   //
606e8d8bef9SDimitry Andric   // So we need following instructions to access a TOC entry:
607e8d8bef9SDimitry Andric   //
608e8d8bef9SDimitry Andric   // %6:g8rc_and_g8rc_nox0 = ADDIStocHA8 $x2, %const.0
609e8d8bef9SDimitry Andric   // %7:vssrc = DFLOADf32 target-flags(ppc-toc-lo) %const.0,
610e8d8bef9SDimitry Andric   //   killed %6:g8rc_and_g8rc_nox0, implicit $x2 :: (load 4 from constant-pool)
611e8d8bef9SDimitry Andric   //
612e8d8bef9SDimitry Andric   // FIXME: add more supported targets, like Small and Large code model, PPC32,
613e8d8bef9SDimitry Andric   // AIX.
614e8d8bef9SDimitry Andric   if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
615e8d8bef9SDimitry Andric         Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))
616e8d8bef9SDimitry Andric     return false;
617e8d8bef9SDimitry Andric 
618e8d8bef9SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
619bdd1243dSDimitry Andric   const MachineFunction *MF = MBB->getParent();
620bdd1243dSDimitry Andric   const MachineRegisterInfo *MRI = &MF->getRegInfo();
621e8d8bef9SDimitry Andric 
622bdd1243dSDimitry Andric   auto GetMBBPressure =
623bdd1243dSDimitry Andric       [&](const MachineBasicBlock *MBB) -> std::vector<unsigned> {
624e8d8bef9SDimitry Andric     RegionPressure Pressure;
625e8d8bef9SDimitry Andric     RegPressureTracker RPTracker(Pressure);
626e8d8bef9SDimitry Andric 
627e8d8bef9SDimitry Andric     // Initialize the register pressure tracker.
628e8d8bef9SDimitry Andric     RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),
629e8d8bef9SDimitry Andric                    /*TrackLaneMasks*/ false, /*TrackUntiedDefs=*/true);
630e8d8bef9SDimitry Andric 
631bdd1243dSDimitry Andric     for (const auto &MI : reverse(*MBB)) {
632e8d8bef9SDimitry Andric       if (MI.isDebugValue() || MI.isDebugLabel())
633e8d8bef9SDimitry Andric         continue;
634e8d8bef9SDimitry Andric       RegisterOperands RegOpers;
635e8d8bef9SDimitry Andric       RegOpers.collect(MI, *TRI, *MRI, false, false);
636e8d8bef9SDimitry Andric       RPTracker.recedeSkipDebugValues();
637e8d8bef9SDimitry Andric       assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");
638e8d8bef9SDimitry Andric       RPTracker.recede(RegOpers);
639e8d8bef9SDimitry Andric     }
640e8d8bef9SDimitry Andric 
641e8d8bef9SDimitry Andric     // Close the RPTracker to finalize live ins.
642e8d8bef9SDimitry Andric     RPTracker.closeRegion();
643e8d8bef9SDimitry Andric 
644e8d8bef9SDimitry Andric     return RPTracker.getPressure().MaxSetPressure;
645e8d8bef9SDimitry Andric   };
646e8d8bef9SDimitry Andric 
647e8d8bef9SDimitry Andric   // For now we only care about float and double type fma.
648e8d8bef9SDimitry Andric   unsigned VSSRCLimit = TRI->getRegPressureSetLimit(
649e8d8bef9SDimitry Andric       *MBB->getParent(), PPC::RegisterPressureSets::VSSRC);
650e8d8bef9SDimitry Andric 
651e8d8bef9SDimitry Andric   // Only reduce register pressure when pressure is high.
652e8d8bef9SDimitry Andric   return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >
653e8d8bef9SDimitry Andric          (float)VSSRCLimit * FMARPFactor;
654e8d8bef9SDimitry Andric }
655e8d8bef9SDimitry Andric 
656e8d8bef9SDimitry Andric bool PPCInstrInfo::isLoadFromConstantPool(MachineInstr *I) const {
657e8d8bef9SDimitry Andric   // I has only one memory operand which is load from constant pool.
658e8d8bef9SDimitry Andric   if (!I->hasOneMemOperand())
659e8d8bef9SDimitry Andric     return false;
660e8d8bef9SDimitry Andric 
661e8d8bef9SDimitry Andric   MachineMemOperand *Op = I->memoperands()[0];
662e8d8bef9SDimitry Andric   return Op->isLoad() && Op->getPseudoValue() &&
663e8d8bef9SDimitry Andric          Op->getPseudoValue()->kind() == PseudoSourceValue::ConstantPool;
664e8d8bef9SDimitry Andric }
665e8d8bef9SDimitry Andric 
666e8d8bef9SDimitry Andric Register PPCInstrInfo::generateLoadForNewConst(
667e8d8bef9SDimitry Andric     unsigned Idx, MachineInstr *MI, Type *Ty,
668e8d8bef9SDimitry Andric     SmallVectorImpl<MachineInstr *> &InsInstrs) const {
669e8d8bef9SDimitry Andric   // Now we only support PPC64, Medium code model and P9 with vector.
670e8d8bef9SDimitry Andric   // We have immutable pattern to access const pool. See function
671e8d8bef9SDimitry Andric   // shouldReduceRegisterPressure.
672e8d8bef9SDimitry Andric   assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
673e8d8bef9SDimitry Andric           Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium) &&
674e8d8bef9SDimitry Andric          "Target not supported!\n");
675e8d8bef9SDimitry Andric 
676e8d8bef9SDimitry Andric   MachineFunction *MF = MI->getMF();
677e8d8bef9SDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
678e8d8bef9SDimitry Andric 
679e8d8bef9SDimitry Andric   // Generate ADDIStocHA8
680e8d8bef9SDimitry Andric   Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
681e8d8bef9SDimitry Andric   MachineInstrBuilder TOCOffset =
682e8d8bef9SDimitry Andric       BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)
683e8d8bef9SDimitry Andric           .addReg(PPC::X2)
684e8d8bef9SDimitry Andric           .addConstantPoolIndex(Idx);
685e8d8bef9SDimitry Andric 
686e8d8bef9SDimitry Andric   assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
687e8d8bef9SDimitry Andric          "Only float and double are supported!");
688e8d8bef9SDimitry Andric 
689e8d8bef9SDimitry Andric   unsigned LoadOpcode;
690e8d8bef9SDimitry Andric   // Should be float type or double type.
691e8d8bef9SDimitry Andric   if (Ty->isFloatTy())
692e8d8bef9SDimitry Andric     LoadOpcode = PPC::DFLOADf32;
693e8d8bef9SDimitry Andric   else
694e8d8bef9SDimitry Andric     LoadOpcode = PPC::DFLOADf64;
695e8d8bef9SDimitry Andric 
696e8d8bef9SDimitry Andric   const TargetRegisterClass *RC = MRI->getRegClass(MI->getOperand(0).getReg());
697e8d8bef9SDimitry Andric   Register VReg2 = MRI->createVirtualRegister(RC);
698e8d8bef9SDimitry Andric   MachineMemOperand *MMO = MF->getMachineMemOperand(
699e8d8bef9SDimitry Andric       MachinePointerInfo::getConstantPool(*MF), MachineMemOperand::MOLoad,
700e8d8bef9SDimitry Andric       Ty->getScalarSizeInBits() / 8, MF->getDataLayout().getPrefTypeAlign(Ty));
701e8d8bef9SDimitry Andric 
702e8d8bef9SDimitry Andric   // Generate Load from constant pool.
703e8d8bef9SDimitry Andric   MachineInstrBuilder Load =
704e8d8bef9SDimitry Andric       BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)
705e8d8bef9SDimitry Andric           .addConstantPoolIndex(Idx)
706e8d8bef9SDimitry Andric           .addReg(VReg1, getKillRegState(true))
707e8d8bef9SDimitry Andric           .addMemOperand(MMO);
708e8d8bef9SDimitry Andric 
709e8d8bef9SDimitry Andric   Load->getOperand(1).setTargetFlags(PPCII::MO_TOC_LO);
710e8d8bef9SDimitry Andric 
711e8d8bef9SDimitry Andric   // Insert the toc load instructions into InsInstrs.
712e8d8bef9SDimitry Andric   InsInstrs.insert(InsInstrs.begin(), Load);
713e8d8bef9SDimitry Andric   InsInstrs.insert(InsInstrs.begin(), TOCOffset);
714e8d8bef9SDimitry Andric   return VReg2;
715e8d8bef9SDimitry Andric }
716e8d8bef9SDimitry Andric 
717e8d8bef9SDimitry Andric // This function returns the const value in constant pool if the \p I is a load
718e8d8bef9SDimitry Andric // from constant pool.
719e8d8bef9SDimitry Andric const Constant *
720e8d8bef9SDimitry Andric PPCInstrInfo::getConstantFromConstantPool(MachineInstr *I) const {
721e8d8bef9SDimitry Andric   MachineFunction *MF = I->getMF();
722e8d8bef9SDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
723e8d8bef9SDimitry Andric   MachineConstantPool *MCP = MF->getConstantPool();
724e8d8bef9SDimitry Andric   assert(I->mayLoad() && "Should be a load instruction.\n");
725e8d8bef9SDimitry Andric   for (auto MO : I->uses()) {
726e8d8bef9SDimitry Andric     if (!MO.isReg())
727e8d8bef9SDimitry Andric       continue;
728e8d8bef9SDimitry Andric     Register Reg = MO.getReg();
729bdd1243dSDimitry Andric     if (Reg == 0 || !Reg.isVirtual())
730e8d8bef9SDimitry Andric       continue;
731e8d8bef9SDimitry Andric     // Find the toc address.
732e8d8bef9SDimitry Andric     MachineInstr *DefMI = MRI->getVRegDef(Reg);
733e8d8bef9SDimitry Andric     for (auto MO2 : DefMI->uses())
734e8d8bef9SDimitry Andric       if (MO2.isCPI())
735e8d8bef9SDimitry Andric         return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;
736e8d8bef9SDimitry Andric   }
737e8d8bef9SDimitry Andric   return nullptr;
738e8d8bef9SDimitry Andric }
739e8d8bef9SDimitry Andric 
7400fca6ea1SDimitry Andric CombinerObjective PPCInstrInfo::getCombinerObjective(unsigned Pattern) const {
7410fca6ea1SDimitry Andric   switch (Pattern) {
7420fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM:
7430fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM:
7440fca6ea1SDimitry Andric     return CombinerObjective::MustReduceDepth;
7450fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BCA:
7460fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BAC:
7470fca6ea1SDimitry Andric     return CombinerObjective::MustReduceRegisterPressure;
7480fca6ea1SDimitry Andric   default:
7490fca6ea1SDimitry Andric     return TargetInstrInfo::getCombinerObjective(Pattern);
7500fca6ea1SDimitry Andric   }
7510fca6ea1SDimitry Andric }
7520fca6ea1SDimitry Andric 
7530b57cec5SDimitry Andric bool PPCInstrInfo::getMachineCombinerPatterns(
7540fca6ea1SDimitry Andric     MachineInstr &Root, SmallVectorImpl<unsigned> &Patterns,
755e8d8bef9SDimitry Andric     bool DoRegPressureReduce) const {
7560b57cec5SDimitry Andric   // Using the machine combiner in this way is potentially expensive, so
7570b57cec5SDimitry Andric   // restrict to when aggressive optimizations are desired.
7585f757f3fSDimitry Andric   if (Subtarget.getTargetMachine().getOptLevel() != CodeGenOptLevel::Aggressive)
7590b57cec5SDimitry Andric     return false;
7600b57cec5SDimitry Andric 
761e8d8bef9SDimitry Andric   if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))
7625ffd83dbSDimitry Andric     return true;
7630b57cec5SDimitry Andric 
764e8d8bef9SDimitry Andric   return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns,
765e8d8bef9SDimitry Andric                                                      DoRegPressureReduce);
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
7685ffd83dbSDimitry Andric void PPCInstrInfo::genAlternativeCodeSequence(
7690fca6ea1SDimitry Andric     MachineInstr &Root, unsigned Pattern,
7705ffd83dbSDimitry Andric     SmallVectorImpl<MachineInstr *> &InsInstrs,
7715ffd83dbSDimitry Andric     SmallVectorImpl<MachineInstr *> &DelInstrs,
7725ffd83dbSDimitry Andric     DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
7735ffd83dbSDimitry Andric   switch (Pattern) {
7740fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM:
7750fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM:
7760fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BCA:
7770fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BAC:
7785ffd83dbSDimitry Andric     reassociateFMA(Root, Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
7795ffd83dbSDimitry Andric     break;
7805ffd83dbSDimitry Andric   default:
7815ffd83dbSDimitry Andric     // Reassociate default patterns.
7825ffd83dbSDimitry Andric     TargetInstrInfo::genAlternativeCodeSequence(Root, Pattern, InsInstrs,
7835ffd83dbSDimitry Andric                                                 DelInstrs, InstrIdxForVirtReg);
7845ffd83dbSDimitry Andric     break;
7855ffd83dbSDimitry Andric   }
7865ffd83dbSDimitry Andric }
7875ffd83dbSDimitry Andric 
7885ffd83dbSDimitry Andric void PPCInstrInfo::reassociateFMA(
7890fca6ea1SDimitry Andric     MachineInstr &Root, unsigned Pattern,
7905ffd83dbSDimitry Andric     SmallVectorImpl<MachineInstr *> &InsInstrs,
7915ffd83dbSDimitry Andric     SmallVectorImpl<MachineInstr *> &DelInstrs,
7925ffd83dbSDimitry Andric     DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const {
7935ffd83dbSDimitry Andric   MachineFunction *MF = Root.getMF();
7945ffd83dbSDimitry Andric   MachineRegisterInfo &MRI = MF->getRegInfo();
795e8d8bef9SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
7965ffd83dbSDimitry Andric   MachineOperand &OpC = Root.getOperand(0);
7975ffd83dbSDimitry Andric   Register RegC = OpC.getReg();
7985ffd83dbSDimitry Andric   const TargetRegisterClass *RC = MRI.getRegClass(RegC);
7995ffd83dbSDimitry Andric   MRI.constrainRegClass(RegC, RC);
8005ffd83dbSDimitry Andric 
8015ffd83dbSDimitry Andric   unsigned FmaOp = Root.getOpcode();
8025ffd83dbSDimitry Andric   int16_t Idx = getFMAOpIdxInfo(FmaOp);
8035ffd83dbSDimitry Andric   assert(Idx >= 0 && "Root must be a FMA instruction");
8045ffd83dbSDimitry Andric 
805e8d8bef9SDimitry Andric   bool IsILPReassociate =
8060fca6ea1SDimitry Andric       (Pattern == PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM) ||
8070fca6ea1SDimitry Andric       (Pattern == PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM);
808e8d8bef9SDimitry Andric 
8095ffd83dbSDimitry Andric   uint16_t AddOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxAddOpIdx];
8105ffd83dbSDimitry Andric   uint16_t FirstMulOpIdx = FMAOpIdxInfo[Idx][InfoArrayIdxMULOpIdx];
811e8d8bef9SDimitry Andric 
812e8d8bef9SDimitry Andric   MachineInstr *Prev = nullptr;
813e8d8bef9SDimitry Andric   MachineInstr *Leaf = nullptr;
814e8d8bef9SDimitry Andric   switch (Pattern) {
815e8d8bef9SDimitry Andric   default:
816e8d8bef9SDimitry Andric     llvm_unreachable("not recognized pattern!");
8170fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM:
8180fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM:
819e8d8bef9SDimitry Andric     Prev = MRI.getUniqueVRegDef(Root.getOperand(AddOpIdx).getReg());
820e8d8bef9SDimitry Andric     Leaf = MRI.getUniqueVRegDef(Prev->getOperand(AddOpIdx).getReg());
821e8d8bef9SDimitry Andric     break;
8220fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BAC: {
823e8d8bef9SDimitry Andric     Register MULReg =
824e8d8bef9SDimitry Andric         TRI->lookThruCopyLike(Root.getOperand(FirstMulOpIdx).getReg(), &MRI);
825e8d8bef9SDimitry Andric     Leaf = MRI.getVRegDef(MULReg);
826e8d8bef9SDimitry Andric     break;
827e8d8bef9SDimitry Andric   }
8280fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BCA: {
829e8d8bef9SDimitry Andric     Register MULReg = TRI->lookThruCopyLike(
830e8d8bef9SDimitry Andric         Root.getOperand(FirstMulOpIdx + 1).getReg(), &MRI);
831e8d8bef9SDimitry Andric     Leaf = MRI.getVRegDef(MULReg);
832e8d8bef9SDimitry Andric     break;
833e8d8bef9SDimitry Andric   }
834e8d8bef9SDimitry Andric   }
835e8d8bef9SDimitry Andric 
83606c3fb27SDimitry Andric   uint32_t IntersectedFlags = 0;
837e8d8bef9SDimitry Andric   if (IsILPReassociate)
838e8d8bef9SDimitry Andric     IntersectedFlags = Root.getFlags() & Prev->getFlags() & Leaf->getFlags();
839e8d8bef9SDimitry Andric   else
840e8d8bef9SDimitry Andric     IntersectedFlags = Root.getFlags() & Leaf->getFlags();
8415ffd83dbSDimitry Andric 
8425ffd83dbSDimitry Andric   auto GetOperandInfo = [&](const MachineOperand &Operand, Register &Reg,
8435ffd83dbSDimitry Andric                             bool &KillFlag) {
8445ffd83dbSDimitry Andric     Reg = Operand.getReg();
8455ffd83dbSDimitry Andric     MRI.constrainRegClass(Reg, RC);
8465ffd83dbSDimitry Andric     KillFlag = Operand.isKill();
8475ffd83dbSDimitry Andric   };
8485ffd83dbSDimitry Andric 
8495ffd83dbSDimitry Andric   auto GetFMAInstrInfo = [&](const MachineInstr &Instr, Register &MulOp1,
850e8d8bef9SDimitry Andric                              Register &MulOp2, Register &AddOp,
851e8d8bef9SDimitry Andric                              bool &MulOp1KillFlag, bool &MulOp2KillFlag,
852e8d8bef9SDimitry Andric                              bool &AddOpKillFlag) {
8535ffd83dbSDimitry Andric     GetOperandInfo(Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
8545ffd83dbSDimitry Andric     GetOperandInfo(Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
855e8d8bef9SDimitry Andric     GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
8565ffd83dbSDimitry Andric   };
8575ffd83dbSDimitry Andric 
858e8d8bef9SDimitry Andric   Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
859e8d8bef9SDimitry Andric       RegA21, RegB;
8605ffd83dbSDimitry Andric   bool KillX = false, KillY = false, KillM11 = false, KillM12 = false,
861e8d8bef9SDimitry Andric        KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,
862e8d8bef9SDimitry Andric        KillA11 = false, KillA21 = false, KillB = false;
8635ffd83dbSDimitry Andric 
864e8d8bef9SDimitry Andric   GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
865e8d8bef9SDimitry Andric 
866e8d8bef9SDimitry Andric   if (IsILPReassociate)
867e8d8bef9SDimitry Andric     GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
8685ffd83dbSDimitry Andric 
8690fca6ea1SDimitry Andric   if (Pattern == PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
870e8d8bef9SDimitry Andric     GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
8715ffd83dbSDimitry Andric     GetOperandInfo(Leaf->getOperand(AddOpIdx), RegX, KillX);
8720fca6ea1SDimitry Andric   } else if (Pattern == PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM) {
8735ffd83dbSDimitry Andric     GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
8745ffd83dbSDimitry Andric     GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
875e8d8bef9SDimitry Andric   } else {
876e8d8bef9SDimitry Andric     // Get FSUB instruction info.
877e8d8bef9SDimitry Andric     GetOperandInfo(Leaf->getOperand(1), RegX, KillX);
878e8d8bef9SDimitry Andric     GetOperandInfo(Leaf->getOperand(2), RegY, KillY);
8795ffd83dbSDimitry Andric   }
8805ffd83dbSDimitry Andric 
8815ffd83dbSDimitry Andric   // Create new virtual registers for the new results instead of
8825ffd83dbSDimitry Andric   // recycling legacy ones because the MachineCombiner's computation of the
8835ffd83dbSDimitry Andric   // critical path requires a new register definition rather than an existing
8845ffd83dbSDimitry Andric   // one.
885e8d8bef9SDimitry Andric   // For register pressure reassociation, we only need create one virtual
886e8d8bef9SDimitry Andric   // register for the new fma.
8875ffd83dbSDimitry Andric   Register NewVRA = MRI.createVirtualRegister(RC);
8885ffd83dbSDimitry Andric   InstrIdxForVirtReg.insert(std::make_pair(NewVRA, 0));
8895ffd83dbSDimitry Andric 
890e8d8bef9SDimitry Andric   Register NewVRB = 0;
891e8d8bef9SDimitry Andric   if (IsILPReassociate) {
892e8d8bef9SDimitry Andric     NewVRB = MRI.createVirtualRegister(RC);
8935ffd83dbSDimitry Andric     InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));
894e8d8bef9SDimitry Andric   }
8955ffd83dbSDimitry Andric 
8965ffd83dbSDimitry Andric   Register NewVRD = 0;
8970fca6ea1SDimitry Andric   if (Pattern == PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM) {
8985ffd83dbSDimitry Andric     NewVRD = MRI.createVirtualRegister(RC);
8995ffd83dbSDimitry Andric     InstrIdxForVirtReg.insert(std::make_pair(NewVRD, 2));
9005ffd83dbSDimitry Andric   }
9015ffd83dbSDimitry Andric 
9025ffd83dbSDimitry Andric   auto AdjustOperandOrder = [&](MachineInstr *MI, Register RegAdd, bool KillAdd,
9035ffd83dbSDimitry Andric                                 Register RegMul1, bool KillRegMul1,
9045ffd83dbSDimitry Andric                                 Register RegMul2, bool KillRegMul2) {
9055ffd83dbSDimitry Andric     MI->getOperand(AddOpIdx).setReg(RegAdd);
9065ffd83dbSDimitry Andric     MI->getOperand(AddOpIdx).setIsKill(KillAdd);
9075ffd83dbSDimitry Andric     MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
9085ffd83dbSDimitry Andric     MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
9095ffd83dbSDimitry Andric     MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
9105ffd83dbSDimitry Andric     MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
9115ffd83dbSDimitry Andric   };
9125ffd83dbSDimitry Andric 
913e8d8bef9SDimitry Andric   MachineInstrBuilder NewARegPressure, NewCRegPressure;
914e8d8bef9SDimitry Andric   switch (Pattern) {
915e8d8bef9SDimitry Andric   default:
916e8d8bef9SDimitry Andric     llvm_unreachable("not recognized pattern!");
9170fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_AMM_BMM: {
9185ffd83dbSDimitry Andric     // Create new instructions for insertion.
9195ffd83dbSDimitry Andric     MachineInstrBuilder MINewB =
9205ffd83dbSDimitry Andric         BuildMI(*MF, Prev->getDebugLoc(), get(FmaOp), NewVRB)
9215ffd83dbSDimitry Andric             .addReg(RegX, getKillRegState(KillX))
9225ffd83dbSDimitry Andric             .addReg(RegM21, getKillRegState(KillM21))
9235ffd83dbSDimitry Andric             .addReg(RegM22, getKillRegState(KillM22));
9245ffd83dbSDimitry Andric     MachineInstrBuilder MINewA =
9255ffd83dbSDimitry Andric         BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
9265ffd83dbSDimitry Andric             .addReg(RegY, getKillRegState(KillY))
9275ffd83dbSDimitry Andric             .addReg(RegM31, getKillRegState(KillM31))
9285ffd83dbSDimitry Andric             .addReg(RegM32, getKillRegState(KillM32));
9295ffd83dbSDimitry Andric     // If AddOpIdx is not 1, adjust the order.
9305ffd83dbSDimitry Andric     if (AddOpIdx != 1) {
9315ffd83dbSDimitry Andric       AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
9325ffd83dbSDimitry Andric       AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
9335ffd83dbSDimitry Andric     }
9345ffd83dbSDimitry Andric 
9355ffd83dbSDimitry Andric     MachineInstrBuilder MINewC =
9365ffd83dbSDimitry Andric         BuildMI(*MF, Root.getDebugLoc(),
9375ffd83dbSDimitry Andric                 get(FMAOpIdxInfo[Idx][InfoArrayIdxFAddInst]), RegC)
9385ffd83dbSDimitry Andric             .addReg(NewVRB, getKillRegState(true))
9395ffd83dbSDimitry Andric             .addReg(NewVRA, getKillRegState(true));
9405ffd83dbSDimitry Andric 
9415ffd83dbSDimitry Andric     // Update flags for newly created instructions.
9425ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewA, IntersectedFlags);
9435ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewB, IntersectedFlags);
9445ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewC, IntersectedFlags);
9455ffd83dbSDimitry Andric 
9465ffd83dbSDimitry Andric     // Record new instructions for insertion.
9475ffd83dbSDimitry Andric     InsInstrs.push_back(MINewA);
9485ffd83dbSDimitry Andric     InsInstrs.push_back(MINewB);
9495ffd83dbSDimitry Andric     InsInstrs.push_back(MINewC);
950e8d8bef9SDimitry Andric     break;
951e8d8bef9SDimitry Andric   }
9520fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XMM_AMM_BMM: {
9535ffd83dbSDimitry Andric     assert(NewVRD && "new FMA register not created!");
9545ffd83dbSDimitry Andric     // Create new instructions for insertion.
9555ffd83dbSDimitry Andric     MachineInstrBuilder MINewA =
9565ffd83dbSDimitry Andric         BuildMI(*MF, Leaf->getDebugLoc(),
9575ffd83dbSDimitry Andric                 get(FMAOpIdxInfo[Idx][InfoArrayIdxFMULInst]), NewVRA)
9585ffd83dbSDimitry Andric             .addReg(RegM11, getKillRegState(KillM11))
9595ffd83dbSDimitry Andric             .addReg(RegM12, getKillRegState(KillM12));
9605ffd83dbSDimitry Andric     MachineInstrBuilder MINewB =
9615ffd83dbSDimitry Andric         BuildMI(*MF, Prev->getDebugLoc(), get(FmaOp), NewVRB)
9625ffd83dbSDimitry Andric             .addReg(RegX, getKillRegState(KillX))
9635ffd83dbSDimitry Andric             .addReg(RegM21, getKillRegState(KillM21))
9645ffd83dbSDimitry Andric             .addReg(RegM22, getKillRegState(KillM22));
9655ffd83dbSDimitry Andric     MachineInstrBuilder MINewD =
9665ffd83dbSDimitry Andric         BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRD)
9675ffd83dbSDimitry Andric             .addReg(NewVRA, getKillRegState(true))
9685ffd83dbSDimitry Andric             .addReg(RegM31, getKillRegState(KillM31))
9695ffd83dbSDimitry Andric             .addReg(RegM32, getKillRegState(KillM32));
9705ffd83dbSDimitry Andric     // If AddOpIdx is not 1, adjust the order.
9715ffd83dbSDimitry Andric     if (AddOpIdx != 1) {
9725ffd83dbSDimitry Andric       AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
9735ffd83dbSDimitry Andric       AdjustOperandOrder(MINewD, NewVRA, true, RegM31, KillM31, RegM32,
9745ffd83dbSDimitry Andric                          KillM32);
9755ffd83dbSDimitry Andric     }
9765ffd83dbSDimitry Andric 
9775ffd83dbSDimitry Andric     MachineInstrBuilder MINewC =
9785ffd83dbSDimitry Andric         BuildMI(*MF, Root.getDebugLoc(),
9795ffd83dbSDimitry Andric                 get(FMAOpIdxInfo[Idx][InfoArrayIdxFAddInst]), RegC)
9805ffd83dbSDimitry Andric             .addReg(NewVRB, getKillRegState(true))
9815ffd83dbSDimitry Andric             .addReg(NewVRD, getKillRegState(true));
9825ffd83dbSDimitry Andric 
9835ffd83dbSDimitry Andric     // Update flags for newly created instructions.
9845ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewA, IntersectedFlags);
9855ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewB, IntersectedFlags);
9865ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewD, IntersectedFlags);
9875ffd83dbSDimitry Andric     setSpecialOperandAttr(*MINewC, IntersectedFlags);
9885ffd83dbSDimitry Andric 
9895ffd83dbSDimitry Andric     // Record new instructions for insertion.
9905ffd83dbSDimitry Andric     InsInstrs.push_back(MINewA);
9915ffd83dbSDimitry Andric     InsInstrs.push_back(MINewB);
9925ffd83dbSDimitry Andric     InsInstrs.push_back(MINewD);
9935ffd83dbSDimitry Andric     InsInstrs.push_back(MINewC);
994e8d8bef9SDimitry Andric     break;
995e8d8bef9SDimitry Andric   }
9960fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BAC:
9970fca6ea1SDimitry Andric   case PPCMachineCombinerPattern::REASSOC_XY_BCA: {
998e8d8bef9SDimitry Andric     Register VarReg;
999e8d8bef9SDimitry Andric     bool KillVarReg = false;
10000fca6ea1SDimitry Andric     if (Pattern == PPCMachineCombinerPattern::REASSOC_XY_BCA) {
1001e8d8bef9SDimitry Andric       VarReg = RegM31;
1002e8d8bef9SDimitry Andric       KillVarReg = KillM31;
1003e8d8bef9SDimitry Andric     } else {
1004e8d8bef9SDimitry Andric       VarReg = RegM32;
1005e8d8bef9SDimitry Andric       KillVarReg = KillM32;
1006e8d8bef9SDimitry Andric     }
1007e8d8bef9SDimitry Andric     // We don't want to get negative const from memory pool too early, as the
1008e8d8bef9SDimitry Andric     // created entry will not be deleted even if it has no users. Since all
1009e8d8bef9SDimitry Andric     // operand of Leaf and Root are virtual register, we use zero register
1010e8d8bef9SDimitry Andric     // here as a placeholder. When the InsInstrs is selected in
1011e8d8bef9SDimitry Andric     // MachineCombiner, we call finalizeInsInstrs to replace the zero register
1012e8d8bef9SDimitry Andric     // with a virtual register which is a load from constant pool.
1013e8d8bef9SDimitry Andric     NewARegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), NewVRA)
1014e8d8bef9SDimitry Andric                           .addReg(RegB, getKillRegState(RegB))
1015e8d8bef9SDimitry Andric                           .addReg(RegY, getKillRegState(KillY))
1016e8d8bef9SDimitry Andric                           .addReg(PPC::ZERO8);
1017e8d8bef9SDimitry Andric     NewCRegPressure = BuildMI(*MF, Root.getDebugLoc(), get(FmaOp), RegC)
1018e8d8bef9SDimitry Andric                           .addReg(NewVRA, getKillRegState(true))
1019e8d8bef9SDimitry Andric                           .addReg(RegX, getKillRegState(KillX))
1020e8d8bef9SDimitry Andric                           .addReg(VarReg, getKillRegState(KillVarReg));
1021e8d8bef9SDimitry Andric     // For now, we only support xsmaddadp/xsmaddasp, their add operand are
1022e8d8bef9SDimitry Andric     // both at index 1, no need to adjust.
1023e8d8bef9SDimitry Andric     // FIXME: when add more fma instructions support, like fma/fmas, adjust
1024e8d8bef9SDimitry Andric     // the operand index here.
1025e8d8bef9SDimitry Andric     break;
1026e8d8bef9SDimitry Andric   }
1027e8d8bef9SDimitry Andric   }
1028e8d8bef9SDimitry Andric 
1029e8d8bef9SDimitry Andric   if (!IsILPReassociate) {
1030e8d8bef9SDimitry Andric     setSpecialOperandAttr(*NewARegPressure, IntersectedFlags);
1031e8d8bef9SDimitry Andric     setSpecialOperandAttr(*NewCRegPressure, IntersectedFlags);
1032e8d8bef9SDimitry Andric 
1033e8d8bef9SDimitry Andric     InsInstrs.push_back(NewARegPressure);
1034e8d8bef9SDimitry Andric     InsInstrs.push_back(NewCRegPressure);
10355ffd83dbSDimitry Andric   }
10365ffd83dbSDimitry Andric 
10375ffd83dbSDimitry Andric   assert(!InsInstrs.empty() &&
10385ffd83dbSDimitry Andric          "Insertion instructions set should not be empty!");
10395ffd83dbSDimitry Andric 
10405ffd83dbSDimitry Andric   // Record old instructions for deletion.
10415ffd83dbSDimitry Andric   DelInstrs.push_back(Leaf);
1042e8d8bef9SDimitry Andric   if (IsILPReassociate)
10435ffd83dbSDimitry Andric     DelInstrs.push_back(Prev);
10445ffd83dbSDimitry Andric   DelInstrs.push_back(&Root);
10455ffd83dbSDimitry Andric }
10465ffd83dbSDimitry Andric 
10470b57cec5SDimitry Andric // Detect 32 -> 64-bit extensions where we may reuse the low sub-register.
10480b57cec5SDimitry Andric bool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
10495ffd83dbSDimitry Andric                                          Register &SrcReg, Register &DstReg,
10500b57cec5SDimitry Andric                                          unsigned &SubIdx) const {
10510b57cec5SDimitry Andric   switch (MI.getOpcode()) {
10520b57cec5SDimitry Andric   default: return false;
10530b57cec5SDimitry Andric   case PPC::EXTSW:
10540b57cec5SDimitry Andric   case PPC::EXTSW_32:
10550b57cec5SDimitry Andric   case PPC::EXTSW_32_64:
10560b57cec5SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
10570b57cec5SDimitry Andric     DstReg = MI.getOperand(0).getReg();
10580b57cec5SDimitry Andric     SubIdx = PPC::sub_32;
10590b57cec5SDimitry Andric     return true;
10600b57cec5SDimitry Andric   }
10610b57cec5SDimitry Andric }
10620b57cec5SDimitry Andric 
10630fca6ea1SDimitry Andric Register PPCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
10640b57cec5SDimitry Andric                                            int &FrameIndex) const {
1065bdd1243dSDimitry Andric   if (llvm::is_contained(getLoadOpcodesForSpillArray(), MI.getOpcode())) {
10660b57cec5SDimitry Andric     // Check for the operands added by addFrameReference (the immediate is the
10670b57cec5SDimitry Andric     // offset which defaults to 0).
10680b57cec5SDimitry Andric     if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
10690b57cec5SDimitry Andric         MI.getOperand(2).isFI()) {
10700b57cec5SDimitry Andric       FrameIndex = MI.getOperand(2).getIndex();
10710b57cec5SDimitry Andric       return MI.getOperand(0).getReg();
10720b57cec5SDimitry Andric     }
10730b57cec5SDimitry Andric   }
10740b57cec5SDimitry Andric   return 0;
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric // For opcodes with the ReMaterializable flag set, this function is called to
10780b57cec5SDimitry Andric // verify the instruction is really rematable.
1079fcaf7f86SDimitry Andric bool PPCInstrInfo::isReallyTriviallyReMaterializable(
1080fcaf7f86SDimitry Andric     const MachineInstr &MI) const {
10810b57cec5SDimitry Andric   switch (MI.getOpcode()) {
10820b57cec5SDimitry Andric   default:
1083cb14a3feSDimitry Andric     // Let base implementaion decide.
10840b57cec5SDimitry Andric     break;
10850b57cec5SDimitry Andric   case PPC::LI:
10860b57cec5SDimitry Andric   case PPC::LI8:
1087fe6060f1SDimitry Andric   case PPC::PLI:
1088fe6060f1SDimitry Andric   case PPC::PLI8:
10890b57cec5SDimitry Andric   case PPC::LIS:
10900b57cec5SDimitry Andric   case PPC::LIS8:
10910b57cec5SDimitry Andric   case PPC::ADDIStocHA:
10928bcb0991SDimitry Andric   case PPC::ADDIStocHA8:
10930b57cec5SDimitry Andric   case PPC::ADDItocL:
10940fca6ea1SDimitry Andric   case PPC::ADDItocL8:
10950b57cec5SDimitry Andric   case PPC::LOAD_STACK_GUARD:
10960fca6ea1SDimitry Andric   case PPC::PPCLdFixedAddr:
10970b57cec5SDimitry Andric   case PPC::XXLXORz:
10980b57cec5SDimitry Andric   case PPC::XXLXORspz:
10990b57cec5SDimitry Andric   case PPC::XXLXORdpz:
11008bcb0991SDimitry Andric   case PPC::XXLEQVOnes:
1101fe6060f1SDimitry Andric   case PPC::XXSPLTI32DX:
1102349cc55cSDimitry Andric   case PPC::XXSPLTIW:
1103349cc55cSDimitry Andric   case PPC::XXSPLTIDP:
11040b57cec5SDimitry Andric   case PPC::V_SET0B:
11050b57cec5SDimitry Andric   case PPC::V_SET0H:
11060b57cec5SDimitry Andric   case PPC::V_SET0:
11070b57cec5SDimitry Andric   case PPC::V_SETALLONESB:
11080b57cec5SDimitry Andric   case PPC::V_SETALLONESH:
11090b57cec5SDimitry Andric   case PPC::V_SETALLONES:
11100b57cec5SDimitry Andric   case PPC::CRSET:
11110b57cec5SDimitry Andric   case PPC::CRUNSET:
1112e8d8bef9SDimitry Andric   case PPC::XXSETACCZ:
1113bdd1243dSDimitry Andric   case PPC::XXSETACCZW:
11140b57cec5SDimitry Andric     return true;
11150b57cec5SDimitry Andric   }
11165f757f3fSDimitry Andric   return TargetInstrInfo::isReallyTriviallyReMaterializable(MI);
11170b57cec5SDimitry Andric }
11180b57cec5SDimitry Andric 
11190fca6ea1SDimitry Andric Register PPCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
11200b57cec5SDimitry Andric                                           int &FrameIndex) const {
1121bdd1243dSDimitry Andric   if (llvm::is_contained(getStoreOpcodesForSpillArray(), MI.getOpcode())) {
11220b57cec5SDimitry Andric     if (MI.getOperand(1).isImm() && !MI.getOperand(1).getImm() &&
11230b57cec5SDimitry Andric         MI.getOperand(2).isFI()) {
11240b57cec5SDimitry Andric       FrameIndex = MI.getOperand(2).getIndex();
11250b57cec5SDimitry Andric       return MI.getOperand(0).getReg();
11260b57cec5SDimitry Andric     }
11270b57cec5SDimitry Andric   }
11280b57cec5SDimitry Andric   return 0;
11290b57cec5SDimitry Andric }
11300b57cec5SDimitry Andric 
11310b57cec5SDimitry Andric MachineInstr *PPCInstrInfo::commuteInstructionImpl(MachineInstr &MI, bool NewMI,
11320b57cec5SDimitry Andric                                                    unsigned OpIdx1,
11330b57cec5SDimitry Andric                                                    unsigned OpIdx2) const {
11340b57cec5SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // Normal instructions can be commuted the obvious way.
1137480093f4SDimitry Andric   if (MI.getOpcode() != PPC::RLWIMI && MI.getOpcode() != PPC::RLWIMI_rec)
11380b57cec5SDimitry Andric     return TargetInstrInfo::commuteInstructionImpl(MI, NewMI, OpIdx1, OpIdx2);
11390b57cec5SDimitry Andric   // Note that RLWIMI can be commuted as a 32-bit instruction, but not as a
11400b57cec5SDimitry Andric   // 64-bit instruction (so we don't handle PPC::RLWIMI8 here), because
11410b57cec5SDimitry Andric   // changing the relative order of the mask operands might change what happens
11420b57cec5SDimitry Andric   // to the high-bits of the mask (and, thus, the result).
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric   // Cannot commute if it has a non-zero rotate count.
11450b57cec5SDimitry Andric   if (MI.getOperand(3).getImm() != 0)
11460b57cec5SDimitry Andric     return nullptr;
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric   // If we have a zero rotate count, we have:
11490b57cec5SDimitry Andric   //   M = mask(MB,ME)
11500b57cec5SDimitry Andric   //   Op0 = (Op1 & ~M) | (Op2 & M)
11510b57cec5SDimitry Andric   // Change this to:
11520b57cec5SDimitry Andric   //   M = mask((ME+1)&31, (MB-1)&31)
11530b57cec5SDimitry Andric   //   Op0 = (Op2 & ~M) | (Op1 & M)
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric   // Swap op1/op2
11560b57cec5SDimitry Andric   assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1157480093f4SDimitry Andric          "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
11580b57cec5SDimitry Andric   Register Reg0 = MI.getOperand(0).getReg();
11590b57cec5SDimitry Andric   Register Reg1 = MI.getOperand(1).getReg();
11600b57cec5SDimitry Andric   Register Reg2 = MI.getOperand(2).getReg();
11610b57cec5SDimitry Andric   unsigned SubReg1 = MI.getOperand(1).getSubReg();
11620b57cec5SDimitry Andric   unsigned SubReg2 = MI.getOperand(2).getSubReg();
11630b57cec5SDimitry Andric   bool Reg1IsKill = MI.getOperand(1).isKill();
11640b57cec5SDimitry Andric   bool Reg2IsKill = MI.getOperand(2).isKill();
11650b57cec5SDimitry Andric   bool ChangeReg0 = false;
11660b57cec5SDimitry Andric   // If machine instrs are no longer in two-address forms, update
11670b57cec5SDimitry Andric   // destination register as well.
11680b57cec5SDimitry Andric   if (Reg0 == Reg1) {
11695f757f3fSDimitry Andric     // Must be two address instruction (i.e. op1 is tied to op0).
11705f757f3fSDimitry Andric     assert(MI.getDesc().getOperandConstraint(1, MCOI::TIED_TO) == 0 &&
11710b57cec5SDimitry Andric            "Expecting a two-address instruction!");
11720b57cec5SDimitry Andric     assert(MI.getOperand(0).getSubReg() == SubReg1 && "Tied subreg mismatch");
11730b57cec5SDimitry Andric     Reg2IsKill = false;
11740b57cec5SDimitry Andric     ChangeReg0 = true;
11750b57cec5SDimitry Andric   }
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   // Masks.
11780b57cec5SDimitry Andric   unsigned MB = MI.getOperand(4).getImm();
11790b57cec5SDimitry Andric   unsigned ME = MI.getOperand(5).getImm();
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   // We can't commute a trivial mask (there is no way to represent an all-zero
11820b57cec5SDimitry Andric   // mask).
11830b57cec5SDimitry Andric   if (MB == 0 && ME == 31)
11840b57cec5SDimitry Andric     return nullptr;
11850b57cec5SDimitry Andric 
11860b57cec5SDimitry Andric   if (NewMI) {
11870b57cec5SDimitry Andric     // Create a new instruction.
11880b57cec5SDimitry Andric     Register Reg0 = ChangeReg0 ? Reg2 : MI.getOperand(0).getReg();
11890b57cec5SDimitry Andric     bool Reg0IsDead = MI.getOperand(0).isDead();
11900b57cec5SDimitry Andric     return BuildMI(MF, MI.getDebugLoc(), MI.getDesc())
11910b57cec5SDimitry Andric         .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead))
11920b57cec5SDimitry Andric         .addReg(Reg2, getKillRegState(Reg2IsKill))
11930b57cec5SDimitry Andric         .addReg(Reg1, getKillRegState(Reg1IsKill))
11940b57cec5SDimitry Andric         .addImm((ME + 1) & 31)
11950b57cec5SDimitry Andric         .addImm((MB - 1) & 31);
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   if (ChangeReg0) {
11990b57cec5SDimitry Andric     MI.getOperand(0).setReg(Reg2);
12000b57cec5SDimitry Andric     MI.getOperand(0).setSubReg(SubReg2);
12010b57cec5SDimitry Andric   }
12020b57cec5SDimitry Andric   MI.getOperand(2).setReg(Reg1);
12030b57cec5SDimitry Andric   MI.getOperand(1).setReg(Reg2);
12040b57cec5SDimitry Andric   MI.getOperand(2).setSubReg(SubReg1);
12050b57cec5SDimitry Andric   MI.getOperand(1).setSubReg(SubReg2);
12060b57cec5SDimitry Andric   MI.getOperand(2).setIsKill(Reg1IsKill);
12070b57cec5SDimitry Andric   MI.getOperand(1).setIsKill(Reg2IsKill);
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric   // Swap the mask around.
12100b57cec5SDimitry Andric   MI.getOperand(4).setImm((ME + 1) & 31);
12110b57cec5SDimitry Andric   MI.getOperand(5).setImm((MB - 1) & 31);
12120b57cec5SDimitry Andric   return &MI;
12130b57cec5SDimitry Andric }
12140b57cec5SDimitry Andric 
12158bcb0991SDimitry Andric bool PPCInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
12168bcb0991SDimitry Andric                                          unsigned &SrcOpIdx1,
12170b57cec5SDimitry Andric                                          unsigned &SrcOpIdx2) const {
12180b57cec5SDimitry Andric   // For VSX A-Type FMA instructions, it is the first two operands that can be
12190b57cec5SDimitry Andric   // commuted, however, because the non-encoded tied input operand is listed
12200b57cec5SDimitry Andric   // first, the operands to swap are actually the second and third.
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric   int AltOpc = PPC::getAltVSXFMAOpcode(MI.getOpcode());
12230b57cec5SDimitry Andric   if (AltOpc == -1)
12240b57cec5SDimitry Andric     return TargetInstrInfo::findCommutedOpIndices(MI, SrcOpIdx1, SrcOpIdx2);
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric   // The commutable operand indices are 2 and 3. Return them in SrcOpIdx1
12270b57cec5SDimitry Andric   // and SrcOpIdx2.
12280b57cec5SDimitry Andric   return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
12290b57cec5SDimitry Andric }
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
12320b57cec5SDimitry Andric                               MachineBasicBlock::iterator MI) const {
12330b57cec5SDimitry Andric   // This function is used for scheduling, and the nop wanted here is the type
12340b57cec5SDimitry Andric   // that terminates dispatch groups on the POWER cores.
1235480093f4SDimitry Andric   unsigned Directive = Subtarget.getCPUDirective();
12360b57cec5SDimitry Andric   unsigned Opcode;
12370b57cec5SDimitry Andric   switch (Directive) {
12380b57cec5SDimitry Andric   default:            Opcode = PPC::NOP; break;
12390b57cec5SDimitry Andric   case PPC::DIR_PWR6: Opcode = PPC::NOP_GT_PWR6; break;
12400b57cec5SDimitry Andric   case PPC::DIR_PWR7: Opcode = PPC::NOP_GT_PWR7; break;
12410b57cec5SDimitry Andric   case PPC::DIR_PWR8: Opcode = PPC::NOP_GT_PWR7; break; /* FIXME: Update when P8 InstrScheduling model is ready */
12420b57cec5SDimitry Andric   // FIXME: Update when POWER9 scheduling model is ready.
12430b57cec5SDimitry Andric   case PPC::DIR_PWR9: Opcode = PPC::NOP_GT_PWR7; break;
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric 
12460b57cec5SDimitry Andric   DebugLoc DL;
12470b57cec5SDimitry Andric   BuildMI(MBB, MI, DL, get(Opcode));
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric /// Return the noop instruction to use for a noop.
1251fe6060f1SDimitry Andric MCInst PPCInstrInfo::getNop() const {
1252fe6060f1SDimitry Andric   MCInst Nop;
1253fe6060f1SDimitry Andric   Nop.setOpcode(PPC::NOP);
1254fe6060f1SDimitry Andric   return Nop;
12550b57cec5SDimitry Andric }
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric // Branch analysis.
12580b57cec5SDimitry Andric // Note: If the condition register is set to CTR or CTR8 then this is a
12590b57cec5SDimitry Andric // BDNZ (imm == 1) or BDZ (imm == 0) branch.
12600b57cec5SDimitry Andric bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
12610b57cec5SDimitry Andric                                  MachineBasicBlock *&TBB,
12620b57cec5SDimitry Andric                                  MachineBasicBlock *&FBB,
12630b57cec5SDimitry Andric                                  SmallVectorImpl<MachineOperand> &Cond,
12640b57cec5SDimitry Andric                                  bool AllowModify) const {
12650b57cec5SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   // If the block has no terminators, it just falls into the block after it.
12680b57cec5SDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
12690b57cec5SDimitry Andric   if (I == MBB.end())
12700b57cec5SDimitry Andric     return false;
12710b57cec5SDimitry Andric 
12720b57cec5SDimitry Andric   if (!isUnpredicatedTerminator(*I))
12730b57cec5SDimitry Andric     return false;
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric   if (AllowModify) {
12760b57cec5SDimitry Andric     // If the BB ends with an unconditional branch to the fallthrough BB,
12770b57cec5SDimitry Andric     // we eliminate the branch instruction.
12780b57cec5SDimitry Andric     if (I->getOpcode() == PPC::B &&
12790b57cec5SDimitry Andric         MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
12800b57cec5SDimitry Andric       I->eraseFromParent();
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric       // We update iterator after deleting the last branch.
12830b57cec5SDimitry Andric       I = MBB.getLastNonDebugInstr();
12840b57cec5SDimitry Andric       if (I == MBB.end() || !isUnpredicatedTerminator(*I))
12850b57cec5SDimitry Andric         return false;
12860b57cec5SDimitry Andric     }
12870b57cec5SDimitry Andric   }
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric   // Get the last instruction in the block.
12900b57cec5SDimitry Andric   MachineInstr &LastInst = *I;
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric   // If there is only one terminator instruction, process it.
12930b57cec5SDimitry Andric   if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
12940b57cec5SDimitry Andric     if (LastInst.getOpcode() == PPC::B) {
12950b57cec5SDimitry Andric       if (!LastInst.getOperand(0).isMBB())
12960b57cec5SDimitry Andric         return true;
12970b57cec5SDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
12980b57cec5SDimitry Andric       return false;
12990b57cec5SDimitry Andric     } else if (LastInst.getOpcode() == PPC::BCC) {
13000b57cec5SDimitry Andric       if (!LastInst.getOperand(2).isMBB())
13010b57cec5SDimitry Andric         return true;
13020b57cec5SDimitry Andric       // Block ends with fall-through condbranch.
13030b57cec5SDimitry Andric       TBB = LastInst.getOperand(2).getMBB();
13040b57cec5SDimitry Andric       Cond.push_back(LastInst.getOperand(0));
13050b57cec5SDimitry Andric       Cond.push_back(LastInst.getOperand(1));
13060b57cec5SDimitry Andric       return false;
13070b57cec5SDimitry Andric     } else if (LastInst.getOpcode() == PPC::BC) {
13080b57cec5SDimitry Andric       if (!LastInst.getOperand(1).isMBB())
13090b57cec5SDimitry Andric         return true;
13100b57cec5SDimitry Andric       // Block ends with fall-through condbranch.
13110b57cec5SDimitry Andric       TBB = LastInst.getOperand(1).getMBB();
13120b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
13130b57cec5SDimitry Andric       Cond.push_back(LastInst.getOperand(0));
13140b57cec5SDimitry Andric       return false;
13150b57cec5SDimitry Andric     } else if (LastInst.getOpcode() == PPC::BCn) {
13160b57cec5SDimitry Andric       if (!LastInst.getOperand(1).isMBB())
13170b57cec5SDimitry Andric         return true;
13180b57cec5SDimitry Andric       // Block ends with fall-through condbranch.
13190b57cec5SDimitry Andric       TBB = LastInst.getOperand(1).getMBB();
13200b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
13210b57cec5SDimitry Andric       Cond.push_back(LastInst.getOperand(0));
13220b57cec5SDimitry Andric       return false;
13230b57cec5SDimitry Andric     } else if (LastInst.getOpcode() == PPC::BDNZ8 ||
13240b57cec5SDimitry Andric                LastInst.getOpcode() == PPC::BDNZ) {
13250b57cec5SDimitry Andric       if (!LastInst.getOperand(0).isMBB())
13260b57cec5SDimitry Andric         return true;
13270b57cec5SDimitry Andric       if (DisableCTRLoopAnal)
13280b57cec5SDimitry Andric         return true;
13290b57cec5SDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
13300b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(1));
13310b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
13320b57cec5SDimitry Andric                                                true));
13330b57cec5SDimitry Andric       return false;
13340b57cec5SDimitry Andric     } else if (LastInst.getOpcode() == PPC::BDZ8 ||
13350b57cec5SDimitry Andric                LastInst.getOpcode() == PPC::BDZ) {
13360b57cec5SDimitry Andric       if (!LastInst.getOperand(0).isMBB())
13370b57cec5SDimitry Andric         return true;
13380b57cec5SDimitry Andric       if (DisableCTRLoopAnal)
13390b57cec5SDimitry Andric         return true;
13400b57cec5SDimitry Andric       TBB = LastInst.getOperand(0).getMBB();
13410b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(0));
13420b57cec5SDimitry Andric       Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
13430b57cec5SDimitry Andric                                                true));
13440b57cec5SDimitry Andric       return false;
13450b57cec5SDimitry Andric     }
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric     // Otherwise, don't know what this is.
13480b57cec5SDimitry Andric     return true;
13490b57cec5SDimitry Andric   }
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   // Get the instruction before it if it's a terminator.
13520b57cec5SDimitry Andric   MachineInstr &SecondLastInst = *I;
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   // If there are three terminators, we don't know what sort of block this is.
13550b57cec5SDimitry Andric   if (I != MBB.begin() && isUnpredicatedTerminator(*--I))
13560b57cec5SDimitry Andric     return true;
13570b57cec5SDimitry Andric 
13580b57cec5SDimitry Andric   // If the block ends with PPC::B and PPC:BCC, handle it.
13590b57cec5SDimitry Andric   if (SecondLastInst.getOpcode() == PPC::BCC &&
13600b57cec5SDimitry Andric       LastInst.getOpcode() == PPC::B) {
13610b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(2).isMBB() ||
13620b57cec5SDimitry Andric         !LastInst.getOperand(0).isMBB())
13630b57cec5SDimitry Andric       return true;
13640b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(2).getMBB();
13650b57cec5SDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
13660b57cec5SDimitry Andric     Cond.push_back(SecondLastInst.getOperand(1));
13670b57cec5SDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
13680b57cec5SDimitry Andric     return false;
13690b57cec5SDimitry Andric   } else if (SecondLastInst.getOpcode() == PPC::BC &&
13700b57cec5SDimitry Andric              LastInst.getOpcode() == PPC::B) {
13710b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(1).isMBB() ||
13720b57cec5SDimitry Andric         !LastInst.getOperand(0).isMBB())
13730b57cec5SDimitry Andric       return true;
13740b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(1).getMBB();
13750b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
13760b57cec5SDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
13770b57cec5SDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
13780b57cec5SDimitry Andric     return false;
13790b57cec5SDimitry Andric   } else if (SecondLastInst.getOpcode() == PPC::BCn &&
13800b57cec5SDimitry Andric              LastInst.getOpcode() == PPC::B) {
13810b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(1).isMBB() ||
13820b57cec5SDimitry Andric         !LastInst.getOperand(0).isMBB())
13830b57cec5SDimitry Andric       return true;
13840b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(1).getMBB();
13850b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
13860b57cec5SDimitry Andric     Cond.push_back(SecondLastInst.getOperand(0));
13870b57cec5SDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
13880b57cec5SDimitry Andric     return false;
13890b57cec5SDimitry Andric   } else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||
13900b57cec5SDimitry Andric               SecondLastInst.getOpcode() == PPC::BDNZ) &&
13910b57cec5SDimitry Andric              LastInst.getOpcode() == PPC::B) {
13920b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB() ||
13930b57cec5SDimitry Andric         !LastInst.getOperand(0).isMBB())
13940b57cec5SDimitry Andric       return true;
13950b57cec5SDimitry Andric     if (DisableCTRLoopAnal)
13960b57cec5SDimitry Andric       return true;
13970b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
13980b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(1));
13990b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
14000b57cec5SDimitry Andric                                              true));
14010b57cec5SDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
14020b57cec5SDimitry Andric     return false;
14030b57cec5SDimitry Andric   } else if ((SecondLastInst.getOpcode() == PPC::BDZ8 ||
14040b57cec5SDimitry Andric               SecondLastInst.getOpcode() == PPC::BDZ) &&
14050b57cec5SDimitry Andric              LastInst.getOpcode() == PPC::B) {
14060b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB() ||
14070b57cec5SDimitry Andric         !LastInst.getOperand(0).isMBB())
14080b57cec5SDimitry Andric       return true;
14090b57cec5SDimitry Andric     if (DisableCTRLoopAnal)
14100b57cec5SDimitry Andric       return true;
14110b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
14120b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateImm(0));
14130b57cec5SDimitry Andric     Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
14140b57cec5SDimitry Andric                                              true));
14150b57cec5SDimitry Andric     FBB = LastInst.getOperand(0).getMBB();
14160b57cec5SDimitry Andric     return false;
14170b57cec5SDimitry Andric   }
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric   // If the block ends with two PPC:Bs, handle it.  The second one is not
14200b57cec5SDimitry Andric   // executed, so remove it.
14210b57cec5SDimitry Andric   if (SecondLastInst.getOpcode() == PPC::B && LastInst.getOpcode() == PPC::B) {
14220b57cec5SDimitry Andric     if (!SecondLastInst.getOperand(0).isMBB())
14230b57cec5SDimitry Andric       return true;
14240b57cec5SDimitry Andric     TBB = SecondLastInst.getOperand(0).getMBB();
14250b57cec5SDimitry Andric     I = LastInst;
14260b57cec5SDimitry Andric     if (AllowModify)
14270b57cec5SDimitry Andric       I->eraseFromParent();
14280b57cec5SDimitry Andric     return false;
14290b57cec5SDimitry Andric   }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   // Otherwise, can't handle this.
14320b57cec5SDimitry Andric   return true;
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric unsigned PPCInstrInfo::removeBranch(MachineBasicBlock &MBB,
14360b57cec5SDimitry Andric                                     int *BytesRemoved) const {
14370b57cec5SDimitry Andric   assert(!BytesRemoved && "code size not handled");
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
14400b57cec5SDimitry Andric   if (I == MBB.end())
14410b57cec5SDimitry Andric     return 0;
14420b57cec5SDimitry Andric 
14430b57cec5SDimitry Andric   if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&
14440b57cec5SDimitry Andric       I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
14450b57cec5SDimitry Andric       I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
14460b57cec5SDimitry Andric       I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
14470b57cec5SDimitry Andric     return 0;
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric   // Remove the branch.
14500b57cec5SDimitry Andric   I->eraseFromParent();
14510b57cec5SDimitry Andric 
14520b57cec5SDimitry Andric   I = MBB.end();
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric   if (I == MBB.begin()) return 1;
14550b57cec5SDimitry Andric   --I;
14560b57cec5SDimitry Andric   if (I->getOpcode() != PPC::BCC &&
14570b57cec5SDimitry Andric       I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&
14580b57cec5SDimitry Andric       I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
14590b57cec5SDimitry Andric       I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
14600b57cec5SDimitry Andric     return 1;
14610b57cec5SDimitry Andric 
14620b57cec5SDimitry Andric   // Remove the branch.
14630b57cec5SDimitry Andric   I->eraseFromParent();
14640b57cec5SDimitry Andric   return 2;
14650b57cec5SDimitry Andric }
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric unsigned PPCInstrInfo::insertBranch(MachineBasicBlock &MBB,
14680b57cec5SDimitry Andric                                     MachineBasicBlock *TBB,
14690b57cec5SDimitry Andric                                     MachineBasicBlock *FBB,
14700b57cec5SDimitry Andric                                     ArrayRef<MachineOperand> Cond,
14710b57cec5SDimitry Andric                                     const DebugLoc &DL,
14720b57cec5SDimitry Andric                                     int *BytesAdded) const {
14730b57cec5SDimitry Andric   // Shouldn't be a fall through.
14740b57cec5SDimitry Andric   assert(TBB && "insertBranch must not be told to insert a fallthrough");
14750b57cec5SDimitry Andric   assert((Cond.size() == 2 || Cond.size() == 0) &&
14760b57cec5SDimitry Andric          "PPC branch conditions have two components!");
14770b57cec5SDimitry Andric   assert(!BytesAdded && "code size not handled");
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric   // One-way branch.
14820b57cec5SDimitry Andric   if (!FBB) {
14830b57cec5SDimitry Andric     if (Cond.empty())   // Unconditional branch
14840b57cec5SDimitry Andric       BuildMI(&MBB, DL, get(PPC::B)).addMBB(TBB);
14850b57cec5SDimitry Andric     else if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
14860b57cec5SDimitry Andric       BuildMI(&MBB, DL, get(Cond[0].getImm() ?
14870b57cec5SDimitry Andric                               (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
14880b57cec5SDimitry Andric                               (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
14890b57cec5SDimitry Andric     else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
14900b57cec5SDimitry Andric       BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
14910b57cec5SDimitry Andric     else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
14920b57cec5SDimitry Andric       BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
14930b57cec5SDimitry Andric     else                // Conditional branch
14940b57cec5SDimitry Andric       BuildMI(&MBB, DL, get(PPC::BCC))
14950b57cec5SDimitry Andric           .addImm(Cond[0].getImm())
14960b57cec5SDimitry Andric           .add(Cond[1])
14970b57cec5SDimitry Andric           .addMBB(TBB);
14980b57cec5SDimitry Andric     return 1;
14990b57cec5SDimitry Andric   }
15000b57cec5SDimitry Andric 
15010b57cec5SDimitry Andric   // Two-way Conditional Branch.
15020b57cec5SDimitry Andric   if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
15030b57cec5SDimitry Andric     BuildMI(&MBB, DL, get(Cond[0].getImm() ?
15040b57cec5SDimitry Andric                             (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
15050b57cec5SDimitry Andric                             (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
15060b57cec5SDimitry Andric   else if (Cond[0].getImm() == PPC::PRED_BIT_SET)
15070b57cec5SDimitry Andric     BuildMI(&MBB, DL, get(PPC::BC)).add(Cond[1]).addMBB(TBB);
15080b57cec5SDimitry Andric   else if (Cond[0].getImm() == PPC::PRED_BIT_UNSET)
15090b57cec5SDimitry Andric     BuildMI(&MBB, DL, get(PPC::BCn)).add(Cond[1]).addMBB(TBB);
15100b57cec5SDimitry Andric   else
15110b57cec5SDimitry Andric     BuildMI(&MBB, DL, get(PPC::BCC))
15120b57cec5SDimitry Andric         .addImm(Cond[0].getImm())
15130b57cec5SDimitry Andric         .add(Cond[1])
15140b57cec5SDimitry Andric         .addMBB(TBB);
15150b57cec5SDimitry Andric   BuildMI(&MBB, DL, get(PPC::B)).addMBB(FBB);
15160b57cec5SDimitry Andric   return 2;
15170b57cec5SDimitry Andric }
15180b57cec5SDimitry Andric 
15190b57cec5SDimitry Andric // Select analysis.
15200b57cec5SDimitry Andric bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
15210b57cec5SDimitry Andric                                    ArrayRef<MachineOperand> Cond,
15225ffd83dbSDimitry Andric                                    Register DstReg, Register TrueReg,
15235ffd83dbSDimitry Andric                                    Register FalseReg, int &CondCycles,
15245ffd83dbSDimitry Andric                                    int &TrueCycles, int &FalseCycles) const {
15255f757f3fSDimitry Andric   if (!Subtarget.hasISEL())
15265f757f3fSDimitry Andric     return false;
15275f757f3fSDimitry Andric 
15280b57cec5SDimitry Andric   if (Cond.size() != 2)
15290b57cec5SDimitry Andric     return false;
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric   // If this is really a bdnz-like condition, then it cannot be turned into a
15320b57cec5SDimitry Andric   // select.
15330b57cec5SDimitry Andric   if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
15340b57cec5SDimitry Andric     return false;
15350b57cec5SDimitry Andric 
1536349cc55cSDimitry Andric   // If the conditional branch uses a physical register, then it cannot be
1537349cc55cSDimitry Andric   // turned into a select.
1538bdd1243dSDimitry Andric   if (Cond[1].getReg().isPhysical())
1539349cc55cSDimitry Andric     return false;
1540349cc55cSDimitry Andric 
15410b57cec5SDimitry Andric   // Check register classes.
15420b57cec5SDimitry Andric   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
15430b57cec5SDimitry Andric   const TargetRegisterClass *RC =
15440b57cec5SDimitry Andric     RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
15450b57cec5SDimitry Andric   if (!RC)
15460b57cec5SDimitry Andric     return false;
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric   // isel is for regular integer GPRs only.
15490b57cec5SDimitry Andric   if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
15500b57cec5SDimitry Andric       !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
15510b57cec5SDimitry Andric       !PPC::G8RCRegClass.hasSubClassEq(RC) &&
15520b57cec5SDimitry Andric       !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
15530b57cec5SDimitry Andric     return false;
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric   // FIXME: These numbers are for the A2, how well they work for other cores is
15560b57cec5SDimitry Andric   // an open question. On the A2, the isel instruction has a 2-cycle latency
15570b57cec5SDimitry Andric   // but single-cycle throughput. These numbers are used in combination with
15580b57cec5SDimitry Andric   // the MispredictPenalty setting from the active SchedMachineModel.
15590b57cec5SDimitry Andric   CondCycles = 1;
15600b57cec5SDimitry Andric   TrueCycles = 1;
15610b57cec5SDimitry Andric   FalseCycles = 1;
15620b57cec5SDimitry Andric 
15630b57cec5SDimitry Andric   return true;
15640b57cec5SDimitry Andric }
15650b57cec5SDimitry Andric 
15660b57cec5SDimitry Andric void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
15670b57cec5SDimitry Andric                                 MachineBasicBlock::iterator MI,
15685ffd83dbSDimitry Andric                                 const DebugLoc &dl, Register DestReg,
15695ffd83dbSDimitry Andric                                 ArrayRef<MachineOperand> Cond, Register TrueReg,
15705ffd83dbSDimitry Andric                                 Register FalseReg) const {
15710b57cec5SDimitry Andric   assert(Cond.size() == 2 &&
15720b57cec5SDimitry Andric          "PPC branch conditions have two components!");
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric   // Get the register classes.
15750b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
15760b57cec5SDimitry Andric   const TargetRegisterClass *RC =
15770b57cec5SDimitry Andric     RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
15780b57cec5SDimitry Andric   assert(RC && "TrueReg and FalseReg must have overlapping register classes");
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric   bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
15810b57cec5SDimitry Andric                  PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
15820b57cec5SDimitry Andric   assert((Is64Bit ||
15830b57cec5SDimitry Andric           PPC::GPRCRegClass.hasSubClassEq(RC) ||
15840b57cec5SDimitry Andric           PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
15850b57cec5SDimitry Andric          "isel is for regular integer GPRs only");
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric   unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
15880b57cec5SDimitry Andric   auto SelectPred = static_cast<PPC::Predicate>(Cond[0].getImm());
15890b57cec5SDimitry Andric 
15900b57cec5SDimitry Andric   unsigned SubIdx = 0;
15910b57cec5SDimitry Andric   bool SwapOps = false;
15920b57cec5SDimitry Andric   switch (SelectPred) {
15930b57cec5SDimitry Andric   case PPC::PRED_EQ:
15940b57cec5SDimitry Andric   case PPC::PRED_EQ_MINUS:
15950b57cec5SDimitry Andric   case PPC::PRED_EQ_PLUS:
15960b57cec5SDimitry Andric       SubIdx = PPC::sub_eq; SwapOps = false; break;
15970b57cec5SDimitry Andric   case PPC::PRED_NE:
15980b57cec5SDimitry Andric   case PPC::PRED_NE_MINUS:
15990b57cec5SDimitry Andric   case PPC::PRED_NE_PLUS:
16000b57cec5SDimitry Andric       SubIdx = PPC::sub_eq; SwapOps = true; break;
16010b57cec5SDimitry Andric   case PPC::PRED_LT:
16020b57cec5SDimitry Andric   case PPC::PRED_LT_MINUS:
16030b57cec5SDimitry Andric   case PPC::PRED_LT_PLUS:
16040b57cec5SDimitry Andric       SubIdx = PPC::sub_lt; SwapOps = false; break;
16050b57cec5SDimitry Andric   case PPC::PRED_GE:
16060b57cec5SDimitry Andric   case PPC::PRED_GE_MINUS:
16070b57cec5SDimitry Andric   case PPC::PRED_GE_PLUS:
16080b57cec5SDimitry Andric       SubIdx = PPC::sub_lt; SwapOps = true; break;
16090b57cec5SDimitry Andric   case PPC::PRED_GT:
16100b57cec5SDimitry Andric   case PPC::PRED_GT_MINUS:
16110b57cec5SDimitry Andric   case PPC::PRED_GT_PLUS:
16120b57cec5SDimitry Andric       SubIdx = PPC::sub_gt; SwapOps = false; break;
16130b57cec5SDimitry Andric   case PPC::PRED_LE:
16140b57cec5SDimitry Andric   case PPC::PRED_LE_MINUS:
16150b57cec5SDimitry Andric   case PPC::PRED_LE_PLUS:
16160b57cec5SDimitry Andric       SubIdx = PPC::sub_gt; SwapOps = true; break;
16170b57cec5SDimitry Andric   case PPC::PRED_UN:
16180b57cec5SDimitry Andric   case PPC::PRED_UN_MINUS:
16190b57cec5SDimitry Andric   case PPC::PRED_UN_PLUS:
16200b57cec5SDimitry Andric       SubIdx = PPC::sub_un; SwapOps = false; break;
16210b57cec5SDimitry Andric   case PPC::PRED_NU:
16220b57cec5SDimitry Andric   case PPC::PRED_NU_MINUS:
16230b57cec5SDimitry Andric   case PPC::PRED_NU_PLUS:
16240b57cec5SDimitry Andric       SubIdx = PPC::sub_un; SwapOps = true; break;
16250b57cec5SDimitry Andric   case PPC::PRED_BIT_SET:   SubIdx = 0; SwapOps = false; break;
16260b57cec5SDimitry Andric   case PPC::PRED_BIT_UNSET: SubIdx = 0; SwapOps = true; break;
16270b57cec5SDimitry Andric   }
16280b57cec5SDimitry Andric 
16295ffd83dbSDimitry Andric   Register FirstReg =  SwapOps ? FalseReg : TrueReg,
16300b57cec5SDimitry Andric            SecondReg = SwapOps ? TrueReg  : FalseReg;
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   // The first input register of isel cannot be r0. If it is a member
16330b57cec5SDimitry Andric   // of a register class that can be r0, then copy it first (the
16340b57cec5SDimitry Andric   // register allocator should eliminate the copy).
16350b57cec5SDimitry Andric   if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
16360b57cec5SDimitry Andric       MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
16370b57cec5SDimitry Andric     const TargetRegisterClass *FirstRC =
16380b57cec5SDimitry Andric       MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
16390b57cec5SDimitry Andric         &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
16405ffd83dbSDimitry Andric     Register OldFirstReg = FirstReg;
16410b57cec5SDimitry Andric     FirstReg = MRI.createVirtualRegister(FirstRC);
16420b57cec5SDimitry Andric     BuildMI(MBB, MI, dl, get(TargetOpcode::COPY), FirstReg)
16430b57cec5SDimitry Andric       .addReg(OldFirstReg);
16440b57cec5SDimitry Andric   }
16450b57cec5SDimitry Andric 
16460b57cec5SDimitry Andric   BuildMI(MBB, MI, dl, get(OpCode), DestReg)
16470b57cec5SDimitry Andric     .addReg(FirstReg).addReg(SecondReg)
16480b57cec5SDimitry Andric     .addReg(Cond[1].getReg(), 0, SubIdx);
16490b57cec5SDimitry Andric }
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric static unsigned getCRBitValue(unsigned CRBit) {
16520b57cec5SDimitry Andric   unsigned Ret = 4;
16530b57cec5SDimitry Andric   if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
16540b57cec5SDimitry Andric       CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
16550b57cec5SDimitry Andric       CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
16560b57cec5SDimitry Andric       CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
16570b57cec5SDimitry Andric     Ret = 3;
16580b57cec5SDimitry Andric   if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
16590b57cec5SDimitry Andric       CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
16600b57cec5SDimitry Andric       CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
16610b57cec5SDimitry Andric       CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
16620b57cec5SDimitry Andric     Ret = 2;
16630b57cec5SDimitry Andric   if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
16640b57cec5SDimitry Andric       CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
16650b57cec5SDimitry Andric       CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
16660b57cec5SDimitry Andric       CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
16670b57cec5SDimitry Andric     Ret = 1;
16680b57cec5SDimitry Andric   if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
16690b57cec5SDimitry Andric       CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
16700b57cec5SDimitry Andric       CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
16710b57cec5SDimitry Andric       CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
16720b57cec5SDimitry Andric     Ret = 0;
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   assert(Ret != 4 && "Invalid CR bit register");
16750b57cec5SDimitry Andric   return Ret;
16760b57cec5SDimitry Andric }
16770b57cec5SDimitry Andric 
16780b57cec5SDimitry Andric void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
16790b57cec5SDimitry Andric                                MachineBasicBlock::iterator I,
1680480093f4SDimitry Andric                                const DebugLoc &DL, MCRegister DestReg,
1681480093f4SDimitry Andric                                MCRegister SrcReg, bool KillSrc) const {
16820b57cec5SDimitry Andric   // We can end up with self copies and similar things as a result of VSX copy
16830b57cec5SDimitry Andric   // legalization. Promote them here.
16840b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
16850b57cec5SDimitry Andric   if (PPC::F8RCRegClass.contains(DestReg) &&
16860b57cec5SDimitry Andric       PPC::VSRCRegClass.contains(SrcReg)) {
1687480093f4SDimitry Andric     MCRegister SuperReg =
16880b57cec5SDimitry Andric         TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric     if (VSXSelfCopyCrash && SrcReg == SuperReg)
16910b57cec5SDimitry Andric       llvm_unreachable("nop VSX copy");
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric     DestReg = SuperReg;
16940b57cec5SDimitry Andric   } else if (PPC::F8RCRegClass.contains(SrcReg) &&
16950b57cec5SDimitry Andric              PPC::VSRCRegClass.contains(DestReg)) {
1696480093f4SDimitry Andric     MCRegister SuperReg =
16970b57cec5SDimitry Andric         TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric     if (VSXSelfCopyCrash && DestReg == SuperReg)
17000b57cec5SDimitry Andric       llvm_unreachable("nop VSX copy");
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric     SrcReg = SuperReg;
17030b57cec5SDimitry Andric   }
17040b57cec5SDimitry Andric 
17050b57cec5SDimitry Andric   // Different class register copy
17060b57cec5SDimitry Andric   if (PPC::CRBITRCRegClass.contains(SrcReg) &&
17070b57cec5SDimitry Andric       PPC::GPRCRegClass.contains(DestReg)) {
1708480093f4SDimitry Andric     MCRegister CRReg = getCRFromCRBit(SrcReg);
17090b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFOCRF), DestReg).addReg(CRReg);
17100b57cec5SDimitry Andric     getKillRegState(KillSrc);
17110b57cec5SDimitry Andric     // Rotate the CR bit in the CR fields to be the least significant bit and
17120b57cec5SDimitry Andric     // then mask with 0x1 (MB = ME = 31).
17130b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::RLWINM), DestReg)
17140b57cec5SDimitry Andric        .addReg(DestReg, RegState::Kill)
17150b57cec5SDimitry Andric        .addImm(TRI->getEncodingValue(CRReg) * 4 + (4 - getCRBitValue(SrcReg)))
17160b57cec5SDimitry Andric        .addImm(31)
17170b57cec5SDimitry Andric        .addImm(31);
17180b57cec5SDimitry Andric     return;
17190b57cec5SDimitry Andric   } else if (PPC::CRRCRegClass.contains(SrcReg) &&
1720e8d8bef9SDimitry Andric              (PPC::G8RCRegClass.contains(DestReg) ||
1721e8d8bef9SDimitry Andric               PPC::GPRCRegClass.contains(DestReg))) {
1722e8d8bef9SDimitry Andric     bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1723e8d8bef9SDimitry Andric     unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1724e8d8bef9SDimitry Andric     unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1725e8d8bef9SDimitry Andric     unsigned CRNum = TRI->getEncodingValue(SrcReg);
1726e8d8bef9SDimitry Andric     BuildMI(MBB, I, DL, get(MvCode), DestReg).addReg(SrcReg);
17270b57cec5SDimitry Andric     getKillRegState(KillSrc);
1728e8d8bef9SDimitry Andric     if (CRNum == 7)
17290b57cec5SDimitry Andric       return;
1730e8d8bef9SDimitry Andric     // Shift the CR bits to make the CR field in the lowest 4 bits of GRC.
1731e8d8bef9SDimitry Andric     BuildMI(MBB, I, DL, get(ShCode), DestReg)
1732e8d8bef9SDimitry Andric         .addReg(DestReg, RegState::Kill)
1733e8d8bef9SDimitry Andric         .addImm(CRNum * 4 + 4)
1734e8d8bef9SDimitry Andric         .addImm(28)
1735e8d8bef9SDimitry Andric         .addImm(31);
17360b57cec5SDimitry Andric     return;
17370b57cec5SDimitry Andric   } else if (PPC::G8RCRegClass.contains(SrcReg) &&
17380b57cec5SDimitry Andric              PPC::VSFRCRegClass.contains(DestReg)) {
17390b57cec5SDimitry Andric     assert(Subtarget.hasDirectMove() &&
17400b57cec5SDimitry Andric            "Subtarget doesn't support directmove, don't know how to copy.");
17410b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MTVSRD), DestReg).addReg(SrcReg);
17420b57cec5SDimitry Andric     NumGPRtoVSRSpill++;
17430b57cec5SDimitry Andric     getKillRegState(KillSrc);
17440b57cec5SDimitry Andric     return;
17450b57cec5SDimitry Andric   } else if (PPC::VSFRCRegClass.contains(SrcReg) &&
17460b57cec5SDimitry Andric              PPC::G8RCRegClass.contains(DestReg)) {
17470b57cec5SDimitry Andric     assert(Subtarget.hasDirectMove() &&
17480b57cec5SDimitry Andric            "Subtarget doesn't support directmove, don't know how to copy.");
17490b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::MFVSRD), DestReg).addReg(SrcReg);
17500b57cec5SDimitry Andric     getKillRegState(KillSrc);
17510b57cec5SDimitry Andric     return;
17520b57cec5SDimitry Andric   } else if (PPC::SPERCRegClass.contains(SrcReg) &&
17538bcb0991SDimitry Andric              PPC::GPRCRegClass.contains(DestReg)) {
17540b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::EFSCFD), DestReg).addReg(SrcReg);
17550b57cec5SDimitry Andric     getKillRegState(KillSrc);
17560b57cec5SDimitry Andric     return;
17578bcb0991SDimitry Andric   } else if (PPC::GPRCRegClass.contains(SrcReg) &&
17580b57cec5SDimitry Andric              PPC::SPERCRegClass.contains(DestReg)) {
17590b57cec5SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::EFDCFS), DestReg).addReg(SrcReg);
17600b57cec5SDimitry Andric     getKillRegState(KillSrc);
17610b57cec5SDimitry Andric     return;
17620b57cec5SDimitry Andric   }
17630b57cec5SDimitry Andric 
17640b57cec5SDimitry Andric   unsigned Opc;
17650b57cec5SDimitry Andric   if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
17660b57cec5SDimitry Andric     Opc = PPC::OR;
17670b57cec5SDimitry Andric   else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))
17680b57cec5SDimitry Andric     Opc = PPC::OR8;
17690b57cec5SDimitry Andric   else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))
17700b57cec5SDimitry Andric     Opc = PPC::FMR;
17710b57cec5SDimitry Andric   else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))
17720b57cec5SDimitry Andric     Opc = PPC::MCRF;
17730b57cec5SDimitry Andric   else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))
17740b57cec5SDimitry Andric     Opc = PPC::VOR;
17750b57cec5SDimitry Andric   else if (PPC::VSRCRegClass.contains(DestReg, SrcReg))
17760b57cec5SDimitry Andric     // There are two different ways this can be done:
17770b57cec5SDimitry Andric     //   1. xxlor : This has lower latency (on the P7), 2 cycles, but can only
17780b57cec5SDimitry Andric     //      issue in VSU pipeline 0.
17790b57cec5SDimitry Andric     //   2. xmovdp/xmovsp: This has higher latency (on the P7), 6 cycles, but
17800b57cec5SDimitry Andric     //      can go to either pipeline.
17810b57cec5SDimitry Andric     // We'll always use xxlor here, because in practically all cases where
17820b57cec5SDimitry Andric     // copies are generated, they are close enough to some use that the
17830b57cec5SDimitry Andric     // lower-latency form is preferable.
17840b57cec5SDimitry Andric     Opc = PPC::XXLOR;
17850b57cec5SDimitry Andric   else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||
17860b57cec5SDimitry Andric            PPC::VSSRCRegClass.contains(DestReg, SrcReg))
17870b57cec5SDimitry Andric     Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1788e8d8bef9SDimitry Andric   else if (Subtarget.pairedVectorMemops() &&
1789e8d8bef9SDimitry Andric            PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1790e8d8bef9SDimitry Andric     if (SrcReg > PPC::VSRp15)
1791e8d8bef9SDimitry Andric       SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1792e8d8bef9SDimitry Andric     else
1793e8d8bef9SDimitry Andric       SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1794e8d8bef9SDimitry Andric     if (DestReg > PPC::VSRp15)
1795e8d8bef9SDimitry Andric       DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1796e8d8bef9SDimitry Andric     else
1797e8d8bef9SDimitry Andric       DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1798e8d8bef9SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg).
1799e8d8bef9SDimitry Andric       addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
1800e8d8bef9SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::XXLOR), DestReg + 1).
1801e8d8bef9SDimitry Andric       addReg(SrcReg + 1).addReg(SrcReg + 1, getKillRegState(KillSrc));
1802e8d8bef9SDimitry Andric     return;
1803e8d8bef9SDimitry Andric   }
18040b57cec5SDimitry Andric   else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
18050b57cec5SDimitry Andric     Opc = PPC::CROR;
18060b57cec5SDimitry Andric   else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))
18070b57cec5SDimitry Andric     Opc = PPC::EVOR;
1808e8d8bef9SDimitry Andric   else if ((PPC::ACCRCRegClass.contains(DestReg) ||
1809e8d8bef9SDimitry Andric             PPC::UACCRCRegClass.contains(DestReg)) &&
1810e8d8bef9SDimitry Andric            (PPC::ACCRCRegClass.contains(SrcReg) ||
1811e8d8bef9SDimitry Andric             PPC::UACCRCRegClass.contains(SrcReg))) {
1812e8d8bef9SDimitry Andric     // If primed, de-prime the source register, copy the individual registers
1813e8d8bef9SDimitry Andric     // and prime the destination if needed. The vector subregisters are
1814e8d8bef9SDimitry Andric     // vs[(u)acc * 4] - vs[(u)acc * 4 + 3]. If the copy is not a kill and the
1815e8d8bef9SDimitry Andric     // source is primed, we need to re-prime it after the copy as well.
1816e8d8bef9SDimitry Andric     PPCRegisterInfo::emitAccCopyInfo(MBB, DestReg, SrcReg);
1817e8d8bef9SDimitry Andric     bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1818e8d8bef9SDimitry Andric     bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1819e8d8bef9SDimitry Andric     MCRegister VSLSrcReg =
1820e8d8bef9SDimitry Andric         PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1821e8d8bef9SDimitry Andric     MCRegister VSLDestReg =
1822e8d8bef9SDimitry Andric         PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1823e8d8bef9SDimitry Andric     if (SrcPrimed)
1824e8d8bef9SDimitry Andric       BuildMI(MBB, I, DL, get(PPC::XXMFACC), SrcReg).addReg(SrcReg);
1825e8d8bef9SDimitry Andric     for (unsigned Idx = 0; Idx < 4; Idx++)
1826e8d8bef9SDimitry Andric       BuildMI(MBB, I, DL, get(PPC::XXLOR), VSLDestReg + Idx)
1827e8d8bef9SDimitry Andric           .addReg(VSLSrcReg + Idx)
1828e8d8bef9SDimitry Andric           .addReg(VSLSrcReg + Idx, getKillRegState(KillSrc));
1829e8d8bef9SDimitry Andric     if (DestPrimed)
1830e8d8bef9SDimitry Andric       BuildMI(MBB, I, DL, get(PPC::XXMTACC), DestReg).addReg(DestReg);
1831e8d8bef9SDimitry Andric     if (SrcPrimed && !KillSrc)
1832e8d8bef9SDimitry Andric       BuildMI(MBB, I, DL, get(PPC::XXMTACC), SrcReg).addReg(SrcReg);
1833e8d8bef9SDimitry Andric     return;
1834fe6060f1SDimitry Andric   } else if (PPC::G8pRCRegClass.contains(DestReg) &&
1835fe6060f1SDimitry Andric              PPC::G8pRCRegClass.contains(SrcReg)) {
1836fe6060f1SDimitry Andric     // TODO: Handle G8RC to G8pRC (and vice versa) copy.
1837fe6060f1SDimitry Andric     unsigned DestRegIdx = DestReg - PPC::G8p0;
1838fe6060f1SDimitry Andric     MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1839fe6060f1SDimitry Andric     MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1840fe6060f1SDimitry Andric     unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1841fe6060f1SDimitry Andric     MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1842fe6060f1SDimitry Andric     MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1843fe6060f1SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::OR8), DestRegSub0)
1844fe6060f1SDimitry Andric         .addReg(SrcRegSub0)
1845fe6060f1SDimitry Andric         .addReg(SrcRegSub0, getKillRegState(KillSrc));
1846fe6060f1SDimitry Andric     BuildMI(MBB, I, DL, get(PPC::OR8), DestRegSub1)
1847fe6060f1SDimitry Andric         .addReg(SrcRegSub1)
1848fe6060f1SDimitry Andric         .addReg(SrcRegSub1, getKillRegState(KillSrc));
1849fe6060f1SDimitry Andric     return;
1850e8d8bef9SDimitry Andric   } else
18510b57cec5SDimitry Andric     llvm_unreachable("Impossible reg-to-reg copy");
18520b57cec5SDimitry Andric 
18530b57cec5SDimitry Andric   const MCInstrDesc &MCID = get(Opc);
18540b57cec5SDimitry Andric   if (MCID.getNumOperands() == 3)
18550b57cec5SDimitry Andric     BuildMI(MBB, I, DL, MCID, DestReg)
18560b57cec5SDimitry Andric       .addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
18570b57cec5SDimitry Andric   else
18580b57cec5SDimitry Andric     BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc));
18590b57cec5SDimitry Andric }
18600b57cec5SDimitry Andric 
1861e8d8bef9SDimitry Andric unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {
18620b57cec5SDimitry Andric   int OpcodeIndex = 0;
18630b57cec5SDimitry Andric 
18640b57cec5SDimitry Andric   if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
18650b57cec5SDimitry Andric       PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
18660b57cec5SDimitry Andric     OpcodeIndex = SOK_Int4Spill;
18670b57cec5SDimitry Andric   } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
18680b57cec5SDimitry Andric              PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
18690b57cec5SDimitry Andric     OpcodeIndex = SOK_Int8Spill;
18700b57cec5SDimitry Andric   } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
18710b57cec5SDimitry Andric     OpcodeIndex = SOK_Float8Spill;
18720b57cec5SDimitry Andric   } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
18730b57cec5SDimitry Andric     OpcodeIndex = SOK_Float4Spill;
18740b57cec5SDimitry Andric   } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
18750b57cec5SDimitry Andric     OpcodeIndex = SOK_SPESpill;
18760b57cec5SDimitry Andric   } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
18770b57cec5SDimitry Andric     OpcodeIndex = SOK_CRSpill;
18780b57cec5SDimitry Andric   } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
18790b57cec5SDimitry Andric     OpcodeIndex = SOK_CRBitSpill;
18800b57cec5SDimitry Andric   } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
18810b57cec5SDimitry Andric     OpcodeIndex = SOK_VRVectorSpill;
18820b57cec5SDimitry Andric   } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
18830b57cec5SDimitry Andric     OpcodeIndex = SOK_VSXVectorSpill;
18840b57cec5SDimitry Andric   } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
18850b57cec5SDimitry Andric     OpcodeIndex = SOK_VectorFloat8Spill;
18860b57cec5SDimitry Andric   } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
18870b57cec5SDimitry Andric     OpcodeIndex = SOK_VectorFloat4Spill;
18880b57cec5SDimitry Andric   } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
18890b57cec5SDimitry Andric     OpcodeIndex = SOK_SpillToVSR;
1890e8d8bef9SDimitry Andric   } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1891e8d8bef9SDimitry Andric     assert(Subtarget.pairedVectorMemops() &&
1892e8d8bef9SDimitry Andric            "Register unexpected when paired memops are disabled.");
1893e8d8bef9SDimitry Andric     OpcodeIndex = SOK_AccumulatorSpill;
1894e8d8bef9SDimitry Andric   } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1895e8d8bef9SDimitry Andric     assert(Subtarget.pairedVectorMemops() &&
1896e8d8bef9SDimitry Andric            "Register unexpected when paired memops are disabled.");
1897e8d8bef9SDimitry Andric     OpcodeIndex = SOK_UAccumulatorSpill;
1898bdd1243dSDimitry Andric   } else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1899bdd1243dSDimitry Andric     assert(Subtarget.pairedVectorMemops() &&
1900bdd1243dSDimitry Andric            "Register unexpected when paired memops are disabled.");
1901bdd1243dSDimitry Andric     OpcodeIndex = SOK_WAccumulatorSpill;
1902e8d8bef9SDimitry Andric   } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1903e8d8bef9SDimitry Andric     assert(Subtarget.pairedVectorMemops() &&
1904e8d8bef9SDimitry Andric            "Register unexpected when paired memops are disabled.");
1905e8d8bef9SDimitry Andric     OpcodeIndex = SOK_PairedVecSpill;
1906fe6060f1SDimitry Andric   } else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1907fe6060f1SDimitry Andric     OpcodeIndex = SOK_PairedG8Spill;
19080b57cec5SDimitry Andric   } else {
19090b57cec5SDimitry Andric     llvm_unreachable("Unknown regclass!");
19100b57cec5SDimitry Andric   }
19115ffd83dbSDimitry Andric   return OpcodeIndex;
19120b57cec5SDimitry Andric }
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric unsigned
19155ffd83dbSDimitry Andric PPCInstrInfo::getStoreOpcodeForSpill(const TargetRegisterClass *RC) const {
1916bdd1243dSDimitry Andric   ArrayRef<unsigned> OpcodesForSpill = getStoreOpcodesForSpillArray();
19175ffd83dbSDimitry Andric   return OpcodesForSpill[getSpillIndex(RC)];
19185ffd83dbSDimitry Andric }
19190b57cec5SDimitry Andric 
19205ffd83dbSDimitry Andric unsigned
19215ffd83dbSDimitry Andric PPCInstrInfo::getLoadOpcodeForSpill(const TargetRegisterClass *RC) const {
1922bdd1243dSDimitry Andric   ArrayRef<unsigned> OpcodesForSpill = getLoadOpcodesForSpillArray();
19235ffd83dbSDimitry Andric   return OpcodesForSpill[getSpillIndex(RC)];
19240b57cec5SDimitry Andric }
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric void PPCInstrInfo::StoreRegToStackSlot(
19270b57cec5SDimitry Andric     MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,
19280b57cec5SDimitry Andric     const TargetRegisterClass *RC,
19290b57cec5SDimitry Andric     SmallVectorImpl<MachineInstr *> &NewMIs) const {
19305ffd83dbSDimitry Andric   unsigned Opcode = getStoreOpcodeForSpill(RC);
19310b57cec5SDimitry Andric   DebugLoc DL;
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric   PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
19340b57cec5SDimitry Andric   FuncInfo->setHasSpills();
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric   NewMIs.push_back(addFrameReference(
19370b57cec5SDimitry Andric       BuildMI(MF, DL, get(Opcode)).addReg(SrcReg, getKillRegState(isKill)),
19380b57cec5SDimitry Andric       FrameIdx));
19390b57cec5SDimitry Andric 
19400b57cec5SDimitry Andric   if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
19410b57cec5SDimitry Andric       PPC::CRBITRCRegClass.hasSubClassEq(RC))
19420b57cec5SDimitry Andric     FuncInfo->setSpillsCR();
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric   if (isXFormMemOp(Opcode))
19450b57cec5SDimitry Andric     FuncInfo->setHasNonRISpills();
19460b57cec5SDimitry Andric }
19470b57cec5SDimitry Andric 
19485ffd83dbSDimitry Andric void PPCInstrInfo::storeRegToStackSlotNoUpd(
19495ffd83dbSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned SrcReg,
19505ffd83dbSDimitry Andric     bool isKill, int FrameIdx, const TargetRegisterClass *RC,
19510b57cec5SDimitry Andric     const TargetRegisterInfo *TRI) const {
19520b57cec5SDimitry Andric   MachineFunction &MF = *MBB.getParent();
19530b57cec5SDimitry Andric   SmallVector<MachineInstr *, 4> NewMIs;
19540b57cec5SDimitry Andric 
19550b57cec5SDimitry Andric   StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
19560b57cec5SDimitry Andric 
19570fca6ea1SDimitry Andric   for (MachineInstr *NewMI : NewMIs)
19580fca6ea1SDimitry Andric     MBB.insert(MI, NewMI);
19590b57cec5SDimitry Andric 
19600b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
19610b57cec5SDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
19620b57cec5SDimitry Andric       MachinePointerInfo::getFixedStack(MF, FrameIdx),
19630b57cec5SDimitry Andric       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
19645ffd83dbSDimitry Andric       MFI.getObjectAlign(FrameIdx));
19650b57cec5SDimitry Andric   NewMIs.back()->addMemOperand(MF, MMO);
19660b57cec5SDimitry Andric }
19670b57cec5SDimitry Andric 
1968bdd1243dSDimitry Andric void PPCInstrInfo::storeRegToStackSlot(
1969bdd1243dSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
1970bdd1243dSDimitry Andric     bool isKill, int FrameIdx, const TargetRegisterClass *RC,
1971bdd1243dSDimitry Andric     const TargetRegisterInfo *TRI, Register VReg) const {
19725ffd83dbSDimitry Andric   // We need to avoid a situation in which the value from a VRRC register is
19735ffd83dbSDimitry Andric   // spilled using an Altivec instruction and reloaded into a VSRC register
19745ffd83dbSDimitry Andric   // using a VSX instruction. The issue with this is that the VSX
19755ffd83dbSDimitry Andric   // load/store instructions swap the doublewords in the vector and the Altivec
19765ffd83dbSDimitry Andric   // ones don't. The register classes on the spill/reload may be different if
19775ffd83dbSDimitry Andric   // the register is defined using an Altivec instruction and is then used by a
19785ffd83dbSDimitry Andric   // VSX instruction.
19795ffd83dbSDimitry Andric   RC = updatedRC(RC);
19805ffd83dbSDimitry Andric   storeRegToStackSlotNoUpd(MBB, MI, SrcReg, isKill, FrameIdx, RC, TRI);
19815ffd83dbSDimitry Andric }
19825ffd83dbSDimitry Andric 
19830b57cec5SDimitry Andric void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, const DebugLoc &DL,
19840b57cec5SDimitry Andric                                         unsigned DestReg, int FrameIdx,
19850b57cec5SDimitry Andric                                         const TargetRegisterClass *RC,
19860b57cec5SDimitry Andric                                         SmallVectorImpl<MachineInstr *> &NewMIs)
19870b57cec5SDimitry Andric                                         const {
19885ffd83dbSDimitry Andric   unsigned Opcode = getLoadOpcodeForSpill(RC);
19890b57cec5SDimitry Andric   NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(Opcode), DestReg),
19900b57cec5SDimitry Andric                                      FrameIdx));
19910b57cec5SDimitry Andric }
19920b57cec5SDimitry Andric 
19935ffd83dbSDimitry Andric void PPCInstrInfo::loadRegFromStackSlotNoUpd(
19945ffd83dbSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg,
19955ffd83dbSDimitry Andric     int FrameIdx, const TargetRegisterClass *RC,
19960b57cec5SDimitry Andric     const TargetRegisterInfo *TRI) const {
19970b57cec5SDimitry Andric   MachineFunction &MF = *MBB.getParent();
19980b57cec5SDimitry Andric   SmallVector<MachineInstr*, 4> NewMIs;
19990b57cec5SDimitry Andric   DebugLoc DL;
20000b57cec5SDimitry Andric   if (MI != MBB.end()) DL = MI->getDebugLoc();
20010b57cec5SDimitry Andric 
20020b57cec5SDimitry Andric   LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);
20030b57cec5SDimitry Andric 
20040fca6ea1SDimitry Andric   for (MachineInstr *NewMI : NewMIs)
20050fca6ea1SDimitry Andric     MBB.insert(MI, NewMI);
20060b57cec5SDimitry Andric 
20070b57cec5SDimitry Andric   const MachineFrameInfo &MFI = MF.getFrameInfo();
20080b57cec5SDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
20090b57cec5SDimitry Andric       MachinePointerInfo::getFixedStack(MF, FrameIdx),
20100b57cec5SDimitry Andric       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
20115ffd83dbSDimitry Andric       MFI.getObjectAlign(FrameIdx));
20120b57cec5SDimitry Andric   NewMIs.back()->addMemOperand(MF, MMO);
20130b57cec5SDimitry Andric }
20140b57cec5SDimitry Andric 
20155ffd83dbSDimitry Andric void PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
20165ffd83dbSDimitry Andric                                         MachineBasicBlock::iterator MI,
20175ffd83dbSDimitry Andric                                         Register DestReg, int FrameIdx,
20185ffd83dbSDimitry Andric                                         const TargetRegisterClass *RC,
2019bdd1243dSDimitry Andric                                         const TargetRegisterInfo *TRI,
2020bdd1243dSDimitry Andric                                         Register VReg) const {
20215ffd83dbSDimitry Andric   // We need to avoid a situation in which the value from a VRRC register is
20225ffd83dbSDimitry Andric   // spilled using an Altivec instruction and reloaded into a VSRC register
20235ffd83dbSDimitry Andric   // using a VSX instruction. The issue with this is that the VSX
20245ffd83dbSDimitry Andric   // load/store instructions swap the doublewords in the vector and the Altivec
20255ffd83dbSDimitry Andric   // ones don't. The register classes on the spill/reload may be different if
20265ffd83dbSDimitry Andric   // the register is defined using an Altivec instruction and is then used by a
20275ffd83dbSDimitry Andric   // VSX instruction.
20285ffd83dbSDimitry Andric   RC = updatedRC(RC);
20295ffd83dbSDimitry Andric 
20305ffd83dbSDimitry Andric   loadRegFromStackSlotNoUpd(MBB, MI, DestReg, FrameIdx, RC, TRI);
20315ffd83dbSDimitry Andric }
20325ffd83dbSDimitry Andric 
20330b57cec5SDimitry Andric bool PPCInstrInfo::
20340b57cec5SDimitry Andric reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
20350b57cec5SDimitry Andric   assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
20360b57cec5SDimitry Andric   if (Cond[1].getReg() == PPC::CTR8 || Cond[1].getReg() == PPC::CTR)
20370b57cec5SDimitry Andric     Cond[0].setImm(Cond[0].getImm() == 0 ? 1 : 0);
20380b57cec5SDimitry Andric   else
20390b57cec5SDimitry Andric     // Leave the CR# the same, but invert the condition.
20400b57cec5SDimitry Andric     Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm()));
20410b57cec5SDimitry Andric   return false;
20420b57cec5SDimitry Andric }
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric // For some instructions, it is legal to fold ZERO into the RA register field.
20455ffd83dbSDimitry Andric // This function performs that fold by replacing the operand with PPC::ZERO,
20465ffd83dbSDimitry Andric // it does not consider whether the load immediate zero is no longer in use.
20475ffd83dbSDimitry Andric bool PPCInstrInfo::onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
20485ffd83dbSDimitry Andric                                      Register Reg) const {
20490b57cec5SDimitry Andric   // A zero immediate should always be loaded with a single li.
20500b57cec5SDimitry Andric   unsigned DefOpc = DefMI.getOpcode();
20510b57cec5SDimitry Andric   if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
20520b57cec5SDimitry Andric     return false;
20530b57cec5SDimitry Andric   if (!DefMI.getOperand(1).isImm())
20540b57cec5SDimitry Andric     return false;
20550b57cec5SDimitry Andric   if (DefMI.getOperand(1).getImm() != 0)
20560b57cec5SDimitry Andric     return false;
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric   // Note that we cannot here invert the arguments of an isel in order to fold
20590b57cec5SDimitry Andric   // a ZERO into what is presented as the second argument. All we have here
20600b57cec5SDimitry Andric   // is the condition bit, and that might come from a CR-logical bit operation.
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   const MCInstrDesc &UseMCID = UseMI.getDesc();
20630b57cec5SDimitry Andric 
20640b57cec5SDimitry Andric   // Only fold into real machine instructions.
20650b57cec5SDimitry Andric   if (UseMCID.isPseudo())
20660b57cec5SDimitry Andric     return false;
20670b57cec5SDimitry Andric 
20685ffd83dbSDimitry Andric   // We need to find which of the User's operands is to be folded, that will be
20695ffd83dbSDimitry Andric   // the operand that matches the given register ID.
20700b57cec5SDimitry Andric   unsigned UseIdx;
20710b57cec5SDimitry Andric   for (UseIdx = 0; UseIdx < UseMI.getNumOperands(); ++UseIdx)
20720b57cec5SDimitry Andric     if (UseMI.getOperand(UseIdx).isReg() &&
20730b57cec5SDimitry Andric         UseMI.getOperand(UseIdx).getReg() == Reg)
20740b57cec5SDimitry Andric       break;
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric   assert(UseIdx < UseMI.getNumOperands() && "Cannot find Reg in UseMI");
20770b57cec5SDimitry Andric   assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");
20780b57cec5SDimitry Andric 
2079bdd1243dSDimitry Andric   const MCOperandInfo *UseInfo = &UseMCID.operands()[UseIdx];
20800b57cec5SDimitry Andric 
20810b57cec5SDimitry Andric   // We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0
20820b57cec5SDimitry Andric   // register (which might also be specified as a pointer class kind).
20830b57cec5SDimitry Andric   if (UseInfo->isLookupPtrRegClass()) {
20840b57cec5SDimitry Andric     if (UseInfo->RegClass /* Kind */ != 1)
20850b57cec5SDimitry Andric       return false;
20860b57cec5SDimitry Andric   } else {
20870b57cec5SDimitry Andric     if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID &&
20880b57cec5SDimitry Andric         UseInfo->RegClass != PPC::G8RC_NOX0RegClassID)
20890b57cec5SDimitry Andric       return false;
20900b57cec5SDimitry Andric   }
20910b57cec5SDimitry Andric 
20920b57cec5SDimitry Andric   // Make sure this is not tied to an output register (or otherwise
20930b57cec5SDimitry Andric   // constrained). This is true for ST?UX registers, for example, which
20940b57cec5SDimitry Andric   // are tied to their output registers.
20950b57cec5SDimitry Andric   if (UseInfo->Constraints != 0)
20960b57cec5SDimitry Andric     return false;
20970b57cec5SDimitry Andric 
20985ffd83dbSDimitry Andric   MCRegister ZeroReg;
20990b57cec5SDimitry Andric   if (UseInfo->isLookupPtrRegClass()) {
21000b57cec5SDimitry Andric     bool isPPC64 = Subtarget.isPPC64();
21010b57cec5SDimitry Andric     ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO;
21020b57cec5SDimitry Andric   } else {
21030b57cec5SDimitry Andric     ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ?
21040b57cec5SDimitry Andric               PPC::ZERO8 : PPC::ZERO;
21050b57cec5SDimitry Andric   }
21060b57cec5SDimitry Andric 
2107bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Folded immediate zero for: ");
2108bdd1243dSDimitry Andric   LLVM_DEBUG(UseMI.dump());
21090b57cec5SDimitry Andric   UseMI.getOperand(UseIdx).setReg(ZeroReg);
2110bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Into: ");
2111bdd1243dSDimitry Andric   LLVM_DEBUG(UseMI.dump());
21120b57cec5SDimitry Andric   return true;
21130b57cec5SDimitry Andric }
21140b57cec5SDimitry Andric 
21155ffd83dbSDimitry Andric // Folds zero into instructions which have a load immediate zero as an operand
21165ffd83dbSDimitry Andric // but also recognize zero as immediate zero. If the definition of the load
21175ffd83dbSDimitry Andric // has no more users it is deleted.
21180fca6ea1SDimitry Andric bool PPCInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
21195ffd83dbSDimitry Andric                                  Register Reg, MachineRegisterInfo *MRI) const {
21205ffd83dbSDimitry Andric   bool Changed = onlyFoldImmediate(UseMI, DefMI, Reg);
21215ffd83dbSDimitry Andric   if (MRI->use_nodbg_empty(Reg))
21225ffd83dbSDimitry Andric     DefMI.eraseFromParent();
21235ffd83dbSDimitry Andric   return Changed;
21245ffd83dbSDimitry Andric }
21255ffd83dbSDimitry Andric 
21260b57cec5SDimitry Andric static bool MBBDefinesCTR(MachineBasicBlock &MBB) {
21274824e7fdSDimitry Andric   for (MachineInstr &MI : MBB)
21280fca6ea1SDimitry Andric     if (MI.definesRegister(PPC::CTR, /*TRI=*/nullptr) ||
21290fca6ea1SDimitry Andric         MI.definesRegister(PPC::CTR8, /*TRI=*/nullptr))
21300b57cec5SDimitry Andric       return true;
21310b57cec5SDimitry Andric   return false;
21320b57cec5SDimitry Andric }
21330b57cec5SDimitry Andric 
21340b57cec5SDimitry Andric // We should make sure that, if we're going to predicate both sides of a
21350b57cec5SDimitry Andric // condition (a diamond), that both sides don't define the counter register. We
21360b57cec5SDimitry Andric // can predicate counter-decrement-based branches, but while that predicates
21370b57cec5SDimitry Andric // the branching, it does not predicate the counter decrement. If we tried to
21380b57cec5SDimitry Andric // merge the triangle into one predicated block, we'd decrement the counter
21390b57cec5SDimitry Andric // twice.
21400b57cec5SDimitry Andric bool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
21410b57cec5SDimitry Andric                      unsigned NumT, unsigned ExtraT,
21420b57cec5SDimitry Andric                      MachineBasicBlock &FMBB,
21430b57cec5SDimitry Andric                      unsigned NumF, unsigned ExtraF,
21440b57cec5SDimitry Andric                      BranchProbability Probability) const {
21450b57cec5SDimitry Andric   return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB));
21460b57cec5SDimitry Andric }
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric 
21490b57cec5SDimitry Andric bool PPCInstrInfo::isPredicated(const MachineInstr &MI) const {
21500b57cec5SDimitry Andric   // The predicated branches are identified by their type, not really by the
21510b57cec5SDimitry Andric   // explicit presence of a predicate. Furthermore, some of them can be
21520b57cec5SDimitry Andric   // predicated more than once. Because if conversion won't try to predicate
21530b57cec5SDimitry Andric   // any instruction which already claims to be predicated (by returning true
21540b57cec5SDimitry Andric   // here), always return false. In doing so, we let isPredicable() be the
21550b57cec5SDimitry Andric   // final word on whether not the instruction can be (further) predicated.
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric   return false;
21580b57cec5SDimitry Andric }
21590b57cec5SDimitry Andric 
2160e8d8bef9SDimitry Andric bool PPCInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
2161e8d8bef9SDimitry Andric                                         const MachineBasicBlock *MBB,
2162e8d8bef9SDimitry Andric                                         const MachineFunction &MF) const {
21637a6dacacSDimitry Andric   switch (MI.getOpcode()) {
21647a6dacacSDimitry Andric   default:
21657a6dacacSDimitry Andric     break;
2166e8d8bef9SDimitry Andric   // Set MFFS and MTFSF as scheduling boundary to avoid unexpected code motion
2167e8d8bef9SDimitry Andric   // across them, since some FP operations may change content of FPSCR.
2168e8d8bef9SDimitry Andric   // TODO: Model FPSCR in PPC instruction definitions and remove the workaround
21697a6dacacSDimitry Andric   case PPC::MFFS:
21707a6dacacSDimitry Andric   case PPC::MTFSF:
21717a6dacacSDimitry Andric   case PPC::FENCE:
2172e8d8bef9SDimitry Andric     return true;
21737a6dacacSDimitry Andric   }
2174e8d8bef9SDimitry Andric   return TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF);
2175e8d8bef9SDimitry Andric }
2176e8d8bef9SDimitry Andric 
21770b57cec5SDimitry Andric bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI,
21780b57cec5SDimitry Andric                                         ArrayRef<MachineOperand> Pred) const {
21790b57cec5SDimitry Andric   unsigned OpC = MI.getOpcode();
21800b57cec5SDimitry Andric   if (OpC == PPC::BLR || OpC == PPC::BLR8) {
21810b57cec5SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
21820b57cec5SDimitry Andric       bool isPPC64 = Subtarget.isPPC64();
21830b57cec5SDimitry Andric       MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
21840b57cec5SDimitry Andric                                       : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2185e8d8bef9SDimitry Andric       // Need add Def and Use for CTR implicit operand.
2186e8d8bef9SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
2187e8d8bef9SDimitry Andric           .addReg(Pred[1].getReg(), RegState::Implicit)
2188e8d8bef9SDimitry Andric           .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
21890b57cec5SDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
21900b57cec5SDimitry Andric       MI.setDesc(get(PPC::BCLR));
21910b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
21920b57cec5SDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
21930b57cec5SDimitry Andric       MI.setDesc(get(PPC::BCLRn));
21940b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
21950b57cec5SDimitry Andric     } else {
21960b57cec5SDimitry Andric       MI.setDesc(get(PPC::BCCLR));
21970b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
21980b57cec5SDimitry Andric           .addImm(Pred[0].getImm())
21990b57cec5SDimitry Andric           .add(Pred[1]);
22000b57cec5SDimitry Andric     }
22010b57cec5SDimitry Andric 
22020b57cec5SDimitry Andric     return true;
22030b57cec5SDimitry Andric   } else if (OpC == PPC::B) {
22040b57cec5SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
22050b57cec5SDimitry Andric       bool isPPC64 = Subtarget.isPPC64();
22060b57cec5SDimitry Andric       MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
22070b57cec5SDimitry Andric                                       : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2208e8d8bef9SDimitry Andric       // Need add Def and Use for CTR implicit operand.
2209e8d8bef9SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
2210e8d8bef9SDimitry Andric           .addReg(Pred[1].getReg(), RegState::Implicit)
2211e8d8bef9SDimitry Andric           .addReg(Pred[1].getReg(), RegState::ImplicitDefine);
22120b57cec5SDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
22130b57cec5SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
221481ad6265SDimitry Andric       MI.removeOperand(0);
22150b57cec5SDimitry Andric 
22160b57cec5SDimitry Andric       MI.setDesc(get(PPC::BC));
22170b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
22180b57cec5SDimitry Andric           .add(Pred[1])
22190b57cec5SDimitry Andric           .addMBB(MBB);
22200b57cec5SDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
22210b57cec5SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
222281ad6265SDimitry Andric       MI.removeOperand(0);
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric       MI.setDesc(get(PPC::BCn));
22250b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
22260b57cec5SDimitry Andric           .add(Pred[1])
22270b57cec5SDimitry Andric           .addMBB(MBB);
22280b57cec5SDimitry Andric     } else {
22290b57cec5SDimitry Andric       MachineBasicBlock *MBB = MI.getOperand(0).getMBB();
223081ad6265SDimitry Andric       MI.removeOperand(0);
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric       MI.setDesc(get(PPC::BCC));
22330b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
22340b57cec5SDimitry Andric           .addImm(Pred[0].getImm())
22350b57cec5SDimitry Andric           .add(Pred[1])
22360b57cec5SDimitry Andric           .addMBB(MBB);
22370b57cec5SDimitry Andric     }
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric     return true;
22400b57cec5SDimitry Andric   } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2241349cc55cSDimitry Andric              OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2242349cc55cSDimitry Andric              OpC == PPC::BCTRL8_RM) {
22430b57cec5SDimitry Andric     if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)
22440b57cec5SDimitry Andric       llvm_unreachable("Cannot predicate bctr[l] on the ctr register");
22450b57cec5SDimitry Andric 
2246349cc55cSDimitry Andric     bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2247349cc55cSDimitry Andric                  OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
22480b57cec5SDimitry Andric     bool isPPC64 = Subtarget.isPPC64();
22490b57cec5SDimitry Andric 
22500b57cec5SDimitry Andric     if (Pred[0].getImm() == PPC::PRED_BIT_SET) {
22510b57cec5SDimitry Andric       MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
22520b57cec5SDimitry Andric                              : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
22530b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
22540b57cec5SDimitry Andric     } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) {
22550b57cec5SDimitry Andric       MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
22560b57cec5SDimitry Andric                              : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
22570b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]);
2258e8d8bef9SDimitry Andric     } else {
22590b57cec5SDimitry Andric       MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
22600b57cec5SDimitry Andric                              : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
22610b57cec5SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
22620b57cec5SDimitry Andric           .addImm(Pred[0].getImm())
22630b57cec5SDimitry Andric           .add(Pred[1]);
2264e8d8bef9SDimitry Andric     }
2265e8d8bef9SDimitry Andric 
2266e8d8bef9SDimitry Andric     // Need add Def and Use for LR implicit operand.
2267e8d8bef9SDimitry Andric     if (setLR)
2268e8d8bef9SDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
2269e8d8bef9SDimitry Andric           .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::Implicit)
2270e8d8bef9SDimitry Andric           .addReg(isPPC64 ? PPC::LR8 : PPC::LR, RegState::ImplicitDefine);
2271349cc55cSDimitry Andric     if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2272349cc55cSDimitry Andric       MachineInstrBuilder(*MI.getParent()->getParent(), MI)
2273349cc55cSDimitry Andric           .addReg(PPC::RM, RegState::ImplicitDefine);
2274e8d8bef9SDimitry Andric 
22750b57cec5SDimitry Andric     return true;
22760b57cec5SDimitry Andric   }
22770b57cec5SDimitry Andric 
22780b57cec5SDimitry Andric   return false;
22790b57cec5SDimitry Andric }
22800b57cec5SDimitry Andric 
22810b57cec5SDimitry Andric bool PPCInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
22820b57cec5SDimitry Andric                                      ArrayRef<MachineOperand> Pred2) const {
22830b57cec5SDimitry Andric   assert(Pred1.size() == 2 && "Invalid PPC first predicate");
22840b57cec5SDimitry Andric   assert(Pred2.size() == 2 && "Invalid PPC second predicate");
22850b57cec5SDimitry Andric 
22860b57cec5SDimitry Andric   if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)
22870b57cec5SDimitry Andric     return false;
22880b57cec5SDimitry Andric   if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)
22890b57cec5SDimitry Andric     return false;
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric   // P1 can only subsume P2 if they test the same condition register.
22920b57cec5SDimitry Andric   if (Pred1[1].getReg() != Pred2[1].getReg())
22930b57cec5SDimitry Andric     return false;
22940b57cec5SDimitry Andric 
22950b57cec5SDimitry Andric   PPC::Predicate P1 = (PPC::Predicate) Pred1[0].getImm();
22960b57cec5SDimitry Andric   PPC::Predicate P2 = (PPC::Predicate) Pred2[0].getImm();
22970b57cec5SDimitry Andric 
22980b57cec5SDimitry Andric   if (P1 == P2)
22990b57cec5SDimitry Andric     return true;
23000b57cec5SDimitry Andric 
23010b57cec5SDimitry Andric   // Does P1 subsume P2, e.g. GE subsumes GT.
23020b57cec5SDimitry Andric   if (P1 == PPC::PRED_LE &&
23030b57cec5SDimitry Andric       (P2 == PPC::PRED_LT || P2 == PPC::PRED_EQ))
23040b57cec5SDimitry Andric     return true;
23050b57cec5SDimitry Andric   if (P1 == PPC::PRED_GE &&
23060b57cec5SDimitry Andric       (P2 == PPC::PRED_GT || P2 == PPC::PRED_EQ))
23070b57cec5SDimitry Andric     return true;
23080b57cec5SDimitry Andric 
23090b57cec5SDimitry Andric   return false;
23100b57cec5SDimitry Andric }
23110b57cec5SDimitry Andric 
2312e8d8bef9SDimitry Andric bool PPCInstrInfo::ClobbersPredicate(MachineInstr &MI,
2313e8d8bef9SDimitry Andric                                      std::vector<MachineOperand> &Pred,
2314e8d8bef9SDimitry Andric                                      bool SkipDead) const {
23150b57cec5SDimitry Andric   // Note: At the present time, the contents of Pred from this function is
23160b57cec5SDimitry Andric   // unused by IfConversion. This implementation follows ARM by pushing the
23170b57cec5SDimitry Andric   // CR-defining operand. Because the 'DZ' and 'DNZ' count as types of
23180b57cec5SDimitry Andric   // predicate, instructions defining CTR or CTR8 are also included as
23190b57cec5SDimitry Andric   // predicate-defining instructions.
23200b57cec5SDimitry Andric 
23210b57cec5SDimitry Andric   const TargetRegisterClass *RCs[] =
23220b57cec5SDimitry Andric     { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
23230b57cec5SDimitry Andric       &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
23240b57cec5SDimitry Andric 
23250b57cec5SDimitry Andric   bool Found = false;
23264824e7fdSDimitry Andric   for (const MachineOperand &MO : MI.operands()) {
2327bdd1243dSDimitry Andric     for (unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
23280b57cec5SDimitry Andric       const TargetRegisterClass *RC = RCs[c];
23290b57cec5SDimitry Andric       if (MO.isReg()) {
23300b57cec5SDimitry Andric         if (MO.isDef() && RC->contains(MO.getReg())) {
23310b57cec5SDimitry Andric           Pred.push_back(MO);
23320b57cec5SDimitry Andric           Found = true;
23330b57cec5SDimitry Andric         }
23340b57cec5SDimitry Andric       } else if (MO.isRegMask()) {
233504eeddc0SDimitry Andric         for (MCPhysReg R : *RC)
233604eeddc0SDimitry Andric           if (MO.clobbersPhysReg(R)) {
23370b57cec5SDimitry Andric             Pred.push_back(MO);
23380b57cec5SDimitry Andric             Found = true;
23390b57cec5SDimitry Andric           }
23400b57cec5SDimitry Andric       }
23410b57cec5SDimitry Andric     }
23420b57cec5SDimitry Andric   }
23430b57cec5SDimitry Andric 
23440b57cec5SDimitry Andric   return Found;
23450b57cec5SDimitry Andric }
23460b57cec5SDimitry Andric 
23475ffd83dbSDimitry Andric bool PPCInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
2348349cc55cSDimitry Andric                                   Register &SrcReg2, int64_t &Mask,
2349349cc55cSDimitry Andric                                   int64_t &Value) const {
23500b57cec5SDimitry Andric   unsigned Opc = MI.getOpcode();
23510b57cec5SDimitry Andric 
23520b57cec5SDimitry Andric   switch (Opc) {
23530b57cec5SDimitry Andric   default: return false;
23540b57cec5SDimitry Andric   case PPC::CMPWI:
23550b57cec5SDimitry Andric   case PPC::CMPLWI:
23560b57cec5SDimitry Andric   case PPC::CMPDI:
23570b57cec5SDimitry Andric   case PPC::CMPLDI:
23580b57cec5SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
23590b57cec5SDimitry Andric     SrcReg2 = 0;
23600b57cec5SDimitry Andric     Value = MI.getOperand(2).getImm();
23610b57cec5SDimitry Andric     Mask = 0xFFFF;
23620b57cec5SDimitry Andric     return true;
23630b57cec5SDimitry Andric   case PPC::CMPW:
23640b57cec5SDimitry Andric   case PPC::CMPLW:
23650b57cec5SDimitry Andric   case PPC::CMPD:
23660b57cec5SDimitry Andric   case PPC::CMPLD:
23670b57cec5SDimitry Andric   case PPC::FCMPUS:
23680b57cec5SDimitry Andric   case PPC::FCMPUD:
23690b57cec5SDimitry Andric     SrcReg = MI.getOperand(1).getReg();
23700b57cec5SDimitry Andric     SrcReg2 = MI.getOperand(2).getReg();
23710b57cec5SDimitry Andric     Value = 0;
23720b57cec5SDimitry Andric     Mask = 0;
23730b57cec5SDimitry Andric     return true;
23740b57cec5SDimitry Andric   }
23750b57cec5SDimitry Andric }
23760b57cec5SDimitry Andric 
23775ffd83dbSDimitry Andric bool PPCInstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
2378349cc55cSDimitry Andric                                         Register SrcReg2, int64_t Mask,
2379349cc55cSDimitry Andric                                         int64_t Value,
23800b57cec5SDimitry Andric                                         const MachineRegisterInfo *MRI) const {
23810b57cec5SDimitry Andric   if (DisableCmpOpt)
23820b57cec5SDimitry Andric     return false;
23830b57cec5SDimitry Andric 
23840b57cec5SDimitry Andric   int OpC = CmpInstr.getOpcode();
23858bcb0991SDimitry Andric   Register CRReg = CmpInstr.getOperand(0).getReg();
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric   // FP record forms set CR1 based on the exception status bits, not a
23880b57cec5SDimitry Andric   // comparison with zero.
23890b57cec5SDimitry Andric   if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
23900b57cec5SDimitry Andric     return false;
23910b57cec5SDimitry Andric 
23920b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
23930b57cec5SDimitry Andric   // The record forms set the condition register based on a signed comparison
23940b57cec5SDimitry Andric   // with zero (so says the ISA manual). This is not as straightforward as it
23950b57cec5SDimitry Andric   // seems, however, because this is always a 64-bit comparison on PPC64, even
23960b57cec5SDimitry Andric   // for instructions that are 32-bit in nature (like slw for example).
23970b57cec5SDimitry Andric   // So, on PPC32, for unsigned comparisons, we can use the record forms only
23980b57cec5SDimitry Andric   // for equality checks (as those don't depend on the sign). On PPC64,
23990b57cec5SDimitry Andric   // we are restricted to equality for unsigned 64-bit comparisons and for
24000b57cec5SDimitry Andric   // signed 32-bit comparisons the applicability is more restricted.
24010b57cec5SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
24020b57cec5SDimitry Andric   bool is32BitSignedCompare   = OpC ==  PPC::CMPWI || OpC == PPC::CMPW;
24030b57cec5SDimitry Andric   bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
24040b57cec5SDimitry Andric   bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric   // Look through copies unless that gets us to a physical register.
24075ffd83dbSDimitry Andric   Register ActualSrc = TRI->lookThruCopyLike(SrcReg, MRI);
24085ffd83dbSDimitry Andric   if (ActualSrc.isVirtual())
24090b57cec5SDimitry Andric     SrcReg = ActualSrc;
24100b57cec5SDimitry Andric 
24110b57cec5SDimitry Andric   // Get the unique definition of SrcReg.
24120b57cec5SDimitry Andric   MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
24130b57cec5SDimitry Andric   if (!MI) return false;
24140b57cec5SDimitry Andric 
24150b57cec5SDimitry Andric   bool equalityOnly = false;
24160b57cec5SDimitry Andric   bool noSub = false;
24170b57cec5SDimitry Andric   if (isPPC64) {
24180b57cec5SDimitry Andric     if (is32BitSignedCompare) {
2419bdd1243dSDimitry Andric       // We can perform this optimization only if SrcReg is sign-extending.
2420bdd1243dSDimitry Andric       if (isSignExtended(SrcReg, MRI))
24210b57cec5SDimitry Andric         noSub = true;
24220b57cec5SDimitry Andric       else
24230b57cec5SDimitry Andric         return false;
24240b57cec5SDimitry Andric     } else if (is32BitUnsignedCompare) {
2425bdd1243dSDimitry Andric       // We can perform this optimization, equality only, if SrcReg is
24260b57cec5SDimitry Andric       // zero-extending.
2427bdd1243dSDimitry Andric       if (isZeroExtended(SrcReg, MRI)) {
24280b57cec5SDimitry Andric         noSub = true;
24290b57cec5SDimitry Andric         equalityOnly = true;
24300b57cec5SDimitry Andric       } else
24310b57cec5SDimitry Andric         return false;
24320b57cec5SDimitry Andric     } else
24330b57cec5SDimitry Andric       equalityOnly = is64BitUnsignedCompare;
24340b57cec5SDimitry Andric   } else
24350b57cec5SDimitry Andric     equalityOnly = is32BitUnsignedCompare;
24360b57cec5SDimitry Andric 
24370b57cec5SDimitry Andric   if (equalityOnly) {
24380b57cec5SDimitry Andric     // We need to check the uses of the condition register in order to reject
24390b57cec5SDimitry Andric     // non-equality comparisons.
24400b57cec5SDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
24410b57cec5SDimitry Andric          I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
24420b57cec5SDimitry Andric          I != IE; ++I) {
24430b57cec5SDimitry Andric       MachineInstr *UseMI = &*I;
24440b57cec5SDimitry Andric       if (UseMI->getOpcode() == PPC::BCC) {
24450b57cec5SDimitry Andric         PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
24460b57cec5SDimitry Andric         unsigned PredCond = PPC::getPredicateCondition(Pred);
24470b57cec5SDimitry Andric         // We ignore hint bits when checking for non-equality comparisons.
24480b57cec5SDimitry Andric         if (PredCond != PPC::PRED_EQ && PredCond != PPC::PRED_NE)
24490b57cec5SDimitry Andric           return false;
24500b57cec5SDimitry Andric       } else if (UseMI->getOpcode() == PPC::ISEL ||
24510b57cec5SDimitry Andric                  UseMI->getOpcode() == PPC::ISEL8) {
24520b57cec5SDimitry Andric         unsigned SubIdx = UseMI->getOperand(3).getSubReg();
24530b57cec5SDimitry Andric         if (SubIdx != PPC::sub_eq)
24540b57cec5SDimitry Andric           return false;
24550b57cec5SDimitry Andric       } else
24560b57cec5SDimitry Andric         return false;
24570b57cec5SDimitry Andric     }
24580b57cec5SDimitry Andric   }
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric   MachineBasicBlock::iterator I = CmpInstr;
24610b57cec5SDimitry Andric 
24620b57cec5SDimitry Andric   // Scan forward to find the first use of the compare.
24630b57cec5SDimitry Andric   for (MachineBasicBlock::iterator EL = CmpInstr.getParent()->end(); I != EL;
24640b57cec5SDimitry Andric        ++I) {
24650b57cec5SDimitry Andric     bool FoundUse = false;
24660b57cec5SDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
24670b57cec5SDimitry Andric          J = MRI->use_instr_begin(CRReg), JE = MRI->use_instr_end();
24680b57cec5SDimitry Andric          J != JE; ++J)
24690b57cec5SDimitry Andric       if (&*J == &*I) {
24700b57cec5SDimitry Andric         FoundUse = true;
24710b57cec5SDimitry Andric         break;
24720b57cec5SDimitry Andric       }
24730b57cec5SDimitry Andric 
24740b57cec5SDimitry Andric     if (FoundUse)
24750b57cec5SDimitry Andric       break;
24760b57cec5SDimitry Andric   }
24770b57cec5SDimitry Andric 
24780b57cec5SDimitry Andric   SmallVector<std::pair<MachineOperand*, PPC::Predicate>, 4> PredsToUpdate;
24790b57cec5SDimitry Andric   SmallVector<std::pair<MachineOperand*, unsigned>, 4> SubRegsToUpdate;
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   // There are two possible candidates which can be changed to set CR[01].
24820b57cec5SDimitry Andric   // One is MI, the other is a SUB instruction.
24830b57cec5SDimitry Andric   // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
24840b57cec5SDimitry Andric   MachineInstr *Sub = nullptr;
24850b57cec5SDimitry Andric   if (SrcReg2 != 0)
24860b57cec5SDimitry Andric     // MI is not a candidate for CMPrr.
24870b57cec5SDimitry Andric     MI = nullptr;
24880b57cec5SDimitry Andric   // FIXME: Conservatively refuse to convert an instruction which isn't in the
24890b57cec5SDimitry Andric   // same BB as the comparison. This is to allow the check below to avoid calls
24900b57cec5SDimitry Andric   // (and other explicit clobbers); instead we should really check for these
24910b57cec5SDimitry Andric   // more explicitly (in at least a few predecessors).
24920b57cec5SDimitry Andric   else if (MI->getParent() != CmpInstr.getParent())
24930b57cec5SDimitry Andric     return false;
24940b57cec5SDimitry Andric   else if (Value != 0) {
24950b57cec5SDimitry Andric     // The record-form instructions set CR bit based on signed comparison
24960b57cec5SDimitry Andric     // against 0. We try to convert a compare against 1 or -1 into a compare
24970b57cec5SDimitry Andric     // against 0 to exploit record-form instructions. For example, we change
24980b57cec5SDimitry Andric     // the condition "greater than -1" into "greater than or equal to 0"
24990b57cec5SDimitry Andric     // and "less than 1" into "less than or equal to 0".
25000b57cec5SDimitry Andric 
25010b57cec5SDimitry Andric     // Since we optimize comparison based on a specific branch condition,
25020b57cec5SDimitry Andric     // we don't optimize if condition code is used by more than once.
25030b57cec5SDimitry Andric     if (equalityOnly || !MRI->hasOneUse(CRReg))
25040b57cec5SDimitry Andric       return false;
25050b57cec5SDimitry Andric 
25060b57cec5SDimitry Andric     MachineInstr *UseMI = &*MRI->use_instr_begin(CRReg);
25070b57cec5SDimitry Andric     if (UseMI->getOpcode() != PPC::BCC)
25080b57cec5SDimitry Andric       return false;
25090b57cec5SDimitry Andric 
25100b57cec5SDimitry Andric     PPC::Predicate Pred = (PPC::Predicate)UseMI->getOperand(0).getImm();
25110b57cec5SDimitry Andric     unsigned PredCond = PPC::getPredicateCondition(Pred);
25120b57cec5SDimitry Andric     unsigned PredHint = PPC::getPredicateHint(Pred);
25130b57cec5SDimitry Andric     int16_t Immed = (int16_t)Value;
25140b57cec5SDimitry Andric 
25150b57cec5SDimitry Andric     // When modifying the condition in the predicate, we propagate hint bits
25160b57cec5SDimitry Andric     // from the original predicate to the new one.
25170b57cec5SDimitry Andric     if (Immed == -1 && PredCond == PPC::PRED_GT)
25180b57cec5SDimitry Andric       // We convert "greater than -1" into "greater than or equal to 0",
25190b57cec5SDimitry Andric       // since we are assuming signed comparison by !equalityOnly
25200b57cec5SDimitry Andric       Pred = PPC::getPredicate(PPC::PRED_GE, PredHint);
25210b57cec5SDimitry Andric     else if (Immed == -1 && PredCond == PPC::PRED_LE)
25220b57cec5SDimitry Andric       // We convert "less than or equal to -1" into "less than 0".
25230b57cec5SDimitry Andric       Pred = PPC::getPredicate(PPC::PRED_LT, PredHint);
25240b57cec5SDimitry Andric     else if (Immed == 1 && PredCond == PPC::PRED_LT)
25250b57cec5SDimitry Andric       // We convert "less than 1" into "less than or equal to 0".
25260b57cec5SDimitry Andric       Pred = PPC::getPredicate(PPC::PRED_LE, PredHint);
25270b57cec5SDimitry Andric     else if (Immed == 1 && PredCond == PPC::PRED_GE)
25280b57cec5SDimitry Andric       // We convert "greater than or equal to 1" into "greater than 0".
25290b57cec5SDimitry Andric       Pred = PPC::getPredicate(PPC::PRED_GT, PredHint);
25300b57cec5SDimitry Andric     else
25310b57cec5SDimitry Andric       return false;
25320b57cec5SDimitry Andric 
2533bdd1243dSDimitry Andric     // Convert the comparison and its user to a compare against zero with the
2534bdd1243dSDimitry Andric     // appropriate predicate on the branch. Zero comparison might provide
2535bdd1243dSDimitry Andric     // optimization opportunities post-RA (see optimization in
2536bdd1243dSDimitry Andric     // PPCPreEmitPeephole.cpp).
2537bdd1243dSDimitry Andric     UseMI->getOperand(0).setImm(Pred);
2538bdd1243dSDimitry Andric     CmpInstr.getOperand(2).setImm(0);
25390b57cec5SDimitry Andric   }
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric   // Search for Sub.
25420b57cec5SDimitry Andric   --I;
25430b57cec5SDimitry Andric 
25440b57cec5SDimitry Andric   // Get ready to iterate backward from CmpInstr.
25450b57cec5SDimitry Andric   MachineBasicBlock::iterator E = MI, B = CmpInstr.getParent()->begin();
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric   for (; I != E && !noSub; --I) {
25480b57cec5SDimitry Andric     const MachineInstr &Instr = *I;
25490b57cec5SDimitry Andric     unsigned IOpC = Instr.getOpcode();
25500b57cec5SDimitry Andric 
25510b57cec5SDimitry Andric     if (&*I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, TRI) ||
25520b57cec5SDimitry Andric                              Instr.readsRegister(PPC::CR0, TRI)))
25530b57cec5SDimitry Andric       // This instruction modifies or uses the record condition register after
25540b57cec5SDimitry Andric       // the one we want to change. While we could do this transformation, it
25550b57cec5SDimitry Andric       // would likely not be profitable. This transformation removes one
25560b57cec5SDimitry Andric       // instruction, and so even forcing RA to generate one move probably
25570b57cec5SDimitry Andric       // makes it unprofitable.
25580b57cec5SDimitry Andric       return false;
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric     // Check whether CmpInstr can be made redundant by the current instruction.
25610b57cec5SDimitry Andric     if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
25620b57cec5SDimitry Andric          OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
25630b57cec5SDimitry Andric         (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
25640b57cec5SDimitry Andric         ((Instr.getOperand(1).getReg() == SrcReg &&
25650b57cec5SDimitry Andric           Instr.getOperand(2).getReg() == SrcReg2) ||
25660b57cec5SDimitry Andric         (Instr.getOperand(1).getReg() == SrcReg2 &&
25670b57cec5SDimitry Andric          Instr.getOperand(2).getReg() == SrcReg))) {
25680b57cec5SDimitry Andric       Sub = &*I;
25690b57cec5SDimitry Andric       break;
25700b57cec5SDimitry Andric     }
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric     if (I == B)
25730b57cec5SDimitry Andric       // The 'and' is below the comparison instruction.
25740b57cec5SDimitry Andric       return false;
25750b57cec5SDimitry Andric   }
25760b57cec5SDimitry Andric 
25770b57cec5SDimitry Andric   // Return false if no candidates exist.
25780b57cec5SDimitry Andric   if (!MI && !Sub)
25790b57cec5SDimitry Andric     return false;
25800b57cec5SDimitry Andric 
25810b57cec5SDimitry Andric   // The single candidate is called MI.
25820b57cec5SDimitry Andric   if (!MI) MI = Sub;
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric   int NewOpC = -1;
25850b57cec5SDimitry Andric   int MIOpC = MI->getOpcode();
2586480093f4SDimitry Andric   if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2587480093f4SDimitry Andric       MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
25880b57cec5SDimitry Andric     NewOpC = MIOpC;
25890b57cec5SDimitry Andric   else {
25900b57cec5SDimitry Andric     NewOpC = PPC::getRecordFormOpcode(MIOpC);
25910b57cec5SDimitry Andric     if (NewOpC == -1 && PPC::getNonRecordFormOpcode(MIOpC) != -1)
25920b57cec5SDimitry Andric       NewOpC = MIOpC;
25930b57cec5SDimitry Andric   }
25940b57cec5SDimitry Andric 
25950b57cec5SDimitry Andric   // FIXME: On the non-embedded POWER architectures, only some of the record
25960b57cec5SDimitry Andric   // forms are fast, and we should use only the fast ones.
25970b57cec5SDimitry Andric 
25980b57cec5SDimitry Andric   // The defining instruction has a record form (or is already a record
25990b57cec5SDimitry Andric   // form). It is possible, however, that we'll need to reverse the condition
26000b57cec5SDimitry Andric   // code of the users.
26010b57cec5SDimitry Andric   if (NewOpC == -1)
26020b57cec5SDimitry Andric     return false;
26030b57cec5SDimitry Andric 
2604e8d8bef9SDimitry Andric   // This transformation should not be performed if `nsw` is missing and is not
2605e8d8bef9SDimitry Andric   // `equalityOnly` comparison. Since if there is overflow, sub_lt, sub_gt in
2606e8d8bef9SDimitry Andric   // CRReg do not reflect correct order. If `equalityOnly` is true, sub_eq in
2607e8d8bef9SDimitry Andric   // CRReg can reflect if compared values are equal, this optz is still valid.
2608e8d8bef9SDimitry Andric   if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2609e8d8bef9SDimitry Andric       Sub && !Sub->getFlag(MachineInstr::NoSWrap))
2610e8d8bef9SDimitry Andric     return false;
2611e8d8bef9SDimitry Andric 
26120b57cec5SDimitry Andric   // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP
26130b57cec5SDimitry Andric   // needs to be updated to be based on SUB.  Push the condition code
26140b57cec5SDimitry Andric   // operands to OperandsToUpdate.  If it is safe to remove CmpInstr, the
26150b57cec5SDimitry Andric   // condition code of these operands will be modified.
26160b57cec5SDimitry Andric   // Here, Value == 0 means we haven't converted comparison against 1 or -1 to
26170b57cec5SDimitry Andric   // comparison against 0, which may modify predicate.
26180b57cec5SDimitry Andric   bool ShouldSwap = false;
26190b57cec5SDimitry Andric   if (Sub && Value == 0) {
26200b57cec5SDimitry Andric     ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
26210b57cec5SDimitry Andric       Sub->getOperand(2).getReg() == SrcReg;
26220b57cec5SDimitry Andric 
26230b57cec5SDimitry Andric     // The operands to subf are the opposite of sub, so only in the fixed-point
26240b57cec5SDimitry Andric     // case, invert the order.
26250b57cec5SDimitry Andric     ShouldSwap = !ShouldSwap;
26260b57cec5SDimitry Andric   }
26270b57cec5SDimitry Andric 
26280b57cec5SDimitry Andric   if (ShouldSwap)
26290b57cec5SDimitry Andric     for (MachineRegisterInfo::use_instr_iterator
26300b57cec5SDimitry Andric          I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();
26310b57cec5SDimitry Andric          I != IE; ++I) {
26320b57cec5SDimitry Andric       MachineInstr *UseMI = &*I;
26330b57cec5SDimitry Andric       if (UseMI->getOpcode() == PPC::BCC) {
26340b57cec5SDimitry Andric         PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm();
26350b57cec5SDimitry Andric         unsigned PredCond = PPC::getPredicateCondition(Pred);
26360b57cec5SDimitry Andric         assert((!equalityOnly ||
26370b57cec5SDimitry Andric                 PredCond == PPC::PRED_EQ || PredCond == PPC::PRED_NE) &&
26380b57cec5SDimitry Andric                "Invalid predicate for equality-only optimization");
26390b57cec5SDimitry Andric         (void)PredCond; // To suppress warning in release build.
26400b57cec5SDimitry Andric         PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),
26410b57cec5SDimitry Andric                                 PPC::getSwappedPredicate(Pred)));
26420b57cec5SDimitry Andric       } else if (UseMI->getOpcode() == PPC::ISEL ||
26430b57cec5SDimitry Andric                  UseMI->getOpcode() == PPC::ISEL8) {
26440b57cec5SDimitry Andric         unsigned NewSubReg = UseMI->getOperand(3).getSubReg();
26450b57cec5SDimitry Andric         assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
26460b57cec5SDimitry Andric                "Invalid CR bit for equality-only optimization");
26470b57cec5SDimitry Andric 
26480b57cec5SDimitry Andric         if (NewSubReg == PPC::sub_lt)
26490b57cec5SDimitry Andric           NewSubReg = PPC::sub_gt;
26500b57cec5SDimitry Andric         else if (NewSubReg == PPC::sub_gt)
26510b57cec5SDimitry Andric           NewSubReg = PPC::sub_lt;
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric         SubRegsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(3)),
26540b57cec5SDimitry Andric                                                  NewSubReg));
26550b57cec5SDimitry Andric       } else // We need to abort on a user we don't understand.
26560b57cec5SDimitry Andric         return false;
26570b57cec5SDimitry Andric     }
26580b57cec5SDimitry Andric   assert(!(Value != 0 && ShouldSwap) &&
26590b57cec5SDimitry Andric          "Non-zero immediate support and ShouldSwap"
26600b57cec5SDimitry Andric          "may conflict in updating predicate");
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric   // Create a new virtual register to hold the value of the CR set by the
26630b57cec5SDimitry Andric   // record-form instruction. If the instruction was not previously in
26640b57cec5SDimitry Andric   // record form, then set the kill flag on the CR.
26650b57cec5SDimitry Andric   CmpInstr.eraseFromParent();
26660b57cec5SDimitry Andric 
26670b57cec5SDimitry Andric   MachineBasicBlock::iterator MII = MI;
26680b57cec5SDimitry Andric   BuildMI(*MI->getParent(), std::next(MII), MI->getDebugLoc(),
26690b57cec5SDimitry Andric           get(TargetOpcode::COPY), CRReg)
26700b57cec5SDimitry Andric     .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0);
26710b57cec5SDimitry Andric 
26720b57cec5SDimitry Andric   // Even if CR0 register were dead before, it is alive now since the
26730b57cec5SDimitry Andric   // instruction we just built uses it.
26740b57cec5SDimitry Andric   MI->clearRegisterDeads(PPC::CR0);
26750b57cec5SDimitry Andric 
26760b57cec5SDimitry Andric   if (MIOpC != NewOpC) {
26770b57cec5SDimitry Andric     // We need to be careful here: we're replacing one instruction with
26780b57cec5SDimitry Andric     // another, and we need to make sure that we get all of the right
26790b57cec5SDimitry Andric     // implicit uses and defs. On the other hand, the caller may be holding
26800b57cec5SDimitry Andric     // an iterator to this instruction, and so we can't delete it (this is
26810b57cec5SDimitry Andric     // specifically the case if this is the instruction directly after the
26820b57cec5SDimitry Andric     // compare).
26830b57cec5SDimitry Andric 
26840b57cec5SDimitry Andric     // Rotates are expensive instructions. If we're emitting a record-form
26850b57cec5SDimitry Andric     // rotate that can just be an andi/andis, we should just emit that.
26860b57cec5SDimitry Andric     if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
26878bcb0991SDimitry Andric       Register GPRRes = MI->getOperand(0).getReg();
26880b57cec5SDimitry Andric       int64_t SH = MI->getOperand(2).getImm();
26890b57cec5SDimitry Andric       int64_t MB = MI->getOperand(3).getImm();
26900b57cec5SDimitry Andric       int64_t ME = MI->getOperand(4).getImm();
26910b57cec5SDimitry Andric       // We can only do this if both the start and end of the mask are in the
26920b57cec5SDimitry Andric       // same halfword.
26930b57cec5SDimitry Andric       bool MBInLoHWord = MB >= 16;
26940b57cec5SDimitry Andric       bool MEInLoHWord = ME >= 16;
26950b57cec5SDimitry Andric       uint64_t Mask = ~0LLU;
26960b57cec5SDimitry Andric 
26970b57cec5SDimitry Andric       if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
26980b57cec5SDimitry Andric         Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
26990b57cec5SDimitry Andric         // The mask value needs to shift right 16 if we're emitting andis.
27000b57cec5SDimitry Andric         Mask >>= MBInLoHWord ? 0 : 16;
2701480093f4SDimitry Andric         NewOpC = MIOpC == PPC::RLWINM
2702480093f4SDimitry Andric                      ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2703480093f4SDimitry Andric                      : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
27040b57cec5SDimitry Andric       } else if (MRI->use_empty(GPRRes) && (ME == 31) &&
27050b57cec5SDimitry Andric                  (ME - MB + 1 == SH) && (MB >= 16)) {
27060b57cec5SDimitry Andric         // If we are rotating by the exact number of bits as are in the mask
27070b57cec5SDimitry Andric         // and the mask is in the least significant bits of the register,
27080b57cec5SDimitry Andric         // that's just an andis. (as long as the GPR result has no uses).
27090b57cec5SDimitry Andric         Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
27100b57cec5SDimitry Andric         Mask >>= 16;
2711480093f4SDimitry Andric         NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
27120b57cec5SDimitry Andric       }
27130b57cec5SDimitry Andric       // If we've set the mask, we can transform.
27140b57cec5SDimitry Andric       if (Mask != ~0LLU) {
271581ad6265SDimitry Andric         MI->removeOperand(4);
271681ad6265SDimitry Andric         MI->removeOperand(3);
27170b57cec5SDimitry Andric         MI->getOperand(2).setImm(Mask);
27180b57cec5SDimitry Andric         NumRcRotatesConvertedToRcAnd++;
27190b57cec5SDimitry Andric       }
27200b57cec5SDimitry Andric     } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {
27210b57cec5SDimitry Andric       int64_t MB = MI->getOperand(3).getImm();
27220b57cec5SDimitry Andric       if (MB >= 48) {
27230b57cec5SDimitry Andric         uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2724480093f4SDimitry Andric         NewOpC = PPC::ANDI8_rec;
272581ad6265SDimitry Andric         MI->removeOperand(3);
27260b57cec5SDimitry Andric         MI->getOperand(2).setImm(Mask);
27270b57cec5SDimitry Andric         NumRcRotatesConvertedToRcAnd++;
27280b57cec5SDimitry Andric       }
27290b57cec5SDimitry Andric     }
27300b57cec5SDimitry Andric 
27310b57cec5SDimitry Andric     const MCInstrDesc &NewDesc = get(NewOpC);
27320b57cec5SDimitry Andric     MI->setDesc(NewDesc);
27330b57cec5SDimitry Andric 
2734bdd1243dSDimitry Andric     for (MCPhysReg ImpDef : NewDesc.implicit_defs()) {
27350fca6ea1SDimitry Andric       if (!MI->definesRegister(ImpDef, /*TRI=*/nullptr)) {
27360b57cec5SDimitry Andric         MI->addOperand(*MI->getParent()->getParent(),
2737bdd1243dSDimitry Andric                        MachineOperand::CreateReg(ImpDef, true, true));
2738bdd1243dSDimitry Andric       }
2739bdd1243dSDimitry Andric     }
2740bdd1243dSDimitry Andric     for (MCPhysReg ImpUse : NewDesc.implicit_uses()) {
27410fca6ea1SDimitry Andric       if (!MI->readsRegister(ImpUse, /*TRI=*/nullptr)) {
27420b57cec5SDimitry Andric         MI->addOperand(*MI->getParent()->getParent(),
2743bdd1243dSDimitry Andric                        MachineOperand::CreateReg(ImpUse, false, true));
2744bdd1243dSDimitry Andric       }
2745bdd1243dSDimitry Andric     }
27460b57cec5SDimitry Andric   }
27470fca6ea1SDimitry Andric   assert(MI->definesRegister(PPC::CR0, /*TRI=*/nullptr) &&
27480b57cec5SDimitry Andric          "Record-form instruction does not define cr0?");
27490b57cec5SDimitry Andric 
27500b57cec5SDimitry Andric   // Modify the condition code of operands in OperandsToUpdate.
27510b57cec5SDimitry Andric   // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
27520b57cec5SDimitry Andric   // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
27530b57cec5SDimitry Andric   for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)
27540b57cec5SDimitry Andric     PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric   for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)
27570b57cec5SDimitry Andric     SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
27580b57cec5SDimitry Andric 
27590b57cec5SDimitry Andric   return true;
27600b57cec5SDimitry Andric }
27610b57cec5SDimitry Andric 
2762bdd1243dSDimitry Andric bool PPCInstrInfo::optimizeCmpPostRA(MachineInstr &CmpMI) const {
2763bdd1243dSDimitry Andric   MachineRegisterInfo *MRI = &CmpMI.getParent()->getParent()->getRegInfo();
2764bdd1243dSDimitry Andric   if (MRI->isSSA())
2765bdd1243dSDimitry Andric     return false;
2766bdd1243dSDimitry Andric 
2767bdd1243dSDimitry Andric   Register SrcReg, SrcReg2;
2768bdd1243dSDimitry Andric   int64_t CmpMask, CmpValue;
2769bdd1243dSDimitry Andric   if (!analyzeCompare(CmpMI, SrcReg, SrcReg2, CmpMask, CmpValue))
2770bdd1243dSDimitry Andric     return false;
2771bdd1243dSDimitry Andric 
2772bdd1243dSDimitry Andric   // Try to optimize the comparison against 0.
2773bdd1243dSDimitry Andric   if (CmpValue || !CmpMask || SrcReg2)
2774bdd1243dSDimitry Andric     return false;
2775bdd1243dSDimitry Andric 
2776bdd1243dSDimitry Andric   // The record forms set the condition register based on a signed comparison
2777bdd1243dSDimitry Andric   // with zero (see comments in optimizeCompareInstr). Since we can't do the
2778bdd1243dSDimitry Andric   // equality checks in post-RA, we are more restricted on a unsigned
2779bdd1243dSDimitry Andric   // comparison.
2780bdd1243dSDimitry Andric   unsigned Opc = CmpMI.getOpcode();
2781bdd1243dSDimitry Andric   if (Opc == PPC::CMPLWI || Opc == PPC::CMPLDI)
2782bdd1243dSDimitry Andric     return false;
2783bdd1243dSDimitry Andric 
2784bdd1243dSDimitry Andric   // The record forms are always based on a 64-bit comparison on PPC64
2785bdd1243dSDimitry Andric   // (similary, a 32-bit comparison on PPC32), while the CMPWI is a 32-bit
2786bdd1243dSDimitry Andric   // comparison. Since we can't do the equality checks in post-RA, we bail out
2787bdd1243dSDimitry Andric   // the case.
2788bdd1243dSDimitry Andric   if (Subtarget.isPPC64() && Opc == PPC::CMPWI)
2789bdd1243dSDimitry Andric     return false;
2790bdd1243dSDimitry Andric 
2791bdd1243dSDimitry Andric   // CmpMI can't be deleted if it has implicit def.
2792bdd1243dSDimitry Andric   if (CmpMI.hasImplicitDef())
2793bdd1243dSDimitry Andric     return false;
2794bdd1243dSDimitry Andric 
2795bdd1243dSDimitry Andric   bool SrcRegHasOtherUse = false;
2796bdd1243dSDimitry Andric   MachineInstr *SrcMI = getDefMIPostRA(SrcReg, CmpMI, SrcRegHasOtherUse);
27970fca6ea1SDimitry Andric   if (!SrcMI || !SrcMI->definesRegister(SrcReg, /*TRI=*/nullptr))
2798bdd1243dSDimitry Andric     return false;
2799bdd1243dSDimitry Andric 
2800bdd1243dSDimitry Andric   MachineOperand RegMO = CmpMI.getOperand(0);
2801bdd1243dSDimitry Andric   Register CRReg = RegMO.getReg();
2802bdd1243dSDimitry Andric   if (CRReg != PPC::CR0)
2803bdd1243dSDimitry Andric     return false;
2804bdd1243dSDimitry Andric 
2805bdd1243dSDimitry Andric   // Make sure there is no def/use of CRReg between SrcMI and CmpMI.
2806bdd1243dSDimitry Andric   bool SeenUseOfCRReg = false;
2807bdd1243dSDimitry Andric   bool IsCRRegKilled = false;
2808bdd1243dSDimitry Andric   if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI, false, IsCRRegKilled,
2809bdd1243dSDimitry Andric                                  SeenUseOfCRReg) ||
28100fca6ea1SDimitry Andric       SrcMI->definesRegister(CRReg, /*TRI=*/nullptr) || SeenUseOfCRReg)
2811bdd1243dSDimitry Andric     return false;
2812bdd1243dSDimitry Andric 
2813bdd1243dSDimitry Andric   int SrcMIOpc = SrcMI->getOpcode();
2814bdd1243dSDimitry Andric   int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2815bdd1243dSDimitry Andric   if (NewOpC == -1)
2816bdd1243dSDimitry Andric     return false;
2817bdd1243dSDimitry Andric 
2818bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Replace Instr: ");
2819bdd1243dSDimitry Andric   LLVM_DEBUG(SrcMI->dump());
2820bdd1243dSDimitry Andric 
2821bdd1243dSDimitry Andric   const MCInstrDesc &NewDesc = get(NewOpC);
2822bdd1243dSDimitry Andric   SrcMI->setDesc(NewDesc);
2823bdd1243dSDimitry Andric   MachineInstrBuilder(*SrcMI->getParent()->getParent(), SrcMI)
2824bdd1243dSDimitry Andric       .addReg(CRReg, RegState::ImplicitDefine);
2825bdd1243dSDimitry Andric   SrcMI->clearRegisterDeads(CRReg);
2826bdd1243dSDimitry Andric 
28270fca6ea1SDimitry Andric   assert(SrcMI->definesRegister(PPC::CR0, /*TRI=*/nullptr) &&
2828bdd1243dSDimitry Andric          "Record-form instruction does not define cr0?");
2829bdd1243dSDimitry Andric 
2830bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "with: ");
2831bdd1243dSDimitry Andric   LLVM_DEBUG(SrcMI->dump());
2832bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
2833bdd1243dSDimitry Andric   LLVM_DEBUG(CmpMI.dump());
2834bdd1243dSDimitry Andric   return true;
2835bdd1243dSDimitry Andric }
2836bdd1243dSDimitry Andric 
2837e8d8bef9SDimitry Andric bool PPCInstrInfo::getMemOperandsWithOffsetWidth(
2838e8d8bef9SDimitry Andric     const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
28390fca6ea1SDimitry Andric     int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
2840e8d8bef9SDimitry Andric     const TargetRegisterInfo *TRI) const {
2841e8d8bef9SDimitry Andric   const MachineOperand *BaseOp;
2842e8d8bef9SDimitry Andric   OffsetIsScalable = false;
2843e8d8bef9SDimitry Andric   if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, Width, TRI))
2844e8d8bef9SDimitry Andric     return false;
2845e8d8bef9SDimitry Andric   BaseOps.push_back(BaseOp);
2846e8d8bef9SDimitry Andric   return true;
2847e8d8bef9SDimitry Andric }
2848e8d8bef9SDimitry Andric 
2849e8d8bef9SDimitry Andric static bool isLdStSafeToCluster(const MachineInstr &LdSt,
2850e8d8bef9SDimitry Andric                                 const TargetRegisterInfo *TRI) {
2851e8d8bef9SDimitry Andric   // If this is a volatile load/store, don't mess with it.
2852e8d8bef9SDimitry Andric   if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
2853e8d8bef9SDimitry Andric     return false;
2854e8d8bef9SDimitry Andric 
2855e8d8bef9SDimitry Andric   if (LdSt.getOperand(2).isFI())
2856e8d8bef9SDimitry Andric     return true;
2857e8d8bef9SDimitry Andric 
2858e8d8bef9SDimitry Andric   assert(LdSt.getOperand(2).isReg() && "Expected a reg operand.");
2859e8d8bef9SDimitry Andric   // Can't cluster if the instruction modifies the base register
2860e8d8bef9SDimitry Andric   // or it is update form. e.g. ld r2,3(r2)
2861e8d8bef9SDimitry Andric   if (LdSt.modifiesRegister(LdSt.getOperand(2).getReg(), TRI))
2862e8d8bef9SDimitry Andric     return false;
2863e8d8bef9SDimitry Andric 
2864e8d8bef9SDimitry Andric   return true;
2865e8d8bef9SDimitry Andric }
2866e8d8bef9SDimitry Andric 
2867e8d8bef9SDimitry Andric // Only cluster instruction pair that have the same opcode, and they are
2868e8d8bef9SDimitry Andric // clusterable according to PowerPC specification.
2869e8d8bef9SDimitry Andric static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc,
2870e8d8bef9SDimitry Andric                                      const PPCSubtarget &Subtarget) {
2871e8d8bef9SDimitry Andric   switch (FirstOpc) {
2872e8d8bef9SDimitry Andric   default:
2873e8d8bef9SDimitry Andric     return false;
2874e8d8bef9SDimitry Andric   case PPC::STD:
2875e8d8bef9SDimitry Andric   case PPC::STFD:
2876e8d8bef9SDimitry Andric   case PPC::STXSD:
2877e8d8bef9SDimitry Andric   case PPC::DFSTOREf64:
2878e8d8bef9SDimitry Andric     return FirstOpc == SecondOpc;
2879e8d8bef9SDimitry Andric   // PowerPC backend has opcode STW/STW8 for instruction "stw" to deal with
2880e8d8bef9SDimitry Andric   // 32bit and 64bit instruction selection. They are clusterable pair though
2881e8d8bef9SDimitry Andric   // they are different opcode.
2882e8d8bef9SDimitry Andric   case PPC::STW:
2883e8d8bef9SDimitry Andric   case PPC::STW8:
2884e8d8bef9SDimitry Andric     return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2885e8d8bef9SDimitry Andric   }
2886e8d8bef9SDimitry Andric }
2887e8d8bef9SDimitry Andric 
2888e8d8bef9SDimitry Andric bool PPCInstrInfo::shouldClusterMemOps(
28895f757f3fSDimitry Andric     ArrayRef<const MachineOperand *> BaseOps1, int64_t OpOffset1,
28905f757f3fSDimitry Andric     bool OffsetIsScalable1, ArrayRef<const MachineOperand *> BaseOps2,
28915f757f3fSDimitry Andric     int64_t OpOffset2, bool OffsetIsScalable2, unsigned ClusterSize,
2892e8d8bef9SDimitry Andric     unsigned NumBytes) const {
2893e8d8bef9SDimitry Andric 
2894e8d8bef9SDimitry Andric   assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);
2895e8d8bef9SDimitry Andric   const MachineOperand &BaseOp1 = *BaseOps1.front();
2896e8d8bef9SDimitry Andric   const MachineOperand &BaseOp2 = *BaseOps2.front();
2897e8d8bef9SDimitry Andric   assert((BaseOp1.isReg() || BaseOp1.isFI()) &&
2898e8d8bef9SDimitry Andric          "Only base registers and frame indices are supported.");
2899e8d8bef9SDimitry Andric 
29005f757f3fSDimitry Andric   // ClusterSize means the number of memory operations that will have been
29015f757f3fSDimitry Andric   // clustered if this hook returns true.
2902e8d8bef9SDimitry Andric   // Don't cluster memory op if there are already two ops clustered at least.
29035f757f3fSDimitry Andric   if (ClusterSize > 2)
2904e8d8bef9SDimitry Andric     return false;
2905e8d8bef9SDimitry Andric 
2906e8d8bef9SDimitry Andric   // Cluster the load/store only when they have the same base
2907e8d8bef9SDimitry Andric   // register or FI.
2908e8d8bef9SDimitry Andric   if ((BaseOp1.isReg() != BaseOp2.isReg()) ||
2909e8d8bef9SDimitry Andric       (BaseOp1.isReg() && BaseOp1.getReg() != BaseOp2.getReg()) ||
2910e8d8bef9SDimitry Andric       (BaseOp1.isFI() && BaseOp1.getIndex() != BaseOp2.getIndex()))
2911e8d8bef9SDimitry Andric     return false;
2912e8d8bef9SDimitry Andric 
2913e8d8bef9SDimitry Andric   // Check if the load/store are clusterable according to the PowerPC
2914e8d8bef9SDimitry Andric   // specification.
2915e8d8bef9SDimitry Andric   const MachineInstr &FirstLdSt = *BaseOp1.getParent();
2916e8d8bef9SDimitry Andric   const MachineInstr &SecondLdSt = *BaseOp2.getParent();
2917e8d8bef9SDimitry Andric   unsigned FirstOpc = FirstLdSt.getOpcode();
2918e8d8bef9SDimitry Andric   unsigned SecondOpc = SecondLdSt.getOpcode();
2919e8d8bef9SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
2920e8d8bef9SDimitry Andric   // Cluster the load/store only when they have the same opcode, and they are
2921e8d8bef9SDimitry Andric   // clusterable opcode according to PowerPC specification.
2922e8d8bef9SDimitry Andric   if (!isClusterableLdStOpcPair(FirstOpc, SecondOpc, Subtarget))
2923e8d8bef9SDimitry Andric     return false;
2924e8d8bef9SDimitry Andric 
2925e8d8bef9SDimitry Andric   // Can't cluster load/store that have ordered or volatile memory reference.
2926e8d8bef9SDimitry Andric   if (!isLdStSafeToCluster(FirstLdSt, TRI) ||
2927e8d8bef9SDimitry Andric       !isLdStSafeToCluster(SecondLdSt, TRI))
2928e8d8bef9SDimitry Andric     return false;
2929e8d8bef9SDimitry Andric 
2930e8d8bef9SDimitry Andric   int64_t Offset1 = 0, Offset2 = 0;
29310fca6ea1SDimitry Andric   LocationSize Width1 = 0, Width2 = 0;
2932e8d8bef9SDimitry Andric   const MachineOperand *Base1 = nullptr, *Base2 = nullptr;
2933e8d8bef9SDimitry Andric   if (!getMemOperandWithOffsetWidth(FirstLdSt, Base1, Offset1, Width1, TRI) ||
2934e8d8bef9SDimitry Andric       !getMemOperandWithOffsetWidth(SecondLdSt, Base2, Offset2, Width2, TRI) ||
2935e8d8bef9SDimitry Andric       Width1 != Width2)
2936e8d8bef9SDimitry Andric     return false;
2937e8d8bef9SDimitry Andric 
2938e8d8bef9SDimitry Andric   assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2939e8d8bef9SDimitry Andric          "getMemOperandWithOffsetWidth return incorrect base op");
2940e8d8bef9SDimitry Andric   // The caller should already have ordered FirstMemOp/SecondMemOp by offset.
2941e8d8bef9SDimitry Andric   assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");
29420fca6ea1SDimitry Andric   return Offset1 + (int64_t)Width1.getValue() == Offset2;
2943e8d8bef9SDimitry Andric }
2944e8d8bef9SDimitry Andric 
29450b57cec5SDimitry Andric /// GetInstSize - Return the number of bytes of code the specified
29460b57cec5SDimitry Andric /// instruction may be.  This returns the maximum number of bytes.
29470b57cec5SDimitry Andric ///
29480b57cec5SDimitry Andric unsigned PPCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
29490b57cec5SDimitry Andric   unsigned Opcode = MI.getOpcode();
29500b57cec5SDimitry Andric 
29510b57cec5SDimitry Andric   if (Opcode == PPC::INLINEASM || Opcode == PPC::INLINEASM_BR) {
29520b57cec5SDimitry Andric     const MachineFunction *MF = MI.getParent()->getParent();
29530b57cec5SDimitry Andric     const char *AsmStr = MI.getOperand(0).getSymbolName();
29540b57cec5SDimitry Andric     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
29550b57cec5SDimitry Andric   } else if (Opcode == TargetOpcode::STACKMAP) {
29560b57cec5SDimitry Andric     StackMapOpers Opers(&MI);
29570b57cec5SDimitry Andric     return Opers.getNumPatchBytes();
29580b57cec5SDimitry Andric   } else if (Opcode == TargetOpcode::PATCHPOINT) {
29590b57cec5SDimitry Andric     PatchPointOpers Opers(&MI);
29600b57cec5SDimitry Andric     return Opers.getNumPatchBytes();
29610b57cec5SDimitry Andric   } else {
29620b57cec5SDimitry Andric     return get(Opcode).getSize();
29630b57cec5SDimitry Andric   }
29640b57cec5SDimitry Andric }
29650b57cec5SDimitry Andric 
29660b57cec5SDimitry Andric std::pair<unsigned, unsigned>
29670b57cec5SDimitry Andric PPCInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
29685f757f3fSDimitry Andric   // PPC always uses a direct mask.
29695f757f3fSDimitry Andric   return std::make_pair(TF, 0u);
29700b57cec5SDimitry Andric }
29710b57cec5SDimitry Andric 
29720b57cec5SDimitry Andric ArrayRef<std::pair<unsigned, const char *>>
29730b57cec5SDimitry Andric PPCInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
29740b57cec5SDimitry Andric   using namespace PPCII;
29750b57cec5SDimitry Andric   static const std::pair<unsigned, const char *> TargetFlags[] = {
29760b57cec5SDimitry Andric       {MO_PLT, "ppc-plt"},
29770b57cec5SDimitry Andric       {MO_PIC_FLAG, "ppc-pic"},
29785ffd83dbSDimitry Andric       {MO_PCREL_FLAG, "ppc-pcrel"},
2979e8d8bef9SDimitry Andric       {MO_GOT_FLAG, "ppc-got"},
2980e8d8bef9SDimitry Andric       {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
2981e8d8bef9SDimitry Andric       {MO_TLSGD_FLAG, "ppc-tlsgd"},
2982e8d8bef9SDimitry Andric       {MO_TPREL_FLAG, "ppc-tprel"},
29830fca6ea1SDimitry Andric       {MO_TLSLDM_FLAG, "ppc-tlsldm"},
29845f757f3fSDimitry Andric       {MO_TLSLD_FLAG, "ppc-tlsld"},
2985fe6060f1SDimitry Andric       {MO_TLSGDM_FLAG, "ppc-tlsgdm"},
2986e8d8bef9SDimitry Andric       {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
2987e8d8bef9SDimitry Andric       {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
29885f757f3fSDimitry Andric       {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"},
29895f757f3fSDimitry Andric       {MO_LO, "ppc-lo"},
29905f757f3fSDimitry Andric       {MO_HA, "ppc-ha"},
29915f757f3fSDimitry Andric       {MO_TPREL_LO, "ppc-tprel-lo"},
29925f757f3fSDimitry Andric       {MO_TPREL_HA, "ppc-tprel-ha"},
29935f757f3fSDimitry Andric       {MO_DTPREL_LO, "ppc-dtprel-lo"},
29945f757f3fSDimitry Andric       {MO_TLSLD_LO, "ppc-tlsld-lo"},
29955f757f3fSDimitry Andric       {MO_TOC_LO, "ppc-toc-lo"},
29965f757f3fSDimitry Andric       {MO_TLS, "ppc-tls"},
29975f757f3fSDimitry Andric       {MO_PIC_HA_FLAG, "ppc-ha-pic"},
29985f757f3fSDimitry Andric       {MO_PIC_LO_FLAG, "ppc-lo-pic"},
29995f757f3fSDimitry Andric       {MO_TPREL_PCREL_FLAG, "ppc-tprel-pcrel"},
30005f757f3fSDimitry Andric       {MO_TLS_PCREL_FLAG, "ppc-tls-pcrel"},
30015f757f3fSDimitry Andric       {MO_GOT_PCREL_FLAG, "ppc-got-pcrel"},
30025f757f3fSDimitry Andric   };
3003bdd1243dSDimitry Andric   return ArrayRef(TargetFlags);
30040b57cec5SDimitry Andric }
30050b57cec5SDimitry Andric 
30060b57cec5SDimitry Andric // Expand VSX Memory Pseudo instruction to either a VSX or a FP instruction.
30070b57cec5SDimitry Andric // The VSX versions have the advantage of a full 64-register target whereas
30080b57cec5SDimitry Andric // the FP ones have the advantage of lower latency and higher throughput. So
30090b57cec5SDimitry Andric // what we are after is using the faster instructions in low register pressure
30100b57cec5SDimitry Andric // situations and using the larger register file in high register pressure
30110b57cec5SDimitry Andric // situations.
30120b57cec5SDimitry Andric bool PPCInstrInfo::expandVSXMemPseudo(MachineInstr &MI) const {
30130b57cec5SDimitry Andric     unsigned UpperOpcode, LowerOpcode;
30140b57cec5SDimitry Andric     switch (MI.getOpcode()) {
30150b57cec5SDimitry Andric     case PPC::DFLOADf32:
30160b57cec5SDimitry Andric       UpperOpcode = PPC::LXSSP;
30170b57cec5SDimitry Andric       LowerOpcode = PPC::LFS;
30180b57cec5SDimitry Andric       break;
30190b57cec5SDimitry Andric     case PPC::DFLOADf64:
30200b57cec5SDimitry Andric       UpperOpcode = PPC::LXSD;
30210b57cec5SDimitry Andric       LowerOpcode = PPC::LFD;
30220b57cec5SDimitry Andric       break;
30230b57cec5SDimitry Andric     case PPC::DFSTOREf32:
30240b57cec5SDimitry Andric       UpperOpcode = PPC::STXSSP;
30250b57cec5SDimitry Andric       LowerOpcode = PPC::STFS;
30260b57cec5SDimitry Andric       break;
30270b57cec5SDimitry Andric     case PPC::DFSTOREf64:
30280b57cec5SDimitry Andric       UpperOpcode = PPC::STXSD;
30290b57cec5SDimitry Andric       LowerOpcode = PPC::STFD;
30300b57cec5SDimitry Andric       break;
30310b57cec5SDimitry Andric     case PPC::XFLOADf32:
30320b57cec5SDimitry Andric       UpperOpcode = PPC::LXSSPX;
30330b57cec5SDimitry Andric       LowerOpcode = PPC::LFSX;
30340b57cec5SDimitry Andric       break;
30350b57cec5SDimitry Andric     case PPC::XFLOADf64:
30360b57cec5SDimitry Andric       UpperOpcode = PPC::LXSDX;
30370b57cec5SDimitry Andric       LowerOpcode = PPC::LFDX;
30380b57cec5SDimitry Andric       break;
30390b57cec5SDimitry Andric     case PPC::XFSTOREf32:
30400b57cec5SDimitry Andric       UpperOpcode = PPC::STXSSPX;
30410b57cec5SDimitry Andric       LowerOpcode = PPC::STFSX;
30420b57cec5SDimitry Andric       break;
30430b57cec5SDimitry Andric     case PPC::XFSTOREf64:
30440b57cec5SDimitry Andric       UpperOpcode = PPC::STXSDX;
30450b57cec5SDimitry Andric       LowerOpcode = PPC::STFDX;
30460b57cec5SDimitry Andric       break;
30470b57cec5SDimitry Andric     case PPC::LIWAX:
30480b57cec5SDimitry Andric       UpperOpcode = PPC::LXSIWAX;
30490b57cec5SDimitry Andric       LowerOpcode = PPC::LFIWAX;
30500b57cec5SDimitry Andric       break;
30510b57cec5SDimitry Andric     case PPC::LIWZX:
30520b57cec5SDimitry Andric       UpperOpcode = PPC::LXSIWZX;
30530b57cec5SDimitry Andric       LowerOpcode = PPC::LFIWZX;
30540b57cec5SDimitry Andric       break;
30550b57cec5SDimitry Andric     case PPC::STIWX:
30560b57cec5SDimitry Andric       UpperOpcode = PPC::STXSIWX;
30570b57cec5SDimitry Andric       LowerOpcode = PPC::STFIWX;
30580b57cec5SDimitry Andric       break;
30590b57cec5SDimitry Andric     default:
30600b57cec5SDimitry Andric       llvm_unreachable("Unknown Operation!");
30610b57cec5SDimitry Andric     }
30620b57cec5SDimitry Andric 
30638bcb0991SDimitry Andric     Register TargetReg = MI.getOperand(0).getReg();
30640b57cec5SDimitry Andric     unsigned Opcode;
30650b57cec5SDimitry Andric     if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
30660b57cec5SDimitry Andric         (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
30670b57cec5SDimitry Andric       Opcode = LowerOpcode;
30680b57cec5SDimitry Andric     else
30690b57cec5SDimitry Andric       Opcode = UpperOpcode;
30700b57cec5SDimitry Andric     MI.setDesc(get(Opcode));
30710b57cec5SDimitry Andric     return true;
30720b57cec5SDimitry Andric }
30730b57cec5SDimitry Andric 
30740b57cec5SDimitry Andric static bool isAnImmediateOperand(const MachineOperand &MO) {
30750b57cec5SDimitry Andric   return MO.isCPI() || MO.isGlobal() || MO.isImm();
30760b57cec5SDimitry Andric }
30770b57cec5SDimitry Andric 
30780b57cec5SDimitry Andric bool PPCInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
30790b57cec5SDimitry Andric   auto &MBB = *MI.getParent();
30800b57cec5SDimitry Andric   auto DL = MI.getDebugLoc();
30810b57cec5SDimitry Andric 
30820b57cec5SDimitry Andric   switch (MI.getOpcode()) {
3083e8d8bef9SDimitry Andric   case PPC::BUILD_UACC: {
3084e8d8bef9SDimitry Andric     MCRegister ACC = MI.getOperand(0).getReg();
3085e8d8bef9SDimitry Andric     MCRegister UACC = MI.getOperand(1).getReg();
3086e8d8bef9SDimitry Andric     if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3087e8d8bef9SDimitry Andric       MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3088e8d8bef9SDimitry Andric       MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3089e8d8bef9SDimitry Andric       // FIXME: This can easily be improved to look up to the top of the MBB
3090e8d8bef9SDimitry Andric       // to see if the inputs are XXLOR's. If they are and SrcReg is killed,
3091e8d8bef9SDimitry Andric       // we can just re-target any such XXLOR's to DstVSR + offset.
3092e8d8bef9SDimitry Andric       for (int VecNo = 0; VecNo < 4; VecNo++)
3093e8d8bef9SDimitry Andric         BuildMI(MBB, MI, DL, get(PPC::XXLOR), DstVSR + VecNo)
3094e8d8bef9SDimitry Andric             .addReg(SrcVSR + VecNo)
3095e8d8bef9SDimitry Andric             .addReg(SrcVSR + VecNo);
3096e8d8bef9SDimitry Andric     }
3097349cc55cSDimitry Andric     // BUILD_UACC is expanded to 4 copies of the underlying vsx registers.
3098e8d8bef9SDimitry Andric     // So after building the 4 copies, we can replace the BUILD_UACC instruction
3099e8d8bef9SDimitry Andric     // with a NOP.
3100bdd1243dSDimitry Andric     [[fallthrough]];
3101e8d8bef9SDimitry Andric   }
3102e8d8bef9SDimitry Andric   case PPC::KILL_PAIR: {
3103e8d8bef9SDimitry Andric     MI.setDesc(get(PPC::UNENCODED_NOP));
310481ad6265SDimitry Andric     MI.removeOperand(1);
310581ad6265SDimitry Andric     MI.removeOperand(0);
3106e8d8bef9SDimitry Andric     return true;
3107e8d8bef9SDimitry Andric   }
31080b57cec5SDimitry Andric   case TargetOpcode::LOAD_STACK_GUARD: {
31090b57cec5SDimitry Andric     assert(Subtarget.isTargetLinux() &&
31100b57cec5SDimitry Andric            "Only Linux target is expected to contain LOAD_STACK_GUARD");
31110b57cec5SDimitry Andric     const int64_t Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
31120b57cec5SDimitry Andric     const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
31130b57cec5SDimitry Andric     MI.setDesc(get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
31140b57cec5SDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
31150b57cec5SDimitry Andric         .addImm(Offset)
31160b57cec5SDimitry Andric         .addReg(Reg);
31170b57cec5SDimitry Andric     return true;
31180b57cec5SDimitry Andric   }
31190fca6ea1SDimitry Andric   case PPC::PPCLdFixedAddr: {
31200fca6ea1SDimitry Andric     assert(Subtarget.getTargetTriple().isOSGlibc() &&
31210fca6ea1SDimitry Andric            "Only targets with Glibc expected to contain PPCLdFixedAddr");
31220fca6ea1SDimitry Andric     int64_t Offset = 0;
31230fca6ea1SDimitry Andric     const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
31240fca6ea1SDimitry Andric     MI.setDesc(get(PPC::LWZ));
31250fca6ea1SDimitry Andric     uint64_t FAType = MI.getOperand(1).getImm();
31260fca6ea1SDimitry Andric #undef PPC_LNX_FEATURE
31270fca6ea1SDimitry Andric #undef PPC_CPU
31280fca6ea1SDimitry Andric #define PPC_LNX_DEFINE_OFFSETS
31290fca6ea1SDimitry Andric #include "llvm/TargetParser/PPCTargetParser.def"
31300fca6ea1SDimitry Andric     bool IsLE = Subtarget.isLittleEndian();
31310fca6ea1SDimitry Andric     bool Is64 = Subtarget.isPPC64();
31320fca6ea1SDimitry Andric     if (FAType == PPC_FAWORD_HWCAP) {
31330fca6ea1SDimitry Andric       if (IsLE)
31340fca6ea1SDimitry Andric         Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
31350fca6ea1SDimitry Andric       else
31360fca6ea1SDimitry Andric         Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
31370fca6ea1SDimitry Andric     } else if (FAType == PPC_FAWORD_HWCAP2) {
31380fca6ea1SDimitry Andric       if (IsLE)
31390fca6ea1SDimitry Andric         Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
31400fca6ea1SDimitry Andric       else
31410fca6ea1SDimitry Andric         Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
31420fca6ea1SDimitry Andric     } else if (FAType == PPC_FAWORD_CPUID) {
31430fca6ea1SDimitry Andric       if (IsLE)
31440fca6ea1SDimitry Andric         Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
31450fca6ea1SDimitry Andric       else
31460fca6ea1SDimitry Andric         Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
31470fca6ea1SDimitry Andric     }
31480fca6ea1SDimitry Andric     assert(Offset && "Do not know the offset for this fixed addr load");
31490fca6ea1SDimitry Andric     MI.removeOperand(1);
31500fca6ea1SDimitry Andric     Subtarget.getTargetMachine().setGlibcHWCAPAccess();
31510fca6ea1SDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
31520fca6ea1SDimitry Andric         .addImm(Offset)
31530fca6ea1SDimitry Andric         .addReg(Reg);
31540fca6ea1SDimitry Andric     return true;
31550fca6ea1SDimitry Andric #define PPC_TGT_PARSER_UNDEF_MACROS
31560fca6ea1SDimitry Andric #include "llvm/TargetParser/PPCTargetParser.def"
31570fca6ea1SDimitry Andric #undef PPC_TGT_PARSER_UNDEF_MACROS
31580fca6ea1SDimitry Andric   }
31590b57cec5SDimitry Andric   case PPC::DFLOADf32:
31600b57cec5SDimitry Andric   case PPC::DFLOADf64:
31610b57cec5SDimitry Andric   case PPC::DFSTOREf32:
31620b57cec5SDimitry Andric   case PPC::DFSTOREf64: {
31630b57cec5SDimitry Andric     assert(Subtarget.hasP9Vector() &&
31640b57cec5SDimitry Andric            "Invalid D-Form Pseudo-ops on Pre-P9 target.");
31650b57cec5SDimitry Andric     assert(MI.getOperand(2).isReg() &&
31660b57cec5SDimitry Andric            isAnImmediateOperand(MI.getOperand(1)) &&
31670b57cec5SDimitry Andric            "D-form op must have register and immediate operands");
31680b57cec5SDimitry Andric     return expandVSXMemPseudo(MI);
31690b57cec5SDimitry Andric   }
31700b57cec5SDimitry Andric   case PPC::XFLOADf32:
31710b57cec5SDimitry Andric   case PPC::XFSTOREf32:
31720b57cec5SDimitry Andric   case PPC::LIWAX:
31730b57cec5SDimitry Andric   case PPC::LIWZX:
31740b57cec5SDimitry Andric   case PPC::STIWX: {
31750b57cec5SDimitry Andric     assert(Subtarget.hasP8Vector() &&
31760b57cec5SDimitry Andric            "Invalid X-Form Pseudo-ops on Pre-P8 target.");
31770b57cec5SDimitry Andric     assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
31780b57cec5SDimitry Andric            "X-form op must have register and register operands");
31790b57cec5SDimitry Andric     return expandVSXMemPseudo(MI);
31800b57cec5SDimitry Andric   }
31810b57cec5SDimitry Andric   case PPC::XFLOADf64:
31820b57cec5SDimitry Andric   case PPC::XFSTOREf64: {
31830b57cec5SDimitry Andric     assert(Subtarget.hasVSX() &&
31840b57cec5SDimitry Andric            "Invalid X-Form Pseudo-ops on target that has no VSX.");
31850b57cec5SDimitry Andric     assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&
31860b57cec5SDimitry Andric            "X-form op must have register and register operands");
31870b57cec5SDimitry Andric     return expandVSXMemPseudo(MI);
31880b57cec5SDimitry Andric   }
31890b57cec5SDimitry Andric   case PPC::SPILLTOVSR_LD: {
31908bcb0991SDimitry Andric     Register TargetReg = MI.getOperand(0).getReg();
31910b57cec5SDimitry Andric     if (PPC::VSFRCRegClass.contains(TargetReg)) {
31920b57cec5SDimitry Andric       MI.setDesc(get(PPC::DFLOADf64));
31930b57cec5SDimitry Andric       return expandPostRAPseudo(MI);
31940b57cec5SDimitry Andric     }
31950b57cec5SDimitry Andric     else
31960b57cec5SDimitry Andric       MI.setDesc(get(PPC::LD));
31970b57cec5SDimitry Andric     return true;
31980b57cec5SDimitry Andric   }
31990b57cec5SDimitry Andric   case PPC::SPILLTOVSR_ST: {
32008bcb0991SDimitry Andric     Register SrcReg = MI.getOperand(0).getReg();
32010b57cec5SDimitry Andric     if (PPC::VSFRCRegClass.contains(SrcReg)) {
32020b57cec5SDimitry Andric       NumStoreSPILLVSRRCAsVec++;
32030b57cec5SDimitry Andric       MI.setDesc(get(PPC::DFSTOREf64));
32040b57cec5SDimitry Andric       return expandPostRAPseudo(MI);
32050b57cec5SDimitry Andric     } else {
32060b57cec5SDimitry Andric       NumStoreSPILLVSRRCAsGpr++;
32070b57cec5SDimitry Andric       MI.setDesc(get(PPC::STD));
32080b57cec5SDimitry Andric     }
32090b57cec5SDimitry Andric     return true;
32100b57cec5SDimitry Andric   }
32110b57cec5SDimitry Andric   case PPC::SPILLTOVSR_LDX: {
32128bcb0991SDimitry Andric     Register TargetReg = MI.getOperand(0).getReg();
32130b57cec5SDimitry Andric     if (PPC::VSFRCRegClass.contains(TargetReg))
32140b57cec5SDimitry Andric       MI.setDesc(get(PPC::LXSDX));
32150b57cec5SDimitry Andric     else
32160b57cec5SDimitry Andric       MI.setDesc(get(PPC::LDX));
32170b57cec5SDimitry Andric     return true;
32180b57cec5SDimitry Andric   }
32190b57cec5SDimitry Andric   case PPC::SPILLTOVSR_STX: {
32208bcb0991SDimitry Andric     Register SrcReg = MI.getOperand(0).getReg();
32210b57cec5SDimitry Andric     if (PPC::VSFRCRegClass.contains(SrcReg)) {
32220b57cec5SDimitry Andric       NumStoreSPILLVSRRCAsVec++;
32230b57cec5SDimitry Andric       MI.setDesc(get(PPC::STXSDX));
32240b57cec5SDimitry Andric     } else {
32250b57cec5SDimitry Andric       NumStoreSPILLVSRRCAsGpr++;
32260b57cec5SDimitry Andric       MI.setDesc(get(PPC::STDX));
32270b57cec5SDimitry Andric     }
32280b57cec5SDimitry Andric     return true;
32290b57cec5SDimitry Andric   }
32300b57cec5SDimitry Andric 
3231349cc55cSDimitry Andric     // FIXME: Maybe we can expand it in 'PowerPC Expand Atomic' pass.
3232cb14a3feSDimitry Andric   case PPC::CFENCE:
32330b57cec5SDimitry Andric   case PPC::CFENCE8: {
32340b57cec5SDimitry Andric     auto Val = MI.getOperand(0).getReg();
3235cb14a3feSDimitry Andric     unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3236cb14a3feSDimitry Andric     BuildMI(MBB, MI, DL, get(CmpOp), PPC::CR7).addReg(Val).addReg(Val);
32370b57cec5SDimitry Andric     BuildMI(MBB, MI, DL, get(PPC::CTRL_DEP))
32380b57cec5SDimitry Andric         .addImm(PPC::PRED_NE_MINUS)
32390b57cec5SDimitry Andric         .addReg(PPC::CR7)
32400b57cec5SDimitry Andric         .addImm(1);
32410b57cec5SDimitry Andric     MI.setDesc(get(PPC::ISYNC));
324281ad6265SDimitry Andric     MI.removeOperand(0);
32430b57cec5SDimitry Andric     return true;
32440b57cec5SDimitry Andric   }
32450b57cec5SDimitry Andric   }
32460b57cec5SDimitry Andric   return false;
32470b57cec5SDimitry Andric }
32480b57cec5SDimitry Andric 
32490b57cec5SDimitry Andric // Essentially a compile-time implementation of a compare->isel sequence.
32500b57cec5SDimitry Andric // It takes two constants to compare, along with the true/false registers
32510b57cec5SDimitry Andric // and the comparison type (as a subreg to a CR field) and returns one
32520b57cec5SDimitry Andric // of the true/false registers, depending on the comparison results.
32530b57cec5SDimitry Andric static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,
32540b57cec5SDimitry Andric                           unsigned TrueReg, unsigned FalseReg,
32550b57cec5SDimitry Andric                           unsigned CRSubReg) {
32560b57cec5SDimitry Andric   // Signed comparisons. The immediates are assumed to be sign-extended.
32570b57cec5SDimitry Andric   if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
32580b57cec5SDimitry Andric     switch (CRSubReg) {
32590b57cec5SDimitry Andric     default: llvm_unreachable("Unknown integer comparison type.");
32600b57cec5SDimitry Andric     case PPC::sub_lt:
32610b57cec5SDimitry Andric       return Imm1 < Imm2 ? TrueReg : FalseReg;
32620b57cec5SDimitry Andric     case PPC::sub_gt:
32630b57cec5SDimitry Andric       return Imm1 > Imm2 ? TrueReg : FalseReg;
32640b57cec5SDimitry Andric     case PPC::sub_eq:
32650b57cec5SDimitry Andric       return Imm1 == Imm2 ? TrueReg : FalseReg;
32660b57cec5SDimitry Andric     }
32670b57cec5SDimitry Andric   }
32680b57cec5SDimitry Andric   // Unsigned comparisons.
32690b57cec5SDimitry Andric   else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
32700b57cec5SDimitry Andric     switch (CRSubReg) {
32710b57cec5SDimitry Andric     default: llvm_unreachable("Unknown integer comparison type.");
32720b57cec5SDimitry Andric     case PPC::sub_lt:
32730b57cec5SDimitry Andric       return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;
32740b57cec5SDimitry Andric     case PPC::sub_gt:
32750b57cec5SDimitry Andric       return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;
32760b57cec5SDimitry Andric     case PPC::sub_eq:
32770b57cec5SDimitry Andric       return Imm1 == Imm2 ? TrueReg : FalseReg;
32780b57cec5SDimitry Andric     }
32790b57cec5SDimitry Andric   }
32800b57cec5SDimitry Andric   return PPC::NoRegister;
32810b57cec5SDimitry Andric }
32820b57cec5SDimitry Andric 
32830b57cec5SDimitry Andric void PPCInstrInfo::replaceInstrOperandWithImm(MachineInstr &MI,
32840b57cec5SDimitry Andric                                               unsigned OpNo,
32850b57cec5SDimitry Andric                                               int64_t Imm) const {
32860b57cec5SDimitry Andric   assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");
32870b57cec5SDimitry Andric   // Replace the REG with the Immediate.
32888bcb0991SDimitry Andric   Register InUseReg = MI.getOperand(OpNo).getReg();
32890b57cec5SDimitry Andric   MI.getOperand(OpNo).ChangeToImmediate(Imm);
32900b57cec5SDimitry Andric 
32910b57cec5SDimitry Andric   // We need to make sure that the MI didn't have any implicit use
3292fe6060f1SDimitry Andric   // of this REG any more. We don't call MI.implicit_operands().empty() to
3293fe6060f1SDimitry Andric   // return early, since MI's MCID might be changed in calling context, as a
3294fe6060f1SDimitry Andric   // result its number of explicit operands may be changed, thus the begin of
3295fe6060f1SDimitry Andric   // implicit operand is changed.
32960b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
32970fca6ea1SDimitry Andric   int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, TRI, false);
32980b57cec5SDimitry Andric   if (UseOpIdx >= 0) {
32990b57cec5SDimitry Andric     MachineOperand &MO = MI.getOperand(UseOpIdx);
33000b57cec5SDimitry Andric     if (MO.isImplicit())
33010b57cec5SDimitry Andric       // The operands must always be in the following order:
33020b57cec5SDimitry Andric       // - explicit reg defs,
33030b57cec5SDimitry Andric       // - other explicit operands (reg uses, immediates, etc.),
33040b57cec5SDimitry Andric       // - implicit reg defs
33050b57cec5SDimitry Andric       // - implicit reg uses
33060b57cec5SDimitry Andric       // Therefore, removing the implicit operand won't change the explicit
33070b57cec5SDimitry Andric       // operands layout.
330881ad6265SDimitry Andric       MI.removeOperand(UseOpIdx);
33090b57cec5SDimitry Andric   }
33100b57cec5SDimitry Andric }
33110b57cec5SDimitry Andric 
33120b57cec5SDimitry Andric // Replace an instruction with one that materializes a constant (and sets
33130b57cec5SDimitry Andric // CR0 if the original instruction was a record-form instruction).
33140b57cec5SDimitry Andric void PPCInstrInfo::replaceInstrWithLI(MachineInstr &MI,
33150b57cec5SDimitry Andric                                       const LoadImmediateInfo &LII) const {
33160b57cec5SDimitry Andric   // Remove existing operands.
33170b57cec5SDimitry Andric   int OperandToKeep = LII.SetCR ? 1 : 0;
33180b57cec5SDimitry Andric   for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)
331981ad6265SDimitry Andric     MI.removeOperand(i);
33200b57cec5SDimitry Andric 
33210b57cec5SDimitry Andric   // Replace the instruction.
33220b57cec5SDimitry Andric   if (LII.SetCR) {
3323480093f4SDimitry Andric     MI.setDesc(get(LII.Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
33240b57cec5SDimitry Andric     // Set the immediate.
33250b57cec5SDimitry Andric     MachineInstrBuilder(*MI.getParent()->getParent(), MI)
33260b57cec5SDimitry Andric         .addImm(LII.Imm).addReg(PPC::CR0, RegState::ImplicitDefine);
33270b57cec5SDimitry Andric     return;
33280b57cec5SDimitry Andric   }
33290b57cec5SDimitry Andric   else
33300b57cec5SDimitry Andric     MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));
33310b57cec5SDimitry Andric 
33320b57cec5SDimitry Andric   // Set the immediate.
33330b57cec5SDimitry Andric   MachineInstrBuilder(*MI.getParent()->getParent(), MI)
33340b57cec5SDimitry Andric       .addImm(LII.Imm);
33350b57cec5SDimitry Andric }
33360b57cec5SDimitry Andric 
33378bcb0991SDimitry Andric MachineInstr *PPCInstrInfo::getDefMIPostRA(unsigned Reg, MachineInstr &MI,
33388bcb0991SDimitry Andric                                            bool &SeenIntermediateUse) const {
33398bcb0991SDimitry Andric   assert(!MI.getParent()->getParent()->getRegInfo().isSSA() &&
33408bcb0991SDimitry Andric          "Should be called after register allocation.");
33418bcb0991SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
33428bcb0991SDimitry Andric   MachineBasicBlock::reverse_iterator E = MI.getParent()->rend(), It = MI;
33438bcb0991SDimitry Andric   It++;
33448bcb0991SDimitry Andric   SeenIntermediateUse = false;
33458bcb0991SDimitry Andric   for (; It != E; ++It) {
33468bcb0991SDimitry Andric     if (It->modifiesRegister(Reg, TRI))
33478bcb0991SDimitry Andric       return &*It;
33488bcb0991SDimitry Andric     if (It->readsRegister(Reg, TRI))
33498bcb0991SDimitry Andric       SeenIntermediateUse = true;
33508bcb0991SDimitry Andric   }
33518bcb0991SDimitry Andric   return nullptr;
33528bcb0991SDimitry Andric }
33538bcb0991SDimitry Andric 
335481ad6265SDimitry Andric void PPCInstrInfo::materializeImmPostRA(MachineBasicBlock &MBB,
335581ad6265SDimitry Andric                                         MachineBasicBlock::iterator MBBI,
335681ad6265SDimitry Andric                                         const DebugLoc &DL, Register Reg,
335781ad6265SDimitry Andric                                         int64_t Imm) const {
335881ad6265SDimitry Andric   assert(!MBB.getParent()->getRegInfo().isSSA() &&
335981ad6265SDimitry Andric          "Register should be in non-SSA form after RA");
336081ad6265SDimitry Andric   bool isPPC64 = Subtarget.isPPC64();
336181ad6265SDimitry Andric   // FIXME: Materialization here is not optimal.
336281ad6265SDimitry Andric   // For some special bit patterns we can use less instructions.
336381ad6265SDimitry Andric   // See `selectI64ImmDirect` in PPCISelDAGToDAG.cpp.
336481ad6265SDimitry Andric   if (isInt<16>(Imm)) {
336581ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(isPPC64 ? PPC::LI8 : PPC::LI), Reg).addImm(Imm);
336681ad6265SDimitry Andric   } else if (isInt<32>(Imm)) {
336781ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(isPPC64 ? PPC::LIS8 : PPC::LIS), Reg)
336881ad6265SDimitry Andric         .addImm(Imm >> 16);
336981ad6265SDimitry Andric     if (Imm & 0xFFFF)
337081ad6265SDimitry Andric       BuildMI(MBB, MBBI, DL, get(isPPC64 ? PPC::ORI8 : PPC::ORI), Reg)
337181ad6265SDimitry Andric           .addReg(Reg, RegState::Kill)
337281ad6265SDimitry Andric           .addImm(Imm & 0xFFFF);
337381ad6265SDimitry Andric   } else {
337481ad6265SDimitry Andric     assert(isPPC64 && "Materializing 64-bit immediate to single register is "
337581ad6265SDimitry Andric                       "only supported in PPC64");
337681ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(PPC::LIS8), Reg).addImm(Imm >> 48);
337781ad6265SDimitry Andric     if ((Imm >> 32) & 0xFFFF)
337881ad6265SDimitry Andric       BuildMI(MBB, MBBI, DL, get(PPC::ORI8), Reg)
337981ad6265SDimitry Andric           .addReg(Reg, RegState::Kill)
338081ad6265SDimitry Andric           .addImm((Imm >> 32) & 0xFFFF);
338181ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(PPC::RLDICR), Reg)
338281ad6265SDimitry Andric         .addReg(Reg, RegState::Kill)
338381ad6265SDimitry Andric         .addImm(32)
338481ad6265SDimitry Andric         .addImm(31);
338581ad6265SDimitry Andric     BuildMI(MBB, MBBI, DL, get(PPC::ORIS8), Reg)
338681ad6265SDimitry Andric         .addReg(Reg, RegState::Kill)
338781ad6265SDimitry Andric         .addImm((Imm >> 16) & 0xFFFF);
338881ad6265SDimitry Andric     if (Imm & 0xFFFF)
338981ad6265SDimitry Andric       BuildMI(MBB, MBBI, DL, get(PPC::ORI8), Reg)
339081ad6265SDimitry Andric           .addReg(Reg, RegState::Kill)
339181ad6265SDimitry Andric           .addImm(Imm & 0xFFFF);
339281ad6265SDimitry Andric   }
339381ad6265SDimitry Andric }
339481ad6265SDimitry Andric 
33950b57cec5SDimitry Andric MachineInstr *PPCInstrInfo::getForwardingDefMI(
33960b57cec5SDimitry Andric   MachineInstr &MI,
33970b57cec5SDimitry Andric   unsigned &OpNoForForwarding,
33980b57cec5SDimitry Andric   bool &SeenIntermediateUse) const {
33990b57cec5SDimitry Andric   OpNoForForwarding = ~0U;
34000b57cec5SDimitry Andric   MachineInstr *DefMI = nullptr;
34010b57cec5SDimitry Andric   MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
34020b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
34030b57cec5SDimitry Andric   // If we're in SSA, get the defs through the MRI. Otherwise, only look
34045ffd83dbSDimitry Andric   // within the basic block to see if the register is defined using an
34055ffd83dbSDimitry Andric   // LI/LI8/ADDI/ADDI8.
34060b57cec5SDimitry Andric   if (MRI->isSSA()) {
34070b57cec5SDimitry Andric     for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
34080b57cec5SDimitry Andric       if (!MI.getOperand(i).isReg())
34090b57cec5SDimitry Andric         continue;
34108bcb0991SDimitry Andric       Register Reg = MI.getOperand(i).getReg();
3411bdd1243dSDimitry Andric       if (!Reg.isVirtual())
34120b57cec5SDimitry Andric         continue;
341304eeddc0SDimitry Andric       Register TrueReg = TRI->lookThruCopyLike(Reg, MRI);
3414bdd1243dSDimitry Andric       if (TrueReg.isVirtual()) {
3415bdd1243dSDimitry Andric         MachineInstr *DefMIForTrueReg = MRI->getVRegDef(TrueReg);
3416bdd1243dSDimitry Andric         if (DefMIForTrueReg->getOpcode() == PPC::LI ||
3417bdd1243dSDimitry Andric             DefMIForTrueReg->getOpcode() == PPC::LI8 ||
3418bdd1243dSDimitry Andric             DefMIForTrueReg->getOpcode() == PPC::ADDI ||
3419bdd1243dSDimitry Andric             DefMIForTrueReg->getOpcode() == PPC::ADDI8) {
34200b57cec5SDimitry Andric           OpNoForForwarding = i;
3421bdd1243dSDimitry Andric           DefMI = DefMIForTrueReg;
34225ffd83dbSDimitry Andric           // The ADDI and LI operand maybe exist in one instruction at same
34235ffd83dbSDimitry Andric           // time. we prefer to fold LI operand as LI only has one Imm operand
34245ffd83dbSDimitry Andric           // and is more possible to be converted. So if current DefMI is
34255ffd83dbSDimitry Andric           // ADDI/ADDI8, we continue to find possible LI/LI8.
34265ffd83dbSDimitry Andric           if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)
34270b57cec5SDimitry Andric             break;
34280b57cec5SDimitry Andric         }
34290b57cec5SDimitry Andric       }
34300b57cec5SDimitry Andric     }
34310b57cec5SDimitry Andric   } else {
34320b57cec5SDimitry Andric     // Looking back through the definition for each operand could be expensive,
34330b57cec5SDimitry Andric     // so exit early if this isn't an instruction that either has an immediate
34340b57cec5SDimitry Andric     // form or is already an immediate form that we can handle.
34350b57cec5SDimitry Andric     ImmInstrInfo III;
34360b57cec5SDimitry Andric     unsigned Opc = MI.getOpcode();
34370b57cec5SDimitry Andric     bool ConvertibleImmForm =
3438480093f4SDimitry Andric         Opc == PPC::CMPWI || Opc == PPC::CMPLWI || Opc == PPC::CMPDI ||
3439480093f4SDimitry Andric         Opc == PPC::CMPLDI || Opc == PPC::ADDI || Opc == PPC::ADDI8 ||
3440480093f4SDimitry Andric         Opc == PPC::ORI || Opc == PPC::ORI8 || Opc == PPC::XORI ||
3441480093f4SDimitry Andric         Opc == PPC::XORI8 || Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec ||
34420b57cec5SDimitry Andric         Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||
3443480093f4SDimitry Andric         Opc == PPC::RLWINM || Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8 ||
3444480093f4SDimitry Andric         Opc == PPC::RLWINM8_rec;
34458bcb0991SDimitry Andric     bool IsVFReg = (MI.getNumOperands() && MI.getOperand(0).isReg())
34465f757f3fSDimitry Andric                        ? PPC::isVFRegister(MI.getOperand(0).getReg())
34478bcb0991SDimitry Andric                        : false;
34488bcb0991SDimitry Andric     if (!ConvertibleImmForm && !instrHasImmForm(Opc, IsVFReg, III, true))
34490b57cec5SDimitry Andric       return nullptr;
34500b57cec5SDimitry Andric 
34510b57cec5SDimitry Andric     // Don't convert or %X, %Y, %Y since that's just a register move.
34520b57cec5SDimitry Andric     if ((Opc == PPC::OR || Opc == PPC::OR8) &&
34530b57cec5SDimitry Andric         MI.getOperand(1).getReg() == MI.getOperand(2).getReg())
34540b57cec5SDimitry Andric       return nullptr;
34550b57cec5SDimitry Andric     for (int i = 1, e = MI.getNumOperands(); i < e; i++) {
34560b57cec5SDimitry Andric       MachineOperand &MO = MI.getOperand(i);
34570b57cec5SDimitry Andric       SeenIntermediateUse = false;
34580b57cec5SDimitry Andric       if (MO.isReg() && MO.isUse() && !MO.isImplicit()) {
34598bcb0991SDimitry Andric         Register Reg = MI.getOperand(i).getReg();
34608bcb0991SDimitry Andric         // If we see another use of this reg between the def and the MI,
3461bdd1243dSDimitry Andric         // we want to flag it so the def isn't deleted.
34628bcb0991SDimitry Andric         MachineInstr *DefMI = getDefMIPostRA(Reg, MI, SeenIntermediateUse);
34638bcb0991SDimitry Andric         if (DefMI) {
34640b57cec5SDimitry Andric           // Is this register defined by some form of add-immediate (including
34650b57cec5SDimitry Andric           // load-immediate) within this basic block?
34668bcb0991SDimitry Andric           switch (DefMI->getOpcode()) {
34678bcb0991SDimitry Andric           default:
34688bcb0991SDimitry Andric             break;
34690b57cec5SDimitry Andric           case PPC::LI:
34700b57cec5SDimitry Andric           case PPC::LI8:
34710fca6ea1SDimitry Andric           case PPC::ADDItocL8:
34720b57cec5SDimitry Andric           case PPC::ADDI:
34730b57cec5SDimitry Andric           case PPC::ADDI8:
34740b57cec5SDimitry Andric             OpNoForForwarding = i;
34758bcb0991SDimitry Andric             return DefMI;
34760b57cec5SDimitry Andric           }
34770b57cec5SDimitry Andric         }
34780b57cec5SDimitry Andric       }
34790b57cec5SDimitry Andric     }
34800b57cec5SDimitry Andric   }
34810b57cec5SDimitry Andric   return OpNoForForwarding == ~0U ? nullptr : DefMI;
34820b57cec5SDimitry Andric }
34830b57cec5SDimitry Andric 
34845ffd83dbSDimitry Andric unsigned PPCInstrInfo::getSpillTarget() const {
3485e8d8bef9SDimitry Andric   // With P10, we may need to spill paired vector registers or accumulator
3486e8d8bef9SDimitry Andric   // registers. MMA implies paired vectors, so we can just check that.
3487e8d8bef9SDimitry Andric   bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3488*36b606aeSDimitry Andric   // P11 uses the P10 target.
3489bdd1243dSDimitry Andric   return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3490bdd1243dSDimitry Andric                                    2 : Subtarget.hasP9Vector() ?
3491bdd1243dSDimitry Andric                                    1 : 0;
34925ffd83dbSDimitry Andric }
34930b57cec5SDimitry Andric 
3494bdd1243dSDimitry Andric ArrayRef<unsigned> PPCInstrInfo::getStoreOpcodesForSpillArray() const {
3495bdd1243dSDimitry Andric   return {StoreSpillOpcodesArray[getSpillTarget()], SOK_LastOpcodeSpill};
34960b57cec5SDimitry Andric }
34970b57cec5SDimitry Andric 
3498bdd1243dSDimitry Andric ArrayRef<unsigned> PPCInstrInfo::getLoadOpcodesForSpillArray() const {
3499bdd1243dSDimitry Andric   return {LoadSpillOpcodesArray[getSpillTarget()], SOK_LastOpcodeSpill};
35000b57cec5SDimitry Andric }
35010b57cec5SDimitry Andric 
3502480093f4SDimitry Andric // This opt tries to convert the following imm form to an index form to save an
3503480093f4SDimitry Andric // add for stack variables.
3504480093f4SDimitry Andric // Return false if no such pattern found.
3505480093f4SDimitry Andric //
3506480093f4SDimitry Andric // ADDI instr: ToBeChangedReg = ADDI FrameBaseReg, OffsetAddi
3507480093f4SDimitry Andric // ADD instr:  ToBeDeletedReg = ADD ToBeChangedReg(killed), ScaleReg
3508480093f4SDimitry Andric // Imm instr:  Reg            = op OffsetImm, ToBeDeletedReg(killed)
3509480093f4SDimitry Andric //
3510480093f4SDimitry Andric // can be converted to:
3511480093f4SDimitry Andric //
3512480093f4SDimitry Andric // new ADDI instr: ToBeChangedReg = ADDI FrameBaseReg, (OffsetAddi + OffsetImm)
3513480093f4SDimitry Andric // Index instr:    Reg            = opx ScaleReg, ToBeChangedReg(killed)
3514480093f4SDimitry Andric //
3515480093f4SDimitry Andric // In order to eliminate ADD instr, make sure that:
3516480093f4SDimitry Andric // 1: (OffsetAddi + OffsetImm) must be int16 since this offset will be used in
3517480093f4SDimitry Andric //    new ADDI instr and ADDI can only take int16 Imm.
3518480093f4SDimitry Andric // 2: ToBeChangedReg must be killed in ADD instr and there is no other use
3519480093f4SDimitry Andric //    between ADDI and ADD instr since its original def in ADDI will be changed
3520480093f4SDimitry Andric //    in new ADDI instr. And also there should be no new def for it between
3521480093f4SDimitry Andric //    ADD and Imm instr as ToBeChangedReg will be used in Index instr.
3522480093f4SDimitry Andric // 3: ToBeDeletedReg must be killed in Imm instr and there is no other use
3523480093f4SDimitry Andric //    between ADD and Imm instr since ADD instr will be eliminated.
3524480093f4SDimitry Andric // 4: ScaleReg must not be redefined between ADD and Imm instr since it will be
3525480093f4SDimitry Andric //    moved to Index instr.
3526480093f4SDimitry Andric bool PPCInstrInfo::foldFrameOffset(MachineInstr &MI) const {
3527480093f4SDimitry Andric   MachineFunction *MF = MI.getParent()->getParent();
3528480093f4SDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
3529480093f4SDimitry Andric   bool PostRA = !MRI->isSSA();
3530480093f4SDimitry Andric   // Do this opt after PEI which is after RA. The reason is stack slot expansion
3531480093f4SDimitry Andric   // in PEI may expose such opportunities since in PEI, stack slot offsets to
3532480093f4SDimitry Andric   // frame base(OffsetAddi) are determined.
3533480093f4SDimitry Andric   if (!PostRA)
3534480093f4SDimitry Andric     return false;
3535480093f4SDimitry Andric   unsigned ToBeDeletedReg = 0;
3536480093f4SDimitry Andric   int64_t OffsetImm = 0;
3537480093f4SDimitry Andric   unsigned XFormOpcode = 0;
3538480093f4SDimitry Andric   ImmInstrInfo III;
3539480093f4SDimitry Andric 
3540480093f4SDimitry Andric   // Check if Imm instr meets requirement.
3541480093f4SDimitry Andric   if (!isImmInstrEligibleForFolding(MI, ToBeDeletedReg, XFormOpcode, OffsetImm,
3542480093f4SDimitry Andric                                     III))
3543480093f4SDimitry Andric     return false;
3544480093f4SDimitry Andric 
3545480093f4SDimitry Andric   bool OtherIntermediateUse = false;
3546480093f4SDimitry Andric   MachineInstr *ADDMI = getDefMIPostRA(ToBeDeletedReg, MI, OtherIntermediateUse);
3547480093f4SDimitry Andric 
3548480093f4SDimitry Andric   // Exit if there is other use between ADD and Imm instr or no def found.
3549480093f4SDimitry Andric   if (OtherIntermediateUse || !ADDMI)
3550480093f4SDimitry Andric     return false;
3551480093f4SDimitry Andric 
3552480093f4SDimitry Andric   // Check if ADD instr meets requirement.
3553480093f4SDimitry Andric   if (!isADDInstrEligibleForFolding(*ADDMI))
3554480093f4SDimitry Andric     return false;
3555480093f4SDimitry Andric 
3556480093f4SDimitry Andric   unsigned ScaleRegIdx = 0;
3557480093f4SDimitry Andric   int64_t OffsetAddi = 0;
3558480093f4SDimitry Andric   MachineInstr *ADDIMI = nullptr;
3559480093f4SDimitry Andric 
3560480093f4SDimitry Andric   // Check if there is a valid ToBeChangedReg in ADDMI.
3561480093f4SDimitry Andric   // 1: It must be killed.
3562480093f4SDimitry Andric   // 2: Its definition must be a valid ADDIMI.
3563480093f4SDimitry Andric   // 3: It must satify int16 offset requirement.
3564480093f4SDimitry Andric   if (isValidToBeChangedReg(ADDMI, 1, ADDIMI, OffsetAddi, OffsetImm))
3565480093f4SDimitry Andric     ScaleRegIdx = 2;
3566480093f4SDimitry Andric   else if (isValidToBeChangedReg(ADDMI, 2, ADDIMI, OffsetAddi, OffsetImm))
3567480093f4SDimitry Andric     ScaleRegIdx = 1;
3568480093f4SDimitry Andric   else
3569480093f4SDimitry Andric     return false;
3570480093f4SDimitry Andric 
3571480093f4SDimitry Andric   assert(ADDIMI && "There should be ADDIMI for valid ToBeChangedReg.");
357204eeddc0SDimitry Andric   Register ToBeChangedReg = ADDIMI->getOperand(0).getReg();
357304eeddc0SDimitry Andric   Register ScaleReg = ADDMI->getOperand(ScaleRegIdx).getReg();
3574480093f4SDimitry Andric   auto NewDefFor = [&](unsigned Reg, MachineBasicBlock::iterator Start,
3575480093f4SDimitry Andric                        MachineBasicBlock::iterator End) {
3576480093f4SDimitry Andric     for (auto It = ++Start; It != End; It++)
3577480093f4SDimitry Andric       if (It->modifiesRegister(Reg, &getRegisterInfo()))
3578480093f4SDimitry Andric         return true;
3579480093f4SDimitry Andric     return false;
3580480093f4SDimitry Andric   };
35815ffd83dbSDimitry Andric 
35825ffd83dbSDimitry Andric   // We are trying to replace the ImmOpNo with ScaleReg. Give up if it is
35835ffd83dbSDimitry Andric   // treated as special zero when ScaleReg is R0/X0 register.
35845ffd83dbSDimitry Andric   if (III.ZeroIsSpecialOrig == III.ImmOpNo &&
35855ffd83dbSDimitry Andric       (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
35865ffd83dbSDimitry Andric     return false;
35875ffd83dbSDimitry Andric 
3588480093f4SDimitry Andric   // Make sure no other def for ToBeChangedReg and ScaleReg between ADD Instr
3589480093f4SDimitry Andric   // and Imm Instr.
3590480093f4SDimitry Andric   if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI))
3591480093f4SDimitry Andric     return false;
3592480093f4SDimitry Andric 
3593480093f4SDimitry Andric   // Now start to do the transformation.
3594480093f4SDimitry Andric   LLVM_DEBUG(dbgs() << "Replace instruction: "
3595480093f4SDimitry Andric                     << "\n");
3596480093f4SDimitry Andric   LLVM_DEBUG(ADDIMI->dump());
3597480093f4SDimitry Andric   LLVM_DEBUG(ADDMI->dump());
3598480093f4SDimitry Andric   LLVM_DEBUG(MI.dump());
3599480093f4SDimitry Andric   LLVM_DEBUG(dbgs() << "with: "
3600480093f4SDimitry Andric                     << "\n");
3601480093f4SDimitry Andric 
3602480093f4SDimitry Andric   // Update ADDI instr.
3603480093f4SDimitry Andric   ADDIMI->getOperand(2).setImm(OffsetAddi + OffsetImm);
3604480093f4SDimitry Andric 
3605480093f4SDimitry Andric   // Update Imm instr.
3606480093f4SDimitry Andric   MI.setDesc(get(XFormOpcode));
3607480093f4SDimitry Andric   MI.getOperand(III.ImmOpNo)
3608480093f4SDimitry Andric       .ChangeToRegister(ScaleReg, false, false,
3609480093f4SDimitry Andric                         ADDMI->getOperand(ScaleRegIdx).isKill());
3610480093f4SDimitry Andric 
3611480093f4SDimitry Andric   MI.getOperand(III.OpNoForForwarding)
3612480093f4SDimitry Andric       .ChangeToRegister(ToBeChangedReg, false, false, true);
3613480093f4SDimitry Andric 
3614480093f4SDimitry Andric   // Eliminate ADD instr.
3615480093f4SDimitry Andric   ADDMI->eraseFromParent();
3616480093f4SDimitry Andric 
3617480093f4SDimitry Andric   LLVM_DEBUG(ADDIMI->dump());
3618480093f4SDimitry Andric   LLVM_DEBUG(MI.dump());
3619480093f4SDimitry Andric 
3620480093f4SDimitry Andric   return true;
3621480093f4SDimitry Andric }
3622480093f4SDimitry Andric 
3623480093f4SDimitry Andric bool PPCInstrInfo::isADDIInstrEligibleForFolding(MachineInstr &ADDIMI,
3624480093f4SDimitry Andric                                                  int64_t &Imm) const {
3625480093f4SDimitry Andric   unsigned Opc = ADDIMI.getOpcode();
3626480093f4SDimitry Andric 
3627480093f4SDimitry Andric   // Exit if the instruction is not ADDI.
3628480093f4SDimitry Andric   if (Opc != PPC::ADDI && Opc != PPC::ADDI8)
3629480093f4SDimitry Andric     return false;
3630480093f4SDimitry Andric 
36310946e70aSDimitry Andric   // The operand may not necessarily be an immediate - it could be a relocation.
36320946e70aSDimitry Andric   if (!ADDIMI.getOperand(2).isImm())
36330946e70aSDimitry Andric     return false;
36340946e70aSDimitry Andric 
3635480093f4SDimitry Andric   Imm = ADDIMI.getOperand(2).getImm();
3636480093f4SDimitry Andric 
3637480093f4SDimitry Andric   return true;
3638480093f4SDimitry Andric }
3639480093f4SDimitry Andric 
3640480093f4SDimitry Andric bool PPCInstrInfo::isADDInstrEligibleForFolding(MachineInstr &ADDMI) const {
3641480093f4SDimitry Andric   unsigned Opc = ADDMI.getOpcode();
3642480093f4SDimitry Andric 
3643480093f4SDimitry Andric   // Exit if the instruction is not ADD.
3644480093f4SDimitry Andric   return Opc == PPC::ADD4 || Opc == PPC::ADD8;
3645480093f4SDimitry Andric }
3646480093f4SDimitry Andric 
3647480093f4SDimitry Andric bool PPCInstrInfo::isImmInstrEligibleForFolding(MachineInstr &MI,
3648480093f4SDimitry Andric                                                 unsigned &ToBeDeletedReg,
3649480093f4SDimitry Andric                                                 unsigned &XFormOpcode,
3650480093f4SDimitry Andric                                                 int64_t &OffsetImm,
3651480093f4SDimitry Andric                                                 ImmInstrInfo &III) const {
3652480093f4SDimitry Andric   // Only handle load/store.
3653480093f4SDimitry Andric   if (!MI.mayLoadOrStore())
3654480093f4SDimitry Andric     return false;
3655480093f4SDimitry Andric 
3656480093f4SDimitry Andric   unsigned Opc = MI.getOpcode();
3657480093f4SDimitry Andric 
3658480093f4SDimitry Andric   XFormOpcode = RI.getMappedIdxOpcForImmOpc(Opc);
3659480093f4SDimitry Andric 
3660480093f4SDimitry Andric   // Exit if instruction has no index form.
3661480093f4SDimitry Andric   if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3662480093f4SDimitry Andric     return false;
3663480093f4SDimitry Andric 
3664480093f4SDimitry Andric   // TODO: sync the logic between instrHasImmForm() and ImmToIdxMap.
36655f757f3fSDimitry Andric   if (!instrHasImmForm(XFormOpcode,
36665f757f3fSDimitry Andric                        PPC::isVFRegister(MI.getOperand(0).getReg()), III, true))
3667480093f4SDimitry Andric     return false;
3668480093f4SDimitry Andric 
3669480093f4SDimitry Andric   if (!III.IsSummingOperands)
3670480093f4SDimitry Andric     return false;
3671480093f4SDimitry Andric 
3672480093f4SDimitry Andric   MachineOperand ImmOperand = MI.getOperand(III.ImmOpNo);
3673480093f4SDimitry Andric   MachineOperand RegOperand = MI.getOperand(III.OpNoForForwarding);
3674480093f4SDimitry Andric   // Only support imm operands, not relocation slots or others.
3675480093f4SDimitry Andric   if (!ImmOperand.isImm())
3676480093f4SDimitry Andric     return false;
3677480093f4SDimitry Andric 
3678480093f4SDimitry Andric   assert(RegOperand.isReg() && "Instruction format is not right");
3679480093f4SDimitry Andric 
3680480093f4SDimitry Andric   // There are other use for ToBeDeletedReg after Imm instr, can not delete it.
3681480093f4SDimitry Andric   if (!RegOperand.isKill())
3682480093f4SDimitry Andric     return false;
3683480093f4SDimitry Andric 
3684480093f4SDimitry Andric   ToBeDeletedReg = RegOperand.getReg();
3685480093f4SDimitry Andric   OffsetImm = ImmOperand.getImm();
3686480093f4SDimitry Andric 
3687480093f4SDimitry Andric   return true;
3688480093f4SDimitry Andric }
3689480093f4SDimitry Andric 
3690480093f4SDimitry Andric bool PPCInstrInfo::isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index,
3691480093f4SDimitry Andric                                          MachineInstr *&ADDIMI,
3692480093f4SDimitry Andric                                          int64_t &OffsetAddi,
3693480093f4SDimitry Andric                                          int64_t OffsetImm) const {
3694480093f4SDimitry Andric   assert((Index == 1 || Index == 2) && "Invalid operand index for add.");
3695480093f4SDimitry Andric   MachineOperand &MO = ADDMI->getOperand(Index);
3696480093f4SDimitry Andric 
3697480093f4SDimitry Andric   if (!MO.isKill())
3698480093f4SDimitry Andric     return false;
3699480093f4SDimitry Andric 
3700480093f4SDimitry Andric   bool OtherIntermediateUse = false;
3701480093f4SDimitry Andric 
3702480093f4SDimitry Andric   ADDIMI = getDefMIPostRA(MO.getReg(), *ADDMI, OtherIntermediateUse);
3703480093f4SDimitry Andric   // Currently handle only one "add + Imminstr" pair case, exit if other
3704480093f4SDimitry Andric   // intermediate use for ToBeChangedReg found.
3705480093f4SDimitry Andric   // TODO: handle the cases where there are other "add + Imminstr" pairs
3706480093f4SDimitry Andric   // with same offset in Imminstr which is like:
3707480093f4SDimitry Andric   //
3708480093f4SDimitry Andric   // ADDI instr: ToBeChangedReg  = ADDI FrameBaseReg, OffsetAddi
3709480093f4SDimitry Andric   // ADD instr1: ToBeDeletedReg1 = ADD ToBeChangedReg, ScaleReg1
3710480093f4SDimitry Andric   // Imm instr1: Reg1            = op1 OffsetImm, ToBeDeletedReg1(killed)
3711480093f4SDimitry Andric   // ADD instr2: ToBeDeletedReg2 = ADD ToBeChangedReg(killed), ScaleReg2
3712480093f4SDimitry Andric   // Imm instr2: Reg2            = op2 OffsetImm, ToBeDeletedReg2(killed)
3713480093f4SDimitry Andric   //
3714480093f4SDimitry Andric   // can be converted to:
3715480093f4SDimitry Andric   //
3716480093f4SDimitry Andric   // new ADDI instr: ToBeChangedReg = ADDI FrameBaseReg,
3717480093f4SDimitry Andric   //                                       (OffsetAddi + OffsetImm)
3718480093f4SDimitry Andric   // Index instr1:   Reg1           = opx1 ScaleReg1, ToBeChangedReg
3719480093f4SDimitry Andric   // Index instr2:   Reg2           = opx2 ScaleReg2, ToBeChangedReg(killed)
3720480093f4SDimitry Andric 
3721480093f4SDimitry Andric   if (OtherIntermediateUse || !ADDIMI)
3722480093f4SDimitry Andric     return false;
3723480093f4SDimitry Andric   // Check if ADDI instr meets requirement.
3724480093f4SDimitry Andric   if (!isADDIInstrEligibleForFolding(*ADDIMI, OffsetAddi))
3725480093f4SDimitry Andric     return false;
3726480093f4SDimitry Andric 
3727480093f4SDimitry Andric   if (isInt<16>(OffsetAddi + OffsetImm))
3728480093f4SDimitry Andric     return true;
3729480093f4SDimitry Andric   return false;
3730480093f4SDimitry Andric }
3731480093f4SDimitry Andric 
37320b57cec5SDimitry Andric // If this instruction has an immediate form and one of its operands is a
37330b57cec5SDimitry Andric // result of a load-immediate or an add-immediate, convert it to
37340b57cec5SDimitry Andric // the immediate form if the constant is in range.
37350b57cec5SDimitry Andric bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
37365f757f3fSDimitry Andric                                           SmallSet<Register, 4> &RegsToUpdate,
37370b57cec5SDimitry Andric                                           MachineInstr **KilledDef) const {
37380b57cec5SDimitry Andric   MachineFunction *MF = MI.getParent()->getParent();
37390b57cec5SDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
37400b57cec5SDimitry Andric   bool PostRA = !MRI->isSSA();
37410b57cec5SDimitry Andric   bool SeenIntermediateUse = true;
37420b57cec5SDimitry Andric   unsigned ForwardingOperand = ~0U;
37430b57cec5SDimitry Andric   MachineInstr *DefMI = getForwardingDefMI(MI, ForwardingOperand,
37440b57cec5SDimitry Andric                                            SeenIntermediateUse);
37450b57cec5SDimitry Andric   if (!DefMI)
37460b57cec5SDimitry Andric     return false;
37470b57cec5SDimitry Andric   assert(ForwardingOperand < MI.getNumOperands() &&
37480b57cec5SDimitry Andric          "The forwarding operand needs to be valid at this point");
37490b57cec5SDimitry Andric   bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
37500b57cec5SDimitry Andric   bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
37510b57cec5SDimitry Andric   if (KilledDef && KillFwdDefMI)
37520b57cec5SDimitry Andric     *KilledDef = DefMI;
37530b57cec5SDimitry Andric 
37545f757f3fSDimitry Andric   // Conservatively add defs from DefMI and defs/uses from MI to the set of
37555f757f3fSDimitry Andric   // registers that need their kill flags updated.
37565f757f3fSDimitry Andric   for (const MachineOperand &MO : DefMI->operands())
37575f757f3fSDimitry Andric     if (MO.isReg() && MO.isDef())
37585f757f3fSDimitry Andric       RegsToUpdate.insert(MO.getReg());
37595f757f3fSDimitry Andric   for (const MachineOperand &MO : MI.operands())
37605f757f3fSDimitry Andric     if (MO.isReg())
37615f757f3fSDimitry Andric       RegsToUpdate.insert(MO.getReg());
37625f757f3fSDimitry Andric 
37635ffd83dbSDimitry Andric   // If this is a imm instruction and its register operands is produced by ADDI,
37645ffd83dbSDimitry Andric   // put the imm into imm inst directly.
37655ffd83dbSDimitry Andric   if (RI.getMappedIdxOpcForImmOpc(MI.getOpcode()) !=
37665ffd83dbSDimitry Andric           PPC::INSTRUCTION_LIST_END &&
37675ffd83dbSDimitry Andric       transformToNewImmFormFedByAdd(MI, *DefMI, ForwardingOperand))
37685ffd83dbSDimitry Andric     return true;
37695ffd83dbSDimitry Andric 
37700b57cec5SDimitry Andric   ImmInstrInfo III;
37718bcb0991SDimitry Andric   bool IsVFReg = MI.getOperand(0).isReg()
37725f757f3fSDimitry Andric                      ? PPC::isVFRegister(MI.getOperand(0).getReg())
37738bcb0991SDimitry Andric                      : false;
37748bcb0991SDimitry Andric   bool HasImmForm = instrHasImmForm(MI.getOpcode(), IsVFReg, III, PostRA);
37750b57cec5SDimitry Andric   // If this is a reg+reg instruction that has a reg+imm form,
37760b57cec5SDimitry Andric   // and one of the operands is produced by an add-immediate,
37770b57cec5SDimitry Andric   // try to convert it.
37780b57cec5SDimitry Andric   if (HasImmForm &&
37790b57cec5SDimitry Andric       transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,
37800b57cec5SDimitry Andric                                  KillFwdDefMI))
37810b57cec5SDimitry Andric     return true;
37820b57cec5SDimitry Andric 
37830b57cec5SDimitry Andric   // If this is a reg+reg instruction that has a reg+imm form,
37840b57cec5SDimitry Andric   // and one of the operands is produced by LI, convert it now.
37855ffd83dbSDimitry Andric   if (HasImmForm &&
37865ffd83dbSDimitry Andric       transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))
37870b57cec5SDimitry Andric     return true;
37880b57cec5SDimitry Andric 
37895ffd83dbSDimitry Andric   // If this is not a reg+reg, but the DefMI is LI/LI8, check if its user MI
37905ffd83dbSDimitry Andric   // can be simpified to LI.
37915ffd83dbSDimitry Andric   if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))
37920b57cec5SDimitry Andric     return true;
37935ffd83dbSDimitry Andric 
37940b57cec5SDimitry Andric   return false;
37950b57cec5SDimitry Andric }
37960b57cec5SDimitry Andric 
3797e8d8bef9SDimitry Andric bool PPCInstrInfo::combineRLWINM(MachineInstr &MI,
3798e8d8bef9SDimitry Andric                                  MachineInstr **ToErase) const {
3799e8d8bef9SDimitry Andric   MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
380004eeddc0SDimitry Andric   Register FoldingReg = MI.getOperand(1).getReg();
3801bdd1243dSDimitry Andric   if (!FoldingReg.isVirtual())
3802e8d8bef9SDimitry Andric     return false;
3803e8d8bef9SDimitry Andric   MachineInstr *SrcMI = MRI->getVRegDef(FoldingReg);
3804e8d8bef9SDimitry Andric   if (SrcMI->getOpcode() != PPC::RLWINM &&
3805e8d8bef9SDimitry Andric       SrcMI->getOpcode() != PPC::RLWINM_rec &&
3806e8d8bef9SDimitry Andric       SrcMI->getOpcode() != PPC::RLWINM8 &&
3807e8d8bef9SDimitry Andric       SrcMI->getOpcode() != PPC::RLWINM8_rec)
3808e8d8bef9SDimitry Andric     return false;
3809e8d8bef9SDimitry Andric   assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&
3810e8d8bef9SDimitry Andric           MI.getOperand(4).isImm() && SrcMI->getOperand(2).isImm() &&
3811e8d8bef9SDimitry Andric           SrcMI->getOperand(3).isImm() && SrcMI->getOperand(4).isImm()) &&
3812e8d8bef9SDimitry Andric          "Invalid PPC::RLWINM Instruction!");
3813e8d8bef9SDimitry Andric   uint64_t SHSrc = SrcMI->getOperand(2).getImm();
3814e8d8bef9SDimitry Andric   uint64_t SHMI = MI.getOperand(2).getImm();
3815e8d8bef9SDimitry Andric   uint64_t MBSrc = SrcMI->getOperand(3).getImm();
3816e8d8bef9SDimitry Andric   uint64_t MBMI = MI.getOperand(3).getImm();
3817e8d8bef9SDimitry Andric   uint64_t MESrc = SrcMI->getOperand(4).getImm();
3818e8d8bef9SDimitry Andric   uint64_t MEMI = MI.getOperand(4).getImm();
3819e8d8bef9SDimitry Andric 
3820e8d8bef9SDimitry Andric   assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3821e8d8bef9SDimitry Andric          "Invalid PPC::RLWINM Instruction!");
3822e8d8bef9SDimitry Andric   // If MBMI is bigger than MEMI, we always can not get run of ones.
3823e8d8bef9SDimitry Andric   // RotatedSrcMask non-wrap:
3824e8d8bef9SDimitry Andric   //                 0........31|32........63
3825e8d8bef9SDimitry Andric   // RotatedSrcMask:   B---E        B---E
3826e8d8bef9SDimitry Andric   // MaskMI:         -----------|--E  B------
3827e8d8bef9SDimitry Andric   // Result:           -----          ---      (Bad candidate)
3828e8d8bef9SDimitry Andric   //
3829e8d8bef9SDimitry Andric   // RotatedSrcMask wrap:
3830e8d8bef9SDimitry Andric   //                 0........31|32........63
3831e8d8bef9SDimitry Andric   // RotatedSrcMask: --E   B----|--E    B----
3832e8d8bef9SDimitry Andric   // MaskMI:         -----------|--E  B------
3833e8d8bef9SDimitry Andric   // Result:         ---   -----|---    -----  (Bad candidate)
3834e8d8bef9SDimitry Andric   //
3835e8d8bef9SDimitry Andric   // One special case is RotatedSrcMask is a full set mask.
3836e8d8bef9SDimitry Andric   // RotatedSrcMask full:
3837e8d8bef9SDimitry Andric   //                 0........31|32........63
3838e8d8bef9SDimitry Andric   // RotatedSrcMask: ------EB---|-------EB---
3839e8d8bef9SDimitry Andric   // MaskMI:         -----------|--E  B------
3840e8d8bef9SDimitry Andric   // Result:         -----------|---  -------  (Good candidate)
3841e8d8bef9SDimitry Andric 
3842e8d8bef9SDimitry Andric   // Mark special case.
3843e8d8bef9SDimitry Andric   bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3844e8d8bef9SDimitry Andric 
3845e8d8bef9SDimitry Andric   // For other MBMI > MEMI cases, just return.
3846e8d8bef9SDimitry Andric   if ((MBMI > MEMI) && !SrcMaskFull)
3847e8d8bef9SDimitry Andric     return false;
3848e8d8bef9SDimitry Andric 
3849e8d8bef9SDimitry Andric   // Handle MBMI <= MEMI cases.
3850e8d8bef9SDimitry Andric   APInt MaskMI = APInt::getBitsSetWithWrap(32, 32 - MEMI - 1, 32 - MBMI);
3851e8d8bef9SDimitry Andric   // In MI, we only need low 32 bits of SrcMI, just consider about low 32
3852e8d8bef9SDimitry Andric   // bit of SrcMI mask. Note that in APInt, lowerest bit is at index 0,
3853e8d8bef9SDimitry Andric   // while in PowerPC ISA, lowerest bit is at index 63.
3854e8d8bef9SDimitry Andric   APInt MaskSrc = APInt::getBitsSetWithWrap(32, 32 - MESrc - 1, 32 - MBSrc);
3855e8d8bef9SDimitry Andric 
3856e8d8bef9SDimitry Andric   APInt RotatedSrcMask = MaskSrc.rotl(SHMI);
3857e8d8bef9SDimitry Andric   APInt FinalMask = RotatedSrcMask & MaskMI;
3858e8d8bef9SDimitry Andric   uint32_t NewMB, NewME;
3859e8d8bef9SDimitry Andric   bool Simplified = false;
3860e8d8bef9SDimitry Andric 
3861e8d8bef9SDimitry Andric   // If final mask is 0, MI result should be 0 too.
3862349cc55cSDimitry Andric   if (FinalMask.isZero()) {
3863e8d8bef9SDimitry Andric     bool Is64Bit =
3864e8d8bef9SDimitry Andric         (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);
3865e8d8bef9SDimitry Andric     Simplified = true;
3866e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "Replace Instr: ");
3867e8d8bef9SDimitry Andric     LLVM_DEBUG(MI.dump());
3868e8d8bef9SDimitry Andric 
3869e8d8bef9SDimitry Andric     if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {
3870e8d8bef9SDimitry Andric       // Replace MI with "LI 0"
387181ad6265SDimitry Andric       MI.removeOperand(4);
387281ad6265SDimitry Andric       MI.removeOperand(3);
387381ad6265SDimitry Andric       MI.removeOperand(2);
3874e8d8bef9SDimitry Andric       MI.getOperand(1).ChangeToImmediate(0);
3875e8d8bef9SDimitry Andric       MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));
3876e8d8bef9SDimitry Andric     } else {
3877e8d8bef9SDimitry Andric       // Replace MI with "ANDI_rec reg, 0"
387881ad6265SDimitry Andric       MI.removeOperand(4);
387981ad6265SDimitry Andric       MI.removeOperand(3);
3880e8d8bef9SDimitry Andric       MI.getOperand(2).setImm(0);
3881e8d8bef9SDimitry Andric       MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3882e8d8bef9SDimitry Andric       MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
3883e8d8bef9SDimitry Andric       if (SrcMI->getOperand(1).isKill()) {
3884e8d8bef9SDimitry Andric         MI.getOperand(1).setIsKill(true);
3885e8d8bef9SDimitry Andric         SrcMI->getOperand(1).setIsKill(false);
3886e8d8bef9SDimitry Andric       } else
3887e8d8bef9SDimitry Andric         // About to replace MI.getOperand(1), clear its kill flag.
3888e8d8bef9SDimitry Andric         MI.getOperand(1).setIsKill(false);
3889e8d8bef9SDimitry Andric     }
3890e8d8bef9SDimitry Andric 
3891e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "With: ");
3892e8d8bef9SDimitry Andric     LLVM_DEBUG(MI.dump());
3893e8d8bef9SDimitry Andric 
3894e8d8bef9SDimitry Andric   } else if ((isRunOfOnes((unsigned)(FinalMask.getZExtValue()), NewMB, NewME) &&
3895e8d8bef9SDimitry Andric               NewMB <= NewME) ||
3896e8d8bef9SDimitry Andric              SrcMaskFull) {
3897e8d8bef9SDimitry Andric     // Here we only handle MBMI <= MEMI case, so NewMB must be no bigger
3898e8d8bef9SDimitry Andric     // than NewME. Otherwise we get a 64 bit value after folding, but MI
3899e8d8bef9SDimitry Andric     // return a 32 bit value.
3900e8d8bef9SDimitry Andric     Simplified = true;
3901e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "Converting Instr: ");
3902e8d8bef9SDimitry Andric     LLVM_DEBUG(MI.dump());
3903e8d8bef9SDimitry Andric 
3904e8d8bef9SDimitry Andric     uint16_t NewSH = (SHSrc + SHMI) % 32;
3905e8d8bef9SDimitry Andric     MI.getOperand(2).setImm(NewSH);
3906e8d8bef9SDimitry Andric     // If SrcMI mask is full, no need to update MBMI and MEMI.
3907e8d8bef9SDimitry Andric     if (!SrcMaskFull) {
3908e8d8bef9SDimitry Andric       MI.getOperand(3).setImm(NewMB);
3909e8d8bef9SDimitry Andric       MI.getOperand(4).setImm(NewME);
3910e8d8bef9SDimitry Andric     }
3911e8d8bef9SDimitry Andric     MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg());
3912e8d8bef9SDimitry Andric     if (SrcMI->getOperand(1).isKill()) {
3913e8d8bef9SDimitry Andric       MI.getOperand(1).setIsKill(true);
3914e8d8bef9SDimitry Andric       SrcMI->getOperand(1).setIsKill(false);
3915e8d8bef9SDimitry Andric     } else
3916e8d8bef9SDimitry Andric       // About to replace MI.getOperand(1), clear its kill flag.
3917e8d8bef9SDimitry Andric       MI.getOperand(1).setIsKill(false);
3918e8d8bef9SDimitry Andric 
3919e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "To: ");
3920e8d8bef9SDimitry Andric     LLVM_DEBUG(MI.dump());
3921e8d8bef9SDimitry Andric   }
3922e8d8bef9SDimitry Andric   if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&
3923e8d8bef9SDimitry Andric       !SrcMI->hasImplicitDef()) {
3924e8d8bef9SDimitry Andric     // If FoldingReg has no non-debug use and it has no implicit def (it
3925e8d8bef9SDimitry Andric     // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI.
3926e8d8bef9SDimitry Andric     // Otherwise keep it.
3927e8d8bef9SDimitry Andric     *ToErase = SrcMI;
3928e8d8bef9SDimitry Andric     LLVM_DEBUG(dbgs() << "Delete dead instruction: ");
3929e8d8bef9SDimitry Andric     LLVM_DEBUG(SrcMI->dump());
3930e8d8bef9SDimitry Andric   }
3931e8d8bef9SDimitry Andric   return Simplified;
3932e8d8bef9SDimitry Andric }
3933e8d8bef9SDimitry Andric 
39348bcb0991SDimitry Andric bool PPCInstrInfo::instrHasImmForm(unsigned Opc, bool IsVFReg,
39350b57cec5SDimitry Andric                                    ImmInstrInfo &III, bool PostRA) const {
39360b57cec5SDimitry Andric   // The vast majority of the instructions would need their operand 2 replaced
39370b57cec5SDimitry Andric   // with an immediate when switching to the reg+imm form. A marked exception
39380b57cec5SDimitry Andric   // are the update form loads/stores for which a constant operand 2 would need
39390b57cec5SDimitry Andric   // to turn into a displacement and move operand 1 to the operand 2 position.
39400b57cec5SDimitry Andric   III.ImmOpNo = 2;
39410b57cec5SDimitry Andric   III.OpNoForForwarding = 2;
39420b57cec5SDimitry Andric   III.ImmWidth = 16;
39430b57cec5SDimitry Andric   III.ImmMustBeMultipleOf = 1;
39440b57cec5SDimitry Andric   III.TruncateImmTo = 0;
39450b57cec5SDimitry Andric   III.IsSummingOperands = false;
39460b57cec5SDimitry Andric   switch (Opc) {
39470b57cec5SDimitry Andric   default: return false;
39480b57cec5SDimitry Andric   case PPC::ADD4:
39490b57cec5SDimitry Andric   case PPC::ADD8:
39500b57cec5SDimitry Andric     III.SignedImm = true;
39510b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39520b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 1;
39530b57cec5SDimitry Andric     III.IsCommutative = true;
39540b57cec5SDimitry Andric     III.IsSummingOperands = true;
39550b57cec5SDimitry Andric     III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
39560b57cec5SDimitry Andric     break;
39570b57cec5SDimitry Andric   case PPC::ADDC:
39580b57cec5SDimitry Andric   case PPC::ADDC8:
39590b57cec5SDimitry Andric     III.SignedImm = true;
39600b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39610b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
39620b57cec5SDimitry Andric     III.IsCommutative = true;
39630b57cec5SDimitry Andric     III.IsSummingOperands = true;
39640b57cec5SDimitry Andric     III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
39650b57cec5SDimitry Andric     break;
3966480093f4SDimitry Andric   case PPC::ADDC_rec:
39670b57cec5SDimitry Andric     III.SignedImm = true;
39680b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39690b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
39700b57cec5SDimitry Andric     III.IsCommutative = true;
39710b57cec5SDimitry Andric     III.IsSummingOperands = true;
3972480093f4SDimitry Andric     III.ImmOpcode = PPC::ADDIC_rec;
39730b57cec5SDimitry Andric     break;
39740b57cec5SDimitry Andric   case PPC::SUBFC:
39750b57cec5SDimitry Andric   case PPC::SUBFC8:
39760b57cec5SDimitry Andric     III.SignedImm = true;
39770b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39780b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
39790b57cec5SDimitry Andric     III.IsCommutative = false;
39800b57cec5SDimitry Andric     III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
39810b57cec5SDimitry Andric     break;
39820b57cec5SDimitry Andric   case PPC::CMPW:
39830b57cec5SDimitry Andric   case PPC::CMPD:
39840b57cec5SDimitry Andric     III.SignedImm = true;
39850b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39860b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
39870b57cec5SDimitry Andric     III.IsCommutative = false;
39880b57cec5SDimitry Andric     III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
39890b57cec5SDimitry Andric     break;
39900b57cec5SDimitry Andric   case PPC::CMPLW:
39910b57cec5SDimitry Andric   case PPC::CMPLD:
39920b57cec5SDimitry Andric     III.SignedImm = false;
39930b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
39940b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
39950b57cec5SDimitry Andric     III.IsCommutative = false;
39960b57cec5SDimitry Andric     III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
39970b57cec5SDimitry Andric     break;
3998480093f4SDimitry Andric   case PPC::AND_rec:
3999480093f4SDimitry Andric   case PPC::AND8_rec:
40000b57cec5SDimitry Andric   case PPC::OR:
40010b57cec5SDimitry Andric   case PPC::OR8:
40020b57cec5SDimitry Andric   case PPC::XOR:
40030b57cec5SDimitry Andric   case PPC::XOR8:
40040b57cec5SDimitry Andric     III.SignedImm = false;
40050b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
40060b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
40070b57cec5SDimitry Andric     III.IsCommutative = true;
40080b57cec5SDimitry Andric     switch(Opc) {
40090b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
4010480093f4SDimitry Andric     case PPC::AND_rec:
4011480093f4SDimitry Andric       III.ImmOpcode = PPC::ANDI_rec;
4012480093f4SDimitry Andric       break;
4013480093f4SDimitry Andric     case PPC::AND8_rec:
4014480093f4SDimitry Andric       III.ImmOpcode = PPC::ANDI8_rec;
4015480093f4SDimitry Andric       break;
40160b57cec5SDimitry Andric     case PPC::OR: III.ImmOpcode = PPC::ORI; break;
40170b57cec5SDimitry Andric     case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;
40180b57cec5SDimitry Andric     case PPC::XOR: III.ImmOpcode = PPC::XORI; break;
40190b57cec5SDimitry Andric     case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;
40200b57cec5SDimitry Andric     }
40210b57cec5SDimitry Andric     break;
40220b57cec5SDimitry Andric   case PPC::RLWNM:
40230b57cec5SDimitry Andric   case PPC::RLWNM8:
4024480093f4SDimitry Andric   case PPC::RLWNM_rec:
4025480093f4SDimitry Andric   case PPC::RLWNM8_rec:
40260b57cec5SDimitry Andric   case PPC::SLW:
40270b57cec5SDimitry Andric   case PPC::SLW8:
4028480093f4SDimitry Andric   case PPC::SLW_rec:
4029480093f4SDimitry Andric   case PPC::SLW8_rec:
40300b57cec5SDimitry Andric   case PPC::SRW:
40310b57cec5SDimitry Andric   case PPC::SRW8:
4032480093f4SDimitry Andric   case PPC::SRW_rec:
4033480093f4SDimitry Andric   case PPC::SRW8_rec:
40340b57cec5SDimitry Andric   case PPC::SRAW:
4035480093f4SDimitry Andric   case PPC::SRAW_rec:
40360b57cec5SDimitry Andric     III.SignedImm = false;
40370b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
40380b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
40390b57cec5SDimitry Andric     III.IsCommutative = false;
40400b57cec5SDimitry Andric     // This isn't actually true, but the instructions ignore any of the
40410b57cec5SDimitry Andric     // upper bits, so any immediate loaded with an LI is acceptable.
40420b57cec5SDimitry Andric     // This does not apply to shift right algebraic because a value
40430b57cec5SDimitry Andric     // out of range will produce a -1/0.
40440b57cec5SDimitry Andric     III.ImmWidth = 16;
4045480093f4SDimitry Andric     if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 || Opc == PPC::RLWNM_rec ||
4046480093f4SDimitry Andric         Opc == PPC::RLWNM8_rec)
40470b57cec5SDimitry Andric       III.TruncateImmTo = 5;
40480b57cec5SDimitry Andric     else
40490b57cec5SDimitry Andric       III.TruncateImmTo = 6;
40500b57cec5SDimitry Andric     switch(Opc) {
40510b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
40520b57cec5SDimitry Andric     case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;
40530b57cec5SDimitry Andric     case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;
4054480093f4SDimitry Andric     case PPC::RLWNM_rec:
4055480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM_rec;
4056480093f4SDimitry Andric       break;
4057480093f4SDimitry Andric     case PPC::RLWNM8_rec:
4058480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM8_rec;
4059480093f4SDimitry Andric       break;
40600b57cec5SDimitry Andric     case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;
40610b57cec5SDimitry Andric     case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;
4062480093f4SDimitry Andric     case PPC::SLW_rec:
4063480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM_rec;
4064480093f4SDimitry Andric       break;
4065480093f4SDimitry Andric     case PPC::SLW8_rec:
4066480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM8_rec;
4067480093f4SDimitry Andric       break;
40680b57cec5SDimitry Andric     case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;
40690b57cec5SDimitry Andric     case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;
4070480093f4SDimitry Andric     case PPC::SRW_rec:
4071480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM_rec;
4072480093f4SDimitry Andric       break;
4073480093f4SDimitry Andric     case PPC::SRW8_rec:
4074480093f4SDimitry Andric       III.ImmOpcode = PPC::RLWINM8_rec;
4075480093f4SDimitry Andric       break;
40760b57cec5SDimitry Andric     case PPC::SRAW:
40770b57cec5SDimitry Andric       III.ImmWidth = 5;
40780b57cec5SDimitry Andric       III.TruncateImmTo = 0;
40790b57cec5SDimitry Andric       III.ImmOpcode = PPC::SRAWI;
40800b57cec5SDimitry Andric       break;
4081480093f4SDimitry Andric     case PPC::SRAW_rec:
40820b57cec5SDimitry Andric       III.ImmWidth = 5;
40830b57cec5SDimitry Andric       III.TruncateImmTo = 0;
4084480093f4SDimitry Andric       III.ImmOpcode = PPC::SRAWI_rec;
40850b57cec5SDimitry Andric       break;
40860b57cec5SDimitry Andric     }
40870b57cec5SDimitry Andric     break;
40880b57cec5SDimitry Andric   case PPC::RLDCL:
4089480093f4SDimitry Andric   case PPC::RLDCL_rec:
40900b57cec5SDimitry Andric   case PPC::RLDCR:
4091480093f4SDimitry Andric   case PPC::RLDCR_rec:
40920b57cec5SDimitry Andric   case PPC::SLD:
4093480093f4SDimitry Andric   case PPC::SLD_rec:
40940b57cec5SDimitry Andric   case PPC::SRD:
4095480093f4SDimitry Andric   case PPC::SRD_rec:
40960b57cec5SDimitry Andric   case PPC::SRAD:
4097480093f4SDimitry Andric   case PPC::SRAD_rec:
40980b57cec5SDimitry Andric     III.SignedImm = false;
40990b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 0;
41000b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 0;
41010b57cec5SDimitry Andric     III.IsCommutative = false;
41020b57cec5SDimitry Andric     // This isn't actually true, but the instructions ignore any of the
41030b57cec5SDimitry Andric     // upper bits, so any immediate loaded with an LI is acceptable.
41040b57cec5SDimitry Andric     // This does not apply to shift right algebraic because a value
41050b57cec5SDimitry Andric     // out of range will produce a -1/0.
41060b57cec5SDimitry Andric     III.ImmWidth = 16;
4107480093f4SDimitry Andric     if (Opc == PPC::RLDCL || Opc == PPC::RLDCL_rec || Opc == PPC::RLDCR ||
4108480093f4SDimitry Andric         Opc == PPC::RLDCR_rec)
41090b57cec5SDimitry Andric       III.TruncateImmTo = 6;
41100b57cec5SDimitry Andric     else
41110b57cec5SDimitry Andric       III.TruncateImmTo = 7;
41120b57cec5SDimitry Andric     switch(Opc) {
41130b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
41140b57cec5SDimitry Andric     case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;
4115480093f4SDimitry Andric     case PPC::RLDCL_rec:
4116480093f4SDimitry Andric       III.ImmOpcode = PPC::RLDICL_rec;
4117480093f4SDimitry Andric       break;
41180b57cec5SDimitry Andric     case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;
4119480093f4SDimitry Andric     case PPC::RLDCR_rec:
4120480093f4SDimitry Andric       III.ImmOpcode = PPC::RLDICR_rec;
4121480093f4SDimitry Andric       break;
41220b57cec5SDimitry Andric     case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;
4123480093f4SDimitry Andric     case PPC::SLD_rec:
4124480093f4SDimitry Andric       III.ImmOpcode = PPC::RLDICR_rec;
4125480093f4SDimitry Andric       break;
41260b57cec5SDimitry Andric     case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;
4127480093f4SDimitry Andric     case PPC::SRD_rec:
4128480093f4SDimitry Andric       III.ImmOpcode = PPC::RLDICL_rec;
4129480093f4SDimitry Andric       break;
41300b57cec5SDimitry Andric     case PPC::SRAD:
41310b57cec5SDimitry Andric       III.ImmWidth = 6;
41320b57cec5SDimitry Andric       III.TruncateImmTo = 0;
41330b57cec5SDimitry Andric       III.ImmOpcode = PPC::SRADI;
41340b57cec5SDimitry Andric        break;
4135480093f4SDimitry Andric     case PPC::SRAD_rec:
41360b57cec5SDimitry Andric       III.ImmWidth = 6;
41370b57cec5SDimitry Andric       III.TruncateImmTo = 0;
4138480093f4SDimitry Andric       III.ImmOpcode = PPC::SRADI_rec;
41390b57cec5SDimitry Andric       break;
41400b57cec5SDimitry Andric     }
41410b57cec5SDimitry Andric     break;
41420b57cec5SDimitry Andric   // Loads and stores:
41430b57cec5SDimitry Andric   case PPC::LBZX:
41440b57cec5SDimitry Andric   case PPC::LBZX8:
41450b57cec5SDimitry Andric   case PPC::LHZX:
41460b57cec5SDimitry Andric   case PPC::LHZX8:
41470b57cec5SDimitry Andric   case PPC::LHAX:
41480b57cec5SDimitry Andric   case PPC::LHAX8:
41490b57cec5SDimitry Andric   case PPC::LWZX:
41500b57cec5SDimitry Andric   case PPC::LWZX8:
41510b57cec5SDimitry Andric   case PPC::LWAX:
41520b57cec5SDimitry Andric   case PPC::LDX:
41530b57cec5SDimitry Andric   case PPC::LFSX:
41540b57cec5SDimitry Andric   case PPC::LFDX:
41550b57cec5SDimitry Andric   case PPC::STBX:
41560b57cec5SDimitry Andric   case PPC::STBX8:
41570b57cec5SDimitry Andric   case PPC::STHX:
41580b57cec5SDimitry Andric   case PPC::STHX8:
41590b57cec5SDimitry Andric   case PPC::STWX:
41600b57cec5SDimitry Andric   case PPC::STWX8:
41610b57cec5SDimitry Andric   case PPC::STDX:
41620b57cec5SDimitry Andric   case PPC::STFSX:
41630b57cec5SDimitry Andric   case PPC::STFDX:
41640b57cec5SDimitry Andric     III.SignedImm = true;
41650b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 1;
41660b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 2;
41670b57cec5SDimitry Andric     III.IsCommutative = true;
41680b57cec5SDimitry Andric     III.IsSummingOperands = true;
41690b57cec5SDimitry Andric     III.ImmOpNo = 1;
41700b57cec5SDimitry Andric     III.OpNoForForwarding = 2;
41710b57cec5SDimitry Andric     switch(Opc) {
41720b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
41730b57cec5SDimitry Andric     case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;
41740b57cec5SDimitry Andric     case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;
41750b57cec5SDimitry Andric     case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;
41760b57cec5SDimitry Andric     case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;
41770b57cec5SDimitry Andric     case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;
41780b57cec5SDimitry Andric     case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;
41790b57cec5SDimitry Andric     case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;
41800b57cec5SDimitry Andric     case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;
41810b57cec5SDimitry Andric     case PPC::LWAX:
41820b57cec5SDimitry Andric       III.ImmOpcode = PPC::LWA;
41830b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 4;
41840b57cec5SDimitry Andric       break;
41850b57cec5SDimitry Andric     case PPC::LDX: III.ImmOpcode = PPC::LD; III.ImmMustBeMultipleOf = 4; break;
41860b57cec5SDimitry Andric     case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;
41870b57cec5SDimitry Andric     case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;
41880b57cec5SDimitry Andric     case PPC::STBX: III.ImmOpcode = PPC::STB; break;
41890b57cec5SDimitry Andric     case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;
41900b57cec5SDimitry Andric     case PPC::STHX: III.ImmOpcode = PPC::STH; break;
41910b57cec5SDimitry Andric     case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;
41920b57cec5SDimitry Andric     case PPC::STWX: III.ImmOpcode = PPC::STW; break;
41930b57cec5SDimitry Andric     case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;
41940b57cec5SDimitry Andric     case PPC::STDX:
41950b57cec5SDimitry Andric       III.ImmOpcode = PPC::STD;
41960b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 4;
41970b57cec5SDimitry Andric       break;
41980b57cec5SDimitry Andric     case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;
41990b57cec5SDimitry Andric     case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;
42000b57cec5SDimitry Andric     }
42010b57cec5SDimitry Andric     break;
42020b57cec5SDimitry Andric   case PPC::LBZUX:
42030b57cec5SDimitry Andric   case PPC::LBZUX8:
42040b57cec5SDimitry Andric   case PPC::LHZUX:
42050b57cec5SDimitry Andric   case PPC::LHZUX8:
42060b57cec5SDimitry Andric   case PPC::LHAUX:
42070b57cec5SDimitry Andric   case PPC::LHAUX8:
42080b57cec5SDimitry Andric   case PPC::LWZUX:
42090b57cec5SDimitry Andric   case PPC::LWZUX8:
42100b57cec5SDimitry Andric   case PPC::LDUX:
42110b57cec5SDimitry Andric   case PPC::LFSUX:
42120b57cec5SDimitry Andric   case PPC::LFDUX:
42130b57cec5SDimitry Andric   case PPC::STBUX:
42140b57cec5SDimitry Andric   case PPC::STBUX8:
42150b57cec5SDimitry Andric   case PPC::STHUX:
42160b57cec5SDimitry Andric   case PPC::STHUX8:
42170b57cec5SDimitry Andric   case PPC::STWUX:
42180b57cec5SDimitry Andric   case PPC::STWUX8:
42190b57cec5SDimitry Andric   case PPC::STDUX:
42200b57cec5SDimitry Andric   case PPC::STFSUX:
42210b57cec5SDimitry Andric   case PPC::STFDUX:
42220b57cec5SDimitry Andric     III.SignedImm = true;
42230b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 2;
42240b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 3;
42250b57cec5SDimitry Andric     III.IsCommutative = false;
42260b57cec5SDimitry Andric     III.IsSummingOperands = true;
42270b57cec5SDimitry Andric     III.ImmOpNo = 2;
42280b57cec5SDimitry Andric     III.OpNoForForwarding = 3;
42290b57cec5SDimitry Andric     switch(Opc) {
42300b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
42310b57cec5SDimitry Andric     case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;
42320b57cec5SDimitry Andric     case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;
42330b57cec5SDimitry Andric     case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;
42340b57cec5SDimitry Andric     case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;
42350b57cec5SDimitry Andric     case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;
42360b57cec5SDimitry Andric     case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;
42370b57cec5SDimitry Andric     case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;
42380b57cec5SDimitry Andric     case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;
42390b57cec5SDimitry Andric     case PPC::LDUX:
42400b57cec5SDimitry Andric       III.ImmOpcode = PPC::LDU;
42410b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 4;
42420b57cec5SDimitry Andric       break;
42430b57cec5SDimitry Andric     case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;
42440b57cec5SDimitry Andric     case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;
42450b57cec5SDimitry Andric     case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;
42460b57cec5SDimitry Andric     case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;
42470b57cec5SDimitry Andric     case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;
42480b57cec5SDimitry Andric     case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;
42490b57cec5SDimitry Andric     case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;
42500b57cec5SDimitry Andric     case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;
42510b57cec5SDimitry Andric     case PPC::STDUX:
42520b57cec5SDimitry Andric       III.ImmOpcode = PPC::STDU;
42530b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 4;
42540b57cec5SDimitry Andric       break;
42550b57cec5SDimitry Andric     case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;
42560b57cec5SDimitry Andric     case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;
42570b57cec5SDimitry Andric     }
42580b57cec5SDimitry Andric     break;
42590b57cec5SDimitry Andric   // Power9 and up only. For some of these, the X-Form version has access to all
42600b57cec5SDimitry Andric   // 64 VSR's whereas the D-Form only has access to the VR's. We replace those
42610b57cec5SDimitry Andric   // with pseudo-ops pre-ra and for post-ra, we check that the register loaded
42620b57cec5SDimitry Andric   // into or stored from is one of the VR registers.
42630b57cec5SDimitry Andric   case PPC::LXVX:
42640b57cec5SDimitry Andric   case PPC::LXSSPX:
42650b57cec5SDimitry Andric   case PPC::LXSDX:
42660b57cec5SDimitry Andric   case PPC::STXVX:
42670b57cec5SDimitry Andric   case PPC::STXSSPX:
42680b57cec5SDimitry Andric   case PPC::STXSDX:
42690b57cec5SDimitry Andric   case PPC::XFLOADf32:
42700b57cec5SDimitry Andric   case PPC::XFLOADf64:
42710b57cec5SDimitry Andric   case PPC::XFSTOREf32:
42720b57cec5SDimitry Andric   case PPC::XFSTOREf64:
42730b57cec5SDimitry Andric     if (!Subtarget.hasP9Vector())
42740b57cec5SDimitry Andric       return false;
42750b57cec5SDimitry Andric     III.SignedImm = true;
42760b57cec5SDimitry Andric     III.ZeroIsSpecialOrig = 1;
42770b57cec5SDimitry Andric     III.ZeroIsSpecialNew = 2;
42780b57cec5SDimitry Andric     III.IsCommutative = true;
42790b57cec5SDimitry Andric     III.IsSummingOperands = true;
42800b57cec5SDimitry Andric     III.ImmOpNo = 1;
42810b57cec5SDimitry Andric     III.OpNoForForwarding = 2;
42820b57cec5SDimitry Andric     III.ImmMustBeMultipleOf = 4;
42830b57cec5SDimitry Andric     switch(Opc) {
42840b57cec5SDimitry Andric     default: llvm_unreachable("Unknown opcode");
42850b57cec5SDimitry Andric     case PPC::LXVX:
42860b57cec5SDimitry Andric       III.ImmOpcode = PPC::LXV;
42870b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 16;
42880b57cec5SDimitry Andric       break;
42890b57cec5SDimitry Andric     case PPC::LXSSPX:
42900b57cec5SDimitry Andric       if (PostRA) {
42918bcb0991SDimitry Andric         if (IsVFReg)
42920b57cec5SDimitry Andric           III.ImmOpcode = PPC::LXSSP;
42930b57cec5SDimitry Andric         else {
42940b57cec5SDimitry Andric           III.ImmOpcode = PPC::LFS;
42950b57cec5SDimitry Andric           III.ImmMustBeMultipleOf = 1;
42960b57cec5SDimitry Andric         }
42970b57cec5SDimitry Andric         break;
42980b57cec5SDimitry Andric       }
4299bdd1243dSDimitry Andric       [[fallthrough]];
43000b57cec5SDimitry Andric     case PPC::XFLOADf32:
43010b57cec5SDimitry Andric       III.ImmOpcode = PPC::DFLOADf32;
43020b57cec5SDimitry Andric       break;
43030b57cec5SDimitry Andric     case PPC::LXSDX:
43040b57cec5SDimitry Andric       if (PostRA) {
43058bcb0991SDimitry Andric         if (IsVFReg)
43060b57cec5SDimitry Andric           III.ImmOpcode = PPC::LXSD;
43070b57cec5SDimitry Andric         else {
43080b57cec5SDimitry Andric           III.ImmOpcode = PPC::LFD;
43090b57cec5SDimitry Andric           III.ImmMustBeMultipleOf = 1;
43100b57cec5SDimitry Andric         }
43110b57cec5SDimitry Andric         break;
43120b57cec5SDimitry Andric       }
4313bdd1243dSDimitry Andric       [[fallthrough]];
43140b57cec5SDimitry Andric     case PPC::XFLOADf64:
43150b57cec5SDimitry Andric       III.ImmOpcode = PPC::DFLOADf64;
43160b57cec5SDimitry Andric       break;
43170b57cec5SDimitry Andric     case PPC::STXVX:
43180b57cec5SDimitry Andric       III.ImmOpcode = PPC::STXV;
43190b57cec5SDimitry Andric       III.ImmMustBeMultipleOf = 16;
43200b57cec5SDimitry Andric       break;
43210b57cec5SDimitry Andric     case PPC::STXSSPX:
43220b57cec5SDimitry Andric       if (PostRA) {
43238bcb0991SDimitry Andric         if (IsVFReg)
43240b57cec5SDimitry Andric           III.ImmOpcode = PPC::STXSSP;
43250b57cec5SDimitry Andric         else {
43260b57cec5SDimitry Andric           III.ImmOpcode = PPC::STFS;
43270b57cec5SDimitry Andric           III.ImmMustBeMultipleOf = 1;
43280b57cec5SDimitry Andric         }
43290b57cec5SDimitry Andric         break;
43300b57cec5SDimitry Andric       }
4331bdd1243dSDimitry Andric       [[fallthrough]];
43320b57cec5SDimitry Andric     case PPC::XFSTOREf32:
43330b57cec5SDimitry Andric       III.ImmOpcode = PPC::DFSTOREf32;
43340b57cec5SDimitry Andric       break;
43350b57cec5SDimitry Andric     case PPC::STXSDX:
43360b57cec5SDimitry Andric       if (PostRA) {
43378bcb0991SDimitry Andric         if (IsVFReg)
43380b57cec5SDimitry Andric           III.ImmOpcode = PPC::STXSD;
43390b57cec5SDimitry Andric         else {
43400b57cec5SDimitry Andric           III.ImmOpcode = PPC::STFD;
43410b57cec5SDimitry Andric           III.ImmMustBeMultipleOf = 1;
43420b57cec5SDimitry Andric         }
43430b57cec5SDimitry Andric         break;
43440b57cec5SDimitry Andric       }
4345bdd1243dSDimitry Andric       [[fallthrough]];
43460b57cec5SDimitry Andric     case PPC::XFSTOREf64:
43470b57cec5SDimitry Andric       III.ImmOpcode = PPC::DFSTOREf64;
43480b57cec5SDimitry Andric       break;
43490b57cec5SDimitry Andric     }
43500b57cec5SDimitry Andric     break;
43510b57cec5SDimitry Andric   }
43520b57cec5SDimitry Andric   return true;
43530b57cec5SDimitry Andric }
43540b57cec5SDimitry Andric 
43550b57cec5SDimitry Andric // Utility function for swaping two arbitrary operands of an instruction.
43560b57cec5SDimitry Andric static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2) {
43570b57cec5SDimitry Andric   assert(Op1 != Op2 && "Cannot swap operand with itself.");
43580b57cec5SDimitry Andric 
43590b57cec5SDimitry Andric   unsigned MaxOp = std::max(Op1, Op2);
43600b57cec5SDimitry Andric   unsigned MinOp = std::min(Op1, Op2);
43610b57cec5SDimitry Andric   MachineOperand MOp1 = MI.getOperand(MinOp);
43620b57cec5SDimitry Andric   MachineOperand MOp2 = MI.getOperand(MaxOp);
436381ad6265SDimitry Andric   MI.removeOperand(std::max(Op1, Op2));
436481ad6265SDimitry Andric   MI.removeOperand(std::min(Op1, Op2));
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric   // If the operands we are swapping are the two at the end (the common case)
43670b57cec5SDimitry Andric   // we can just remove both and add them in the opposite order.
43680b57cec5SDimitry Andric   if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {
43690b57cec5SDimitry Andric     MI.addOperand(MOp2);
43700b57cec5SDimitry Andric     MI.addOperand(MOp1);
43710b57cec5SDimitry Andric   } else {
43720b57cec5SDimitry Andric     // Store all operands in a temporary vector, remove them and re-add in the
43730b57cec5SDimitry Andric     // right order.
43740b57cec5SDimitry Andric     SmallVector<MachineOperand, 2> MOps;
43750b57cec5SDimitry Andric     unsigned TotalOps = MI.getNumOperands() + 2; // We've already removed 2 ops.
43760b57cec5SDimitry Andric     for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {
43770b57cec5SDimitry Andric       MOps.push_back(MI.getOperand(i));
437881ad6265SDimitry Andric       MI.removeOperand(i);
43790b57cec5SDimitry Andric     }
43800b57cec5SDimitry Andric     // MOp2 needs to be added next.
43810b57cec5SDimitry Andric     MI.addOperand(MOp2);
43820b57cec5SDimitry Andric     // Now add the rest.
43830b57cec5SDimitry Andric     for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {
43840b57cec5SDimitry Andric       if (i == MaxOp)
43850b57cec5SDimitry Andric         MI.addOperand(MOp1);
43860b57cec5SDimitry Andric       else {
43870b57cec5SDimitry Andric         MI.addOperand(MOps.back());
43880b57cec5SDimitry Andric         MOps.pop_back();
43890b57cec5SDimitry Andric       }
43900b57cec5SDimitry Andric     }
43910b57cec5SDimitry Andric   }
43920b57cec5SDimitry Andric }
43930b57cec5SDimitry Andric 
43940b57cec5SDimitry Andric // Check if the 'MI' that has the index OpNoForForwarding
43950b57cec5SDimitry Andric // meets the requirement described in the ImmInstrInfo.
43960b57cec5SDimitry Andric bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,
43970b57cec5SDimitry Andric                                                const ImmInstrInfo &III,
43980b57cec5SDimitry Andric                                                unsigned OpNoForForwarding
43990b57cec5SDimitry Andric                                                ) const {
44000b57cec5SDimitry Andric   // As the algorithm of checking for PPC::ZERO/PPC::ZERO8
44010b57cec5SDimitry Andric   // would not work pre-RA, we can only do the check post RA.
44020b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
44030b57cec5SDimitry Andric   if (MRI.isSSA())
44040b57cec5SDimitry Andric     return false;
44050b57cec5SDimitry Andric 
44060b57cec5SDimitry Andric   // Cannot do the transform if MI isn't summing the operands.
44070b57cec5SDimitry Andric   if (!III.IsSummingOperands)
44080b57cec5SDimitry Andric     return false;
44090b57cec5SDimitry Andric 
44100b57cec5SDimitry Andric   // The instruction we are trying to replace must have the ZeroIsSpecialOrig set.
44110b57cec5SDimitry Andric   if (!III.ZeroIsSpecialOrig)
44120b57cec5SDimitry Andric     return false;
44130b57cec5SDimitry Andric 
44140b57cec5SDimitry Andric   // We cannot do the transform if the operand we are trying to replace
44150b57cec5SDimitry Andric   // isn't the same as the operand the instruction allows.
44160b57cec5SDimitry Andric   if (OpNoForForwarding != III.OpNoForForwarding)
44170b57cec5SDimitry Andric     return false;
44180b57cec5SDimitry Andric 
44190b57cec5SDimitry Andric   // Check if the instruction we are trying to transform really has
44200b57cec5SDimitry Andric   // the special zero register as its operand.
44210b57cec5SDimitry Andric   if (MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO &&
44220b57cec5SDimitry Andric       MI.getOperand(III.ZeroIsSpecialOrig).getReg() != PPC::ZERO8)
44230b57cec5SDimitry Andric     return false;
44240b57cec5SDimitry Andric 
44250b57cec5SDimitry Andric   // This machine instruction is convertible if it is,
44260b57cec5SDimitry Andric   // 1. summing the operands.
44270b57cec5SDimitry Andric   // 2. one of the operands is special zero register.
44280b57cec5SDimitry Andric   // 3. the operand we are trying to replace is allowed by the MI.
44290b57cec5SDimitry Andric   return true;
44300b57cec5SDimitry Andric }
44310b57cec5SDimitry Andric 
44320b57cec5SDimitry Andric // Check if the DefMI is the add inst and set the ImmMO and RegMO
44330b57cec5SDimitry Andric // accordingly.
44340b57cec5SDimitry Andric bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
44350b57cec5SDimitry Andric                                                const ImmInstrInfo &III,
44360b57cec5SDimitry Andric                                                MachineOperand *&ImmMO,
44370b57cec5SDimitry Andric                                                MachineOperand *&RegMO) const {
44380b57cec5SDimitry Andric   unsigned Opc = DefMI.getOpcode();
44390fca6ea1SDimitry Andric   if (Opc != PPC::ADDItocL8 && Opc != PPC::ADDI && Opc != PPC::ADDI8)
44400fca6ea1SDimitry Andric     return false;
44410fca6ea1SDimitry Andric 
44420fca6ea1SDimitry Andric   // Skip the optimization of transformTo[NewImm|Imm]FormFedByAdd for ADDItocL8
44430fca6ea1SDimitry Andric   // on AIX which is used for toc-data access. TODO: Follow up to see if it can
44440fca6ea1SDimitry Andric   // apply for AIX toc-data as well.
44450fca6ea1SDimitry Andric   if (Opc == PPC::ADDItocL8 && Subtarget.isAIX())
44460b57cec5SDimitry Andric     return false;
44470b57cec5SDimitry Andric 
44480b57cec5SDimitry Andric   assert(DefMI.getNumOperands() >= 3 &&
44490b57cec5SDimitry Andric          "Add inst must have at least three operands");
44500b57cec5SDimitry Andric   RegMO = &DefMI.getOperand(1);
44510b57cec5SDimitry Andric   ImmMO = &DefMI.getOperand(2);
44520b57cec5SDimitry Andric 
44535ffd83dbSDimitry Andric   // Before RA, ADDI first operand could be a frame index.
44545ffd83dbSDimitry Andric   if (!RegMO->isReg())
44555ffd83dbSDimitry Andric     return false;
44565ffd83dbSDimitry Andric 
44570b57cec5SDimitry Andric   // This DefMI is elgible for forwarding if it is:
44580b57cec5SDimitry Andric   // 1. add inst
44590b57cec5SDimitry Andric   // 2. one of the operands is Imm/CPI/Global.
44600b57cec5SDimitry Andric   return isAnImmediateOperand(*ImmMO);
44610b57cec5SDimitry Andric }
44620b57cec5SDimitry Andric 
44630b57cec5SDimitry Andric bool PPCInstrInfo::isRegElgibleForForwarding(
44640b57cec5SDimitry Andric     const MachineOperand &RegMO, const MachineInstr &DefMI,
44650b57cec5SDimitry Andric     const MachineInstr &MI, bool KillDefMI,
4466bdd1243dSDimitry Andric     bool &IsFwdFeederRegKilled, bool &SeenIntermediateUse) const {
44670b57cec5SDimitry Andric   // x = addi y, imm
44680b57cec5SDimitry Andric   // ...
44690b57cec5SDimitry Andric   // z = lfdx 0, x   -> z = lfd imm(y)
44700b57cec5SDimitry Andric   // The Reg "y" can be forwarded to the MI(z) only when there is no DEF
44710b57cec5SDimitry Andric   // of "y" between the DEF of "x" and "z".
44720b57cec5SDimitry Andric   // The query is only valid post RA.
44730b57cec5SDimitry Andric   const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
44740b57cec5SDimitry Andric   if (MRI.isSSA())
44750b57cec5SDimitry Andric     return false;
44760b57cec5SDimitry Andric 
44778bcb0991SDimitry Andric   Register Reg = RegMO.getReg();
44780b57cec5SDimitry Andric 
44790b57cec5SDimitry Andric   // Walking the inst in reverse(MI-->DefMI) to get the last DEF of the Reg.
44800b57cec5SDimitry Andric   MachineBasicBlock::const_reverse_iterator It = MI;
44810b57cec5SDimitry Andric   MachineBasicBlock::const_reverse_iterator E = MI.getParent()->rend();
44820b57cec5SDimitry Andric   It++;
44830b57cec5SDimitry Andric   for (; It != E; ++It) {
44840b57cec5SDimitry Andric     if (It->modifiesRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
44850b57cec5SDimitry Andric       return false;
44860b57cec5SDimitry Andric     else if (It->killsRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
44870b57cec5SDimitry Andric       IsFwdFeederRegKilled = true;
4488bdd1243dSDimitry Andric     if (It->readsRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
4489bdd1243dSDimitry Andric       SeenIntermediateUse = true;
44900b57cec5SDimitry Andric     // Made it to DefMI without encountering a clobber.
44910b57cec5SDimitry Andric     if ((&*It) == &DefMI)
44920b57cec5SDimitry Andric       break;
44930b57cec5SDimitry Andric   }
44940b57cec5SDimitry Andric   assert((&*It) == &DefMI && "DefMI is missing");
44950b57cec5SDimitry Andric 
44960b57cec5SDimitry Andric   // If DefMI also defines the register to be forwarded, we can only forward it
44970b57cec5SDimitry Andric   // if DefMI is being erased.
44980b57cec5SDimitry Andric   if (DefMI.modifiesRegister(Reg, &getRegisterInfo()))
44990b57cec5SDimitry Andric     return KillDefMI;
45000b57cec5SDimitry Andric 
45010b57cec5SDimitry Andric   return true;
45020b57cec5SDimitry Andric }
45030b57cec5SDimitry Andric 
45040b57cec5SDimitry Andric bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
45050b57cec5SDimitry Andric                                              const MachineInstr &DefMI,
45060b57cec5SDimitry Andric                                              const ImmInstrInfo &III,
45075ffd83dbSDimitry Andric                                              int64_t &Imm,
45085ffd83dbSDimitry Andric                                              int64_t BaseImm) const {
45090b57cec5SDimitry Andric   assert(isAnImmediateOperand(ImmMO) && "ImmMO is NOT an immediate");
45100fca6ea1SDimitry Andric   if (DefMI.getOpcode() == PPC::ADDItocL8) {
45110fca6ea1SDimitry Andric     // The operand for ADDItocL8 is CPI, which isn't imm at compiling time,
45120b57cec5SDimitry Andric     // However, we know that, it is 16-bit width, and has the alignment of 4.
45130b57cec5SDimitry Andric     // Check if the instruction met the requirement.
45140b57cec5SDimitry Andric     if (III.ImmMustBeMultipleOf > 4 ||
45150b57cec5SDimitry Andric        III.TruncateImmTo || III.ImmWidth != 16)
45160b57cec5SDimitry Andric       return false;
45170b57cec5SDimitry Andric 
45180b57cec5SDimitry Andric     // Going from XForm to DForm loads means that the displacement needs to be
45190b57cec5SDimitry Andric     // not just an immediate but also a multiple of 4, or 16 depending on the
45200b57cec5SDimitry Andric     // load. A DForm load cannot be represented if it is a multiple of say 2.
45210b57cec5SDimitry Andric     // XForm loads do not have this restriction.
45225ffd83dbSDimitry Andric     if (ImmMO.isGlobal()) {
45230fca6ea1SDimitry Andric       const DataLayout &DL = ImmMO.getGlobal()->getDataLayout();
45245ffd83dbSDimitry Andric       if (ImmMO.getGlobal()->getPointerAlignment(DL) < III.ImmMustBeMultipleOf)
45250b57cec5SDimitry Andric         return false;
45265ffd83dbSDimitry Andric     }
45270b57cec5SDimitry Andric 
45280b57cec5SDimitry Andric     return true;
45290b57cec5SDimitry Andric   }
45300b57cec5SDimitry Andric 
45310b57cec5SDimitry Andric   if (ImmMO.isImm()) {
45320b57cec5SDimitry Andric     // It is Imm, we need to check if the Imm fit the range.
45330b57cec5SDimitry Andric     // Sign-extend to 64-bits.
45345ffd83dbSDimitry Andric     // DefMI may be folded with another imm form instruction, the result Imm is
45355ffd83dbSDimitry Andric     // the sum of Imm of DefMI and BaseImm which is from imm form instruction.
4536fe6060f1SDimitry Andric     APInt ActualValue(64, ImmMO.getImm() + BaseImm, true);
4537fe6060f1SDimitry Andric     if (III.SignedImm && !ActualValue.isSignedIntN(III.ImmWidth))
4538fe6060f1SDimitry Andric       return false;
4539fe6060f1SDimitry Andric     if (!III.SignedImm && !ActualValue.isIntN(III.ImmWidth))
4540fe6060f1SDimitry Andric       return false;
45415ffd83dbSDimitry Andric     Imm = SignExtend64<16>(ImmMO.getImm() + BaseImm);
45420b57cec5SDimitry Andric 
45430b57cec5SDimitry Andric     if (Imm % III.ImmMustBeMultipleOf)
45440b57cec5SDimitry Andric       return false;
45450b57cec5SDimitry Andric     if (III.TruncateImmTo)
45460b57cec5SDimitry Andric       Imm &= ((1 << III.TruncateImmTo) - 1);
45470b57cec5SDimitry Andric   }
45480b57cec5SDimitry Andric   else
45490b57cec5SDimitry Andric     return false;
45500b57cec5SDimitry Andric 
45510b57cec5SDimitry Andric   // This ImmMO is forwarded if it meets the requriement describle
45520b57cec5SDimitry Andric   // in ImmInstrInfo
45530b57cec5SDimitry Andric   return true;
45540b57cec5SDimitry Andric }
45550b57cec5SDimitry Andric 
45565ffd83dbSDimitry Andric bool PPCInstrInfo::simplifyToLI(MachineInstr &MI, MachineInstr &DefMI,
45575ffd83dbSDimitry Andric                                 unsigned OpNoForForwarding,
45585ffd83dbSDimitry Andric                                 MachineInstr **KilledDef) const {
45595ffd83dbSDimitry Andric   if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
45605ffd83dbSDimitry Andric       !DefMI.getOperand(1).isImm())
45615ffd83dbSDimitry Andric     return false;
45625ffd83dbSDimitry Andric 
45635ffd83dbSDimitry Andric   MachineFunction *MF = MI.getParent()->getParent();
45645ffd83dbSDimitry Andric   MachineRegisterInfo *MRI = &MF->getRegInfo();
45655ffd83dbSDimitry Andric   bool PostRA = !MRI->isSSA();
45665ffd83dbSDimitry Andric 
45675ffd83dbSDimitry Andric   int64_t Immediate = DefMI.getOperand(1).getImm();
45685ffd83dbSDimitry Andric   // Sign-extend to 64-bits.
45695ffd83dbSDimitry Andric   int64_t SExtImm = SignExtend64<16>(Immediate);
45705ffd83dbSDimitry Andric 
45715ffd83dbSDimitry Andric   bool ReplaceWithLI = false;
45725ffd83dbSDimitry Andric   bool Is64BitLI = false;
45735ffd83dbSDimitry Andric   int64_t NewImm = 0;
45745ffd83dbSDimitry Andric   bool SetCR = false;
45755ffd83dbSDimitry Andric   unsigned Opc = MI.getOpcode();
45765ffd83dbSDimitry Andric   switch (Opc) {
45775ffd83dbSDimitry Andric   default:
45785ffd83dbSDimitry Andric     return false;
45795ffd83dbSDimitry Andric 
45805ffd83dbSDimitry Andric   // FIXME: Any branches conditional on such a comparison can be made
45815ffd83dbSDimitry Andric   // unconditional. At this time, this happens too infrequently to be worth
45825ffd83dbSDimitry Andric   // the implementation effort, but if that ever changes, we could convert
45835ffd83dbSDimitry Andric   // such a pattern here.
45845ffd83dbSDimitry Andric   case PPC::CMPWI:
45855ffd83dbSDimitry Andric   case PPC::CMPLWI:
45865ffd83dbSDimitry Andric   case PPC::CMPDI:
45875ffd83dbSDimitry Andric   case PPC::CMPLDI: {
45885ffd83dbSDimitry Andric     // Doing this post-RA would require dataflow analysis to reliably find uses
45895ffd83dbSDimitry Andric     // of the CR register set by the compare.
45905ffd83dbSDimitry Andric     // No need to fixup killed/dead flag since this transformation is only valid
45915ffd83dbSDimitry Andric     // before RA.
45925ffd83dbSDimitry Andric     if (PostRA)
45935ffd83dbSDimitry Andric       return false;
45945ffd83dbSDimitry Andric     // If a compare-immediate is fed by an immediate and is itself an input of
45955ffd83dbSDimitry Andric     // an ISEL (the most common case) into a COPY of the correct register.
45965ffd83dbSDimitry Andric     bool Changed = false;
45975ffd83dbSDimitry Andric     Register DefReg = MI.getOperand(0).getReg();
45985ffd83dbSDimitry Andric     int64_t Comparand = MI.getOperand(2).getImm();
45995ffd83dbSDimitry Andric     int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
46005ffd83dbSDimitry Andric                                 ? (Comparand | 0xFFFFFFFFFFFF0000)
46015ffd83dbSDimitry Andric                                 : Comparand;
46025ffd83dbSDimitry Andric 
46035ffd83dbSDimitry Andric     for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {
46045ffd83dbSDimitry Andric       unsigned UseOpc = CompareUseMI.getOpcode();
46055ffd83dbSDimitry Andric       if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
46065ffd83dbSDimitry Andric         continue;
46075ffd83dbSDimitry Andric       unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
46085ffd83dbSDimitry Andric       Register TrueReg = CompareUseMI.getOperand(1).getReg();
46095ffd83dbSDimitry Andric       Register FalseReg = CompareUseMI.getOperand(2).getReg();
46105ffd83dbSDimitry Andric       unsigned RegToCopy =
46115ffd83dbSDimitry Andric           selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);
46125ffd83dbSDimitry Andric       if (RegToCopy == PPC::NoRegister)
46135ffd83dbSDimitry Andric         continue;
46145ffd83dbSDimitry Andric       // Can't use PPC::COPY to copy PPC::ZERO[8]. Convert it to LI[8] 0.
46155ffd83dbSDimitry Andric       if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
46165ffd83dbSDimitry Andric         CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
46175ffd83dbSDimitry Andric         replaceInstrOperandWithImm(CompareUseMI, 1, 0);
461881ad6265SDimitry Andric         CompareUseMI.removeOperand(3);
461981ad6265SDimitry Andric         CompareUseMI.removeOperand(2);
46205ffd83dbSDimitry Andric         continue;
46215ffd83dbSDimitry Andric       }
46225ffd83dbSDimitry Andric       LLVM_DEBUG(
46235ffd83dbSDimitry Andric           dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");
46245ffd83dbSDimitry Andric       LLVM_DEBUG(DefMI.dump(); MI.dump(); CompareUseMI.dump());
46255ffd83dbSDimitry Andric       LLVM_DEBUG(dbgs() << "Is converted to:\n");
46265ffd83dbSDimitry Andric       // Convert to copy and remove unneeded operands.
46275ffd83dbSDimitry Andric       CompareUseMI.setDesc(get(PPC::COPY));
462881ad6265SDimitry Andric       CompareUseMI.removeOperand(3);
462981ad6265SDimitry Andric       CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
46305ffd83dbSDimitry Andric       CmpIselsConverted++;
46315ffd83dbSDimitry Andric       Changed = true;
46325ffd83dbSDimitry Andric       LLVM_DEBUG(CompareUseMI.dump());
46335ffd83dbSDimitry Andric     }
46345ffd83dbSDimitry Andric     if (Changed)
46355ffd83dbSDimitry Andric       return true;
46365ffd83dbSDimitry Andric     // This may end up incremented multiple times since this function is called
46375ffd83dbSDimitry Andric     // during a fixed-point transformation, but it is only meant to indicate the
46385ffd83dbSDimitry Andric     // presence of this opportunity.
46395ffd83dbSDimitry Andric     MissedConvertibleImmediateInstrs++;
46405ffd83dbSDimitry Andric     return false;
46415ffd83dbSDimitry Andric   }
46425ffd83dbSDimitry Andric 
46435ffd83dbSDimitry Andric   // Immediate forms - may simply be convertable to an LI.
46445ffd83dbSDimitry Andric   case PPC::ADDI:
46455ffd83dbSDimitry Andric   case PPC::ADDI8: {
46465ffd83dbSDimitry Andric     // Does the sum fit in a 16-bit signed field?
46475ffd83dbSDimitry Andric     int64_t Addend = MI.getOperand(2).getImm();
46485ffd83dbSDimitry Andric     if (isInt<16>(Addend + SExtImm)) {
46495ffd83dbSDimitry Andric       ReplaceWithLI = true;
46505ffd83dbSDimitry Andric       Is64BitLI = Opc == PPC::ADDI8;
46515ffd83dbSDimitry Andric       NewImm = Addend + SExtImm;
46525ffd83dbSDimitry Andric       break;
46535ffd83dbSDimitry Andric     }
46545ffd83dbSDimitry Andric     return false;
46555ffd83dbSDimitry Andric   }
4656e8d8bef9SDimitry Andric   case PPC::SUBFIC:
4657e8d8bef9SDimitry Andric   case PPC::SUBFIC8: {
4658e8d8bef9SDimitry Andric     // Only transform this if the CARRY implicit operand is dead.
4659e8d8bef9SDimitry Andric     if (MI.getNumOperands() > 3 && !MI.getOperand(3).isDead())
4660e8d8bef9SDimitry Andric       return false;
4661e8d8bef9SDimitry Andric     int64_t Minuend = MI.getOperand(2).getImm();
4662e8d8bef9SDimitry Andric     if (isInt<16>(Minuend - SExtImm)) {
4663e8d8bef9SDimitry Andric       ReplaceWithLI = true;
4664e8d8bef9SDimitry Andric       Is64BitLI = Opc == PPC::SUBFIC8;
4665e8d8bef9SDimitry Andric       NewImm = Minuend - SExtImm;
4666e8d8bef9SDimitry Andric       break;
4667e8d8bef9SDimitry Andric     }
4668e8d8bef9SDimitry Andric     return false;
4669e8d8bef9SDimitry Andric   }
46705ffd83dbSDimitry Andric   case PPC::RLDICL:
46715ffd83dbSDimitry Andric   case PPC::RLDICL_rec:
46725ffd83dbSDimitry Andric   case PPC::RLDICL_32:
46735ffd83dbSDimitry Andric   case PPC::RLDICL_32_64: {
46745ffd83dbSDimitry Andric     // Use APInt's rotate function.
46755ffd83dbSDimitry Andric     int64_t SH = MI.getOperand(2).getImm();
46765ffd83dbSDimitry Andric     int64_t MB = MI.getOperand(3).getImm();
46775ffd83dbSDimitry Andric     APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,
46785ffd83dbSDimitry Andric                 SExtImm, true);
46795ffd83dbSDimitry Andric     InVal = InVal.rotl(SH);
46805ffd83dbSDimitry Andric     uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;
46815ffd83dbSDimitry Andric     InVal &= Mask;
46825ffd83dbSDimitry Andric     // Can't replace negative values with an LI as that will sign-extend
46835ffd83dbSDimitry Andric     // and not clear the left bits. If we're setting the CR bit, we will use
46845ffd83dbSDimitry Andric     // ANDI_rec which won't sign extend, so that's safe.
46855ffd83dbSDimitry Andric     if (isUInt<15>(InVal.getSExtValue()) ||
46865ffd83dbSDimitry Andric         (Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {
46875ffd83dbSDimitry Andric       ReplaceWithLI = true;
46885ffd83dbSDimitry Andric       Is64BitLI = Opc != PPC::RLDICL_32;
46895ffd83dbSDimitry Andric       NewImm = InVal.getSExtValue();
46905ffd83dbSDimitry Andric       SetCR = Opc == PPC::RLDICL_rec;
46915ffd83dbSDimitry Andric       break;
46925ffd83dbSDimitry Andric     }
46935ffd83dbSDimitry Andric     return false;
46945ffd83dbSDimitry Andric   }
46955ffd83dbSDimitry Andric   case PPC::RLWINM:
46965ffd83dbSDimitry Andric   case PPC::RLWINM8:
46975ffd83dbSDimitry Andric   case PPC::RLWINM_rec:
46985ffd83dbSDimitry Andric   case PPC::RLWINM8_rec: {
46995ffd83dbSDimitry Andric     int64_t SH = MI.getOperand(2).getImm();
47005ffd83dbSDimitry Andric     int64_t MB = MI.getOperand(3).getImm();
47015ffd83dbSDimitry Andric     int64_t ME = MI.getOperand(4).getImm();
47025ffd83dbSDimitry Andric     APInt InVal(32, SExtImm, true);
47035ffd83dbSDimitry Andric     InVal = InVal.rotl(SH);
47045ffd83dbSDimitry Andric     APInt Mask = APInt::getBitsSetWithWrap(32, 32 - ME - 1, 32 - MB);
47055ffd83dbSDimitry Andric     InVal &= Mask;
47065ffd83dbSDimitry Andric     // Can't replace negative values with an LI as that will sign-extend
47075ffd83dbSDimitry Andric     // and not clear the left bits. If we're setting the CR bit, we will use
47085ffd83dbSDimitry Andric     // ANDI_rec which won't sign extend, so that's safe.
47095ffd83dbSDimitry Andric     bool ValueFits = isUInt<15>(InVal.getSExtValue());
47105ffd83dbSDimitry Andric     ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&
47115ffd83dbSDimitry Andric                   isUInt<16>(InVal.getSExtValue()));
47125ffd83dbSDimitry Andric     if (ValueFits) {
47135ffd83dbSDimitry Andric       ReplaceWithLI = true;
47145ffd83dbSDimitry Andric       Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;
47155ffd83dbSDimitry Andric       NewImm = InVal.getSExtValue();
47165ffd83dbSDimitry Andric       SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;
47175ffd83dbSDimitry Andric       break;
47185ffd83dbSDimitry Andric     }
47195ffd83dbSDimitry Andric     return false;
47205ffd83dbSDimitry Andric   }
47215ffd83dbSDimitry Andric   case PPC::ORI:
47225ffd83dbSDimitry Andric   case PPC::ORI8:
47235ffd83dbSDimitry Andric   case PPC::XORI:
47245ffd83dbSDimitry Andric   case PPC::XORI8: {
47255ffd83dbSDimitry Andric     int64_t LogicalImm = MI.getOperand(2).getImm();
47265ffd83dbSDimitry Andric     int64_t Result = 0;
47275ffd83dbSDimitry Andric     if (Opc == PPC::ORI || Opc == PPC::ORI8)
47285ffd83dbSDimitry Andric       Result = LogicalImm | SExtImm;
47295ffd83dbSDimitry Andric     else
47305ffd83dbSDimitry Andric       Result = LogicalImm ^ SExtImm;
47315ffd83dbSDimitry Andric     if (isInt<16>(Result)) {
47325ffd83dbSDimitry Andric       ReplaceWithLI = true;
47335ffd83dbSDimitry Andric       Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;
47345ffd83dbSDimitry Andric       NewImm = Result;
47355ffd83dbSDimitry Andric       break;
47365ffd83dbSDimitry Andric     }
47375ffd83dbSDimitry Andric     return false;
47385ffd83dbSDimitry Andric   }
47395ffd83dbSDimitry Andric   }
47405ffd83dbSDimitry Andric 
47415ffd83dbSDimitry Andric   if (ReplaceWithLI) {
47425ffd83dbSDimitry Andric     // We need to be careful with CR-setting instructions we're replacing.
47435ffd83dbSDimitry Andric     if (SetCR) {
47445ffd83dbSDimitry Andric       // We don't know anything about uses when we're out of SSA, so only
47455ffd83dbSDimitry Andric       // replace if the new immediate will be reproduced.
47465ffd83dbSDimitry Andric       bool ImmChanged = (SExtImm & NewImm) != NewImm;
47475ffd83dbSDimitry Andric       if (PostRA && ImmChanged)
47485ffd83dbSDimitry Andric         return false;
47495ffd83dbSDimitry Andric 
47505ffd83dbSDimitry Andric       if (!PostRA) {
47515ffd83dbSDimitry Andric         // If the defining load-immediate has no other uses, we can just replace
47525ffd83dbSDimitry Andric         // the immediate with the new immediate.
47535ffd83dbSDimitry Andric         if (MRI->hasOneUse(DefMI.getOperand(0).getReg()))
47545ffd83dbSDimitry Andric           DefMI.getOperand(1).setImm(NewImm);
47555ffd83dbSDimitry Andric 
47565ffd83dbSDimitry Andric         // If we're not using the GPR result of the CR-setting instruction, we
47575ffd83dbSDimitry Andric         // just need to and with zero/non-zero depending on the new immediate.
47585ffd83dbSDimitry Andric         else if (MRI->use_empty(MI.getOperand(0).getReg())) {
47595ffd83dbSDimitry Andric           if (NewImm) {
47605ffd83dbSDimitry Andric             assert(Immediate && "Transformation converted zero to non-zero?");
47615ffd83dbSDimitry Andric             NewImm = Immediate;
47625ffd83dbSDimitry Andric           }
47635ffd83dbSDimitry Andric         } else if (ImmChanged)
47645ffd83dbSDimitry Andric           return false;
47655ffd83dbSDimitry Andric       }
47665ffd83dbSDimitry Andric     }
47675ffd83dbSDimitry Andric 
4768bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "Replacing constant instruction:\n");
47695ffd83dbSDimitry Andric     LLVM_DEBUG(MI.dump());
47705ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "Fed by:\n");
47715ffd83dbSDimitry Andric     LLVM_DEBUG(DefMI.dump());
47725ffd83dbSDimitry Andric     LoadImmediateInfo LII;
47735ffd83dbSDimitry Andric     LII.Imm = NewImm;
47745ffd83dbSDimitry Andric     LII.Is64Bit = Is64BitLI;
47755ffd83dbSDimitry Andric     LII.SetCR = SetCR;
47765ffd83dbSDimitry Andric     // If we're setting the CR, the original load-immediate must be kept (as an
47775ffd83dbSDimitry Andric     // operand to ANDI_rec/ANDI8_rec).
47785ffd83dbSDimitry Andric     if (KilledDef && SetCR)
47795ffd83dbSDimitry Andric       *KilledDef = nullptr;
47805ffd83dbSDimitry Andric     replaceInstrWithLI(MI, LII);
47815ffd83dbSDimitry Andric 
47825f757f3fSDimitry Andric     if (PostRA)
47835f757f3fSDimitry Andric       recomputeLivenessFlags(*MI.getParent());
47845ffd83dbSDimitry Andric 
47855ffd83dbSDimitry Andric     LLVM_DEBUG(dbgs() << "With:\n");
47865ffd83dbSDimitry Andric     LLVM_DEBUG(MI.dump());
47875ffd83dbSDimitry Andric     return true;
47885ffd83dbSDimitry Andric   }
47895ffd83dbSDimitry Andric   return false;
47905ffd83dbSDimitry Andric }
47915ffd83dbSDimitry Andric 
47925ffd83dbSDimitry Andric bool PPCInstrInfo::transformToNewImmFormFedByAdd(
47935ffd83dbSDimitry Andric     MachineInstr &MI, MachineInstr &DefMI, unsigned OpNoForForwarding) const {
47945ffd83dbSDimitry Andric   MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();
47955ffd83dbSDimitry Andric   bool PostRA = !MRI->isSSA();
47965ffd83dbSDimitry Andric   // FIXME: extend this to post-ra. Need to do some change in getForwardingDefMI
47975ffd83dbSDimitry Andric   // for post-ra.
47985ffd83dbSDimitry Andric   if (PostRA)
47995ffd83dbSDimitry Andric     return false;
48005ffd83dbSDimitry Andric 
48015ffd83dbSDimitry Andric   // Only handle load/store.
48025ffd83dbSDimitry Andric   if (!MI.mayLoadOrStore())
48035ffd83dbSDimitry Andric     return false;
48045ffd83dbSDimitry Andric 
48055ffd83dbSDimitry Andric   unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(MI.getOpcode());
48065ffd83dbSDimitry Andric 
48075ffd83dbSDimitry Andric   assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
48085ffd83dbSDimitry Andric          "MI must have x-form opcode");
48095ffd83dbSDimitry Andric 
48105ffd83dbSDimitry Andric   // get Imm Form info.
48115ffd83dbSDimitry Andric   ImmInstrInfo III;
48125ffd83dbSDimitry Andric   bool IsVFReg = MI.getOperand(0).isReg()
48135f757f3fSDimitry Andric                      ? PPC::isVFRegister(MI.getOperand(0).getReg())
48145ffd83dbSDimitry Andric                      : false;
48155ffd83dbSDimitry Andric 
48165ffd83dbSDimitry Andric   if (!instrHasImmForm(XFormOpcode, IsVFReg, III, PostRA))
48175ffd83dbSDimitry Andric     return false;
48185ffd83dbSDimitry Andric 
48195ffd83dbSDimitry Andric   if (!III.IsSummingOperands)
48205ffd83dbSDimitry Andric     return false;
48215ffd83dbSDimitry Andric 
48225ffd83dbSDimitry Andric   if (OpNoForForwarding != III.OpNoForForwarding)
48235ffd83dbSDimitry Andric     return false;
48245ffd83dbSDimitry Andric 
48255ffd83dbSDimitry Andric   MachineOperand ImmOperandMI = MI.getOperand(III.ImmOpNo);
48265ffd83dbSDimitry Andric   if (!ImmOperandMI.isImm())
48275ffd83dbSDimitry Andric     return false;
48285ffd83dbSDimitry Andric 
48295ffd83dbSDimitry Andric   // Check DefMI.
48305ffd83dbSDimitry Andric   MachineOperand *ImmMO = nullptr;
48315ffd83dbSDimitry Andric   MachineOperand *RegMO = nullptr;
48325ffd83dbSDimitry Andric   if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
48335ffd83dbSDimitry Andric     return false;
48345ffd83dbSDimitry Andric   assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
48355ffd83dbSDimitry Andric 
48365ffd83dbSDimitry Andric   // Check Imm.
48375ffd83dbSDimitry Andric   // Set ImmBase from imm instruction as base and get new Imm inside
48385ffd83dbSDimitry Andric   // isImmElgibleForForwarding.
48395ffd83dbSDimitry Andric   int64_t ImmBase = ImmOperandMI.getImm();
48405ffd83dbSDimitry Andric   int64_t Imm = 0;
48415ffd83dbSDimitry Andric   if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm, ImmBase))
48425ffd83dbSDimitry Andric     return false;
48435ffd83dbSDimitry Andric 
48445ffd83dbSDimitry Andric   // Do the transform
4845bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Replacing existing reg+imm instruction:\n");
48465ffd83dbSDimitry Andric   LLVM_DEBUG(MI.dump());
48475ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "Fed by:\n");
48485ffd83dbSDimitry Andric   LLVM_DEBUG(DefMI.dump());
48495ffd83dbSDimitry Andric 
48505ffd83dbSDimitry Andric   MI.getOperand(III.OpNoForForwarding).setReg(RegMO->getReg());
48515ffd83dbSDimitry Andric   MI.getOperand(III.ImmOpNo).setImm(Imm);
48525ffd83dbSDimitry Andric 
48535ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "With:\n");
48545ffd83dbSDimitry Andric   LLVM_DEBUG(MI.dump());
48555ffd83dbSDimitry Andric   return true;
48565ffd83dbSDimitry Andric }
48575ffd83dbSDimitry Andric 
48580b57cec5SDimitry Andric // If an X-Form instruction is fed by an add-immediate and one of its operands
48590b57cec5SDimitry Andric // is the literal zero, attempt to forward the source of the add-immediate to
48600b57cec5SDimitry Andric // the corresponding D-Form instruction with the displacement coming from
48610b57cec5SDimitry Andric // the immediate being added.
48620b57cec5SDimitry Andric bool PPCInstrInfo::transformToImmFormFedByAdd(
48630b57cec5SDimitry Andric     MachineInstr &MI, const ImmInstrInfo &III, unsigned OpNoForForwarding,
48640b57cec5SDimitry Andric     MachineInstr &DefMI, bool KillDefMI) const {
48650b57cec5SDimitry Andric   //         RegMO ImmMO
48660b57cec5SDimitry Andric   //           |    |
48670b57cec5SDimitry Andric   // x = addi reg, imm  <----- DefMI
48680b57cec5SDimitry Andric   // y = op    0 ,  x   <----- MI
48690b57cec5SDimitry Andric   //                |
48700b57cec5SDimitry Andric   //         OpNoForForwarding
48710b57cec5SDimitry Andric   // Check if the MI meet the requirement described in the III.
48720b57cec5SDimitry Andric   if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))
48730b57cec5SDimitry Andric     return false;
48740b57cec5SDimitry Andric 
48750b57cec5SDimitry Andric   // Check if the DefMI meet the requirement
48760b57cec5SDimitry Andric   // described in the III. If yes, set the ImmMO and RegMO accordingly.
48770b57cec5SDimitry Andric   MachineOperand *ImmMO = nullptr;
48780b57cec5SDimitry Andric   MachineOperand *RegMO = nullptr;
48790b57cec5SDimitry Andric   if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))
48800b57cec5SDimitry Andric     return false;
48810b57cec5SDimitry Andric   assert(ImmMO && RegMO && "Imm and Reg operand must have been set");
48820b57cec5SDimitry Andric 
48830b57cec5SDimitry Andric   // As we get the Imm operand now, we need to check if the ImmMO meet
48840b57cec5SDimitry Andric   // the requirement described in the III. If yes set the Imm.
48850b57cec5SDimitry Andric   int64_t Imm = 0;
48860b57cec5SDimitry Andric   if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
48870b57cec5SDimitry Andric     return false;
48880b57cec5SDimitry Andric 
48890b57cec5SDimitry Andric   bool IsFwdFeederRegKilled = false;
4890bdd1243dSDimitry Andric   bool SeenIntermediateUse = false;
48910b57cec5SDimitry Andric   // Check if the RegMO can be forwarded to MI.
48920b57cec5SDimitry Andric   if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,
4893bdd1243dSDimitry Andric                                  IsFwdFeederRegKilled, SeenIntermediateUse))
48940b57cec5SDimitry Andric     return false;
48950b57cec5SDimitry Andric 
48960b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
48970b57cec5SDimitry Andric   bool PostRA = !MRI.isSSA();
48980b57cec5SDimitry Andric 
48990b57cec5SDimitry Andric   // We know that, the MI and DefMI both meet the pattern, and
49000b57cec5SDimitry Andric   // the Imm also meet the requirement with the new Imm-form.
49010b57cec5SDimitry Andric   // It is safe to do the transformation now.
4902bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Replacing indexed instruction:\n");
49030b57cec5SDimitry Andric   LLVM_DEBUG(MI.dump());
49040b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Fed by:\n");
49050b57cec5SDimitry Andric   LLVM_DEBUG(DefMI.dump());
49060b57cec5SDimitry Andric 
49070b57cec5SDimitry Andric   // Update the base reg first.
49080b57cec5SDimitry Andric   MI.getOperand(III.OpNoForForwarding).ChangeToRegister(RegMO->getReg(),
49090b57cec5SDimitry Andric                                                         false, false,
49100b57cec5SDimitry Andric                                                         RegMO->isKill());
49110b57cec5SDimitry Andric 
49120b57cec5SDimitry Andric   // Then, update the imm.
49130b57cec5SDimitry Andric   if (ImmMO->isImm()) {
49140b57cec5SDimitry Andric     // If the ImmMO is Imm, change the operand that has ZERO to that Imm
49150b57cec5SDimitry Andric     // directly.
49160b57cec5SDimitry Andric     replaceInstrOperandWithImm(MI, III.ZeroIsSpecialOrig, Imm);
49170b57cec5SDimitry Andric   }
49180b57cec5SDimitry Andric   else {
49190b57cec5SDimitry Andric     // Otherwise, it is Constant Pool Index(CPI) or Global,
49200b57cec5SDimitry Andric     // which is relocation in fact. We need to replace the special zero
49210b57cec5SDimitry Andric     // register with ImmMO.
49220b57cec5SDimitry Andric     // Before that, we need to fixup the target flags for imm.
49230b57cec5SDimitry Andric     // For some reason, we miss to set the flag for the ImmMO if it is CPI.
49240fca6ea1SDimitry Andric     if (DefMI.getOpcode() == PPC::ADDItocL8)
49250b57cec5SDimitry Andric       ImmMO->setTargetFlags(PPCII::MO_TOC_LO);
49260b57cec5SDimitry Andric 
49270b57cec5SDimitry Andric     // MI didn't have the interface such as MI.setOperand(i) though
49280b57cec5SDimitry Andric     // it has MI.getOperand(i). To repalce the ZERO MachineOperand with
49290b57cec5SDimitry Andric     // ImmMO, we need to remove ZERO operand and all the operands behind it,
49300b57cec5SDimitry Andric     // and, add the ImmMO, then, move back all the operands behind ZERO.
49310b57cec5SDimitry Andric     SmallVector<MachineOperand, 2> MOps;
49320b57cec5SDimitry Andric     for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {
49330b57cec5SDimitry Andric       MOps.push_back(MI.getOperand(i));
493481ad6265SDimitry Andric       MI.removeOperand(i);
49350b57cec5SDimitry Andric     }
49360b57cec5SDimitry Andric 
49370b57cec5SDimitry Andric     // Remove the last MO in the list, which is ZERO operand in fact.
49380b57cec5SDimitry Andric     MOps.pop_back();
49390b57cec5SDimitry Andric     // Add the imm operand.
49400b57cec5SDimitry Andric     MI.addOperand(*ImmMO);
49410b57cec5SDimitry Andric     // Now add the rest back.
49420b57cec5SDimitry Andric     for (auto &MO : MOps)
49430b57cec5SDimitry Andric       MI.addOperand(MO);
49440b57cec5SDimitry Andric   }
49450b57cec5SDimitry Andric 
49460b57cec5SDimitry Andric   // Update the opcode.
49470b57cec5SDimitry Andric   MI.setDesc(get(III.ImmOpcode));
49480b57cec5SDimitry Andric 
49495f757f3fSDimitry Andric   if (PostRA)
49505f757f3fSDimitry Andric     recomputeLivenessFlags(*MI.getParent());
49510b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "With:\n");
49520b57cec5SDimitry Andric   LLVM_DEBUG(MI.dump());
49530b57cec5SDimitry Andric 
49540b57cec5SDimitry Andric   return true;
49550b57cec5SDimitry Andric }
49560b57cec5SDimitry Andric 
49570b57cec5SDimitry Andric bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
49580b57cec5SDimitry Andric                                              const ImmInstrInfo &III,
49590b57cec5SDimitry Andric                                              unsigned ConstantOpNo,
49605ffd83dbSDimitry Andric                                              MachineInstr &DefMI) const {
49615ffd83dbSDimitry Andric   // DefMI must be LI or LI8.
49625ffd83dbSDimitry Andric   if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||
49635ffd83dbSDimitry Andric       !DefMI.getOperand(1).isImm())
49645ffd83dbSDimitry Andric     return false;
49655ffd83dbSDimitry Andric 
49665ffd83dbSDimitry Andric   // Get Imm operand and Sign-extend to 64-bits.
49675ffd83dbSDimitry Andric   int64_t Imm = SignExtend64<16>(DefMI.getOperand(1).getImm());
49685ffd83dbSDimitry Andric 
49690b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
49700b57cec5SDimitry Andric   bool PostRA = !MRI.isSSA();
49710b57cec5SDimitry Andric   // Exit early if we can't convert this.
49720b57cec5SDimitry Andric   if ((ConstantOpNo != III.OpNoForForwarding) && !III.IsCommutative)
49730b57cec5SDimitry Andric     return false;
49740b57cec5SDimitry Andric   if (Imm % III.ImmMustBeMultipleOf)
49750b57cec5SDimitry Andric     return false;
49760b57cec5SDimitry Andric   if (III.TruncateImmTo)
49770b57cec5SDimitry Andric     Imm &= ((1 << III.TruncateImmTo) - 1);
49780b57cec5SDimitry Andric   if (III.SignedImm) {
49790b57cec5SDimitry Andric     APInt ActualValue(64, Imm, true);
49800b57cec5SDimitry Andric     if (!ActualValue.isSignedIntN(III.ImmWidth))
49810b57cec5SDimitry Andric       return false;
49820b57cec5SDimitry Andric   } else {
49830b57cec5SDimitry Andric     uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;
49840b57cec5SDimitry Andric     if ((uint64_t)Imm > UnsignedMax)
49850b57cec5SDimitry Andric       return false;
49860b57cec5SDimitry Andric   }
49870b57cec5SDimitry Andric 
49880b57cec5SDimitry Andric   // If we're post-RA, the instructions don't agree on whether register zero is
49890b57cec5SDimitry Andric   // special, we can transform this as long as the register operand that will
49900b57cec5SDimitry Andric   // end up in the location where zero is special isn't R0.
49910b57cec5SDimitry Andric   if (PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
49920b57cec5SDimitry Andric     unsigned PosForOrigZero = III.ZeroIsSpecialOrig ? III.ZeroIsSpecialOrig :
49930b57cec5SDimitry Andric       III.ZeroIsSpecialNew + 1;
49948bcb0991SDimitry Andric     Register OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();
49958bcb0991SDimitry Andric     Register NewZeroReg = MI.getOperand(III.ZeroIsSpecialNew).getReg();
49960b57cec5SDimitry Andric     // If R0 is in the operand where zero is special for the new instruction,
49970b57cec5SDimitry Andric     // it is unsafe to transform if the constant operand isn't that operand.
49980b57cec5SDimitry Andric     if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
49990b57cec5SDimitry Andric         ConstantOpNo != III.ZeroIsSpecialNew)
50000b57cec5SDimitry Andric       return false;
50010b57cec5SDimitry Andric     if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
50020b57cec5SDimitry Andric         ConstantOpNo != PosForOrigZero)
50030b57cec5SDimitry Andric       return false;
50040b57cec5SDimitry Andric   }
50050b57cec5SDimitry Andric 
50060b57cec5SDimitry Andric   unsigned Opc = MI.getOpcode();
5007480093f4SDimitry Andric   bool SpecialShift32 = Opc == PPC::SLW || Opc == PPC::SLW_rec ||
5008480093f4SDimitry Andric                         Opc == PPC::SRW || Opc == PPC::SRW_rec ||
5009480093f4SDimitry Andric                         Opc == PPC::SLW8 || Opc == PPC::SLW8_rec ||
5010480093f4SDimitry Andric                         Opc == PPC::SRW8 || Opc == PPC::SRW8_rec;
5011480093f4SDimitry Andric   bool SpecialShift64 = Opc == PPC::SLD || Opc == PPC::SLD_rec ||
5012480093f4SDimitry Andric                         Opc == PPC::SRD || Opc == PPC::SRD_rec;
5013480093f4SDimitry Andric   bool SetCR = Opc == PPC::SLW_rec || Opc == PPC::SRW_rec ||
5014480093f4SDimitry Andric                Opc == PPC::SLD_rec || Opc == PPC::SRD_rec;
5015480093f4SDimitry Andric   bool RightShift = Opc == PPC::SRW || Opc == PPC::SRW_rec || Opc == PPC::SRD ||
5016480093f4SDimitry Andric                     Opc == PPC::SRD_rec;
50170b57cec5SDimitry Andric 
5018bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Replacing reg+reg instruction: ");
5019bdd1243dSDimitry Andric   LLVM_DEBUG(MI.dump());
5020bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Fed by load-immediate: ");
5021bdd1243dSDimitry Andric   LLVM_DEBUG(DefMI.dump());
50220b57cec5SDimitry Andric   MI.setDesc(get(III.ImmOpcode));
50230b57cec5SDimitry Andric   if (ConstantOpNo == III.OpNoForForwarding) {
50240b57cec5SDimitry Andric     // Converting shifts to immediate form is a bit tricky since they may do
50250b57cec5SDimitry Andric     // one of three things:
50260b57cec5SDimitry Andric     // 1. If the shift amount is between OpSize and 2*OpSize, the result is zero
50270b57cec5SDimitry Andric     // 2. If the shift amount is zero, the result is unchanged (save for maybe
50280b57cec5SDimitry Andric     //    setting CR0)
50290b57cec5SDimitry Andric     // 3. If the shift amount is in [1, OpSize), it's just a shift
50300b57cec5SDimitry Andric     if (SpecialShift32 || SpecialShift64) {
50310b57cec5SDimitry Andric       LoadImmediateInfo LII;
50320b57cec5SDimitry Andric       LII.Imm = 0;
50330b57cec5SDimitry Andric       LII.SetCR = SetCR;
50340b57cec5SDimitry Andric       LII.Is64Bit = SpecialShift64;
50350b57cec5SDimitry Andric       uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);
50360b57cec5SDimitry Andric       if (Imm & (SpecialShift32 ? 0x20 : 0x40))
50370b57cec5SDimitry Andric         replaceInstrWithLI(MI, LII);
50380b57cec5SDimitry Andric       // Shifts by zero don't change the value. If we don't need to set CR0,
50390b57cec5SDimitry Andric       // just convert this to a COPY. Can't do this post-RA since we've already
50400b57cec5SDimitry Andric       // cleaned up the copies.
50410b57cec5SDimitry Andric       else if (!SetCR && ShAmt == 0 && !PostRA) {
504281ad6265SDimitry Andric         MI.removeOperand(2);
50430b57cec5SDimitry Andric         MI.setDesc(get(PPC::COPY));
50440b57cec5SDimitry Andric       } else {
50450b57cec5SDimitry Andric         // The 32 bit and 64 bit instructions are quite different.
50460b57cec5SDimitry Andric         if (SpecialShift32) {
50478bcb0991SDimitry Andric           // Left shifts use (N, 0, 31-N).
50488bcb0991SDimitry Andric           // Right shifts use (32-N, N, 31) if 0 < N < 32.
50498bcb0991SDimitry Andric           //              use (0, 0, 31)    if N == 0.
50508bcb0991SDimitry Andric           uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 32 - ShAmt : ShAmt;
50510b57cec5SDimitry Andric           uint64_t MB = RightShift ? ShAmt : 0;
50520b57cec5SDimitry Andric           uint64_t ME = RightShift ? 31 : 31 - ShAmt;
50530b57cec5SDimitry Andric           replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
50540b57cec5SDimitry Andric           MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)
50550b57cec5SDimitry Andric             .addImm(ME);
50560b57cec5SDimitry Andric         } else {
50578bcb0991SDimitry Andric           // Left shifts use (N, 63-N).
50588bcb0991SDimitry Andric           // Right shifts use (64-N, N) if 0 < N < 64.
50598bcb0991SDimitry Andric           //              use (0, 0)    if N == 0.
50608bcb0991SDimitry Andric           uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 64 - ShAmt : ShAmt;
50610b57cec5SDimitry Andric           uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;
50620b57cec5SDimitry Andric           replaceInstrOperandWithImm(MI, III.OpNoForForwarding, SH);
50630b57cec5SDimitry Andric           MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);
50640b57cec5SDimitry Andric         }
50650b57cec5SDimitry Andric       }
50660b57cec5SDimitry Andric     } else
50670b57cec5SDimitry Andric       replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
50680b57cec5SDimitry Andric   }
50690b57cec5SDimitry Andric   // Convert commutative instructions (switch the operands and convert the
50700b57cec5SDimitry Andric   // desired one to an immediate.
50710b57cec5SDimitry Andric   else if (III.IsCommutative) {
50720b57cec5SDimitry Andric     replaceInstrOperandWithImm(MI, ConstantOpNo, Imm);
50730b57cec5SDimitry Andric     swapMIOperands(MI, ConstantOpNo, III.OpNoForForwarding);
50740b57cec5SDimitry Andric   } else
50750b57cec5SDimitry Andric     llvm_unreachable("Should have exited early!");
50760b57cec5SDimitry Andric 
50770b57cec5SDimitry Andric   // For instructions for which the constant register replaces a different
50780b57cec5SDimitry Andric   // operand than where the immediate goes, we need to swap them.
50790b57cec5SDimitry Andric   if (III.OpNoForForwarding != III.ImmOpNo)
50800b57cec5SDimitry Andric     swapMIOperands(MI, III.OpNoForForwarding, III.ImmOpNo);
50810b57cec5SDimitry Andric 
50820b57cec5SDimitry Andric   // If the special R0/X0 register index are different for original instruction
50830b57cec5SDimitry Andric   // and new instruction, we need to fix up the register class in new
50840b57cec5SDimitry Andric   // instruction.
50850b57cec5SDimitry Andric   if (!PostRA && III.ZeroIsSpecialOrig != III.ZeroIsSpecialNew) {
50860b57cec5SDimitry Andric     if (III.ZeroIsSpecialNew) {
50870b57cec5SDimitry Andric       // If operand at III.ZeroIsSpecialNew is physical reg(eg: ZERO/ZERO8), no
50880b57cec5SDimitry Andric       // need to fix up register class.
50898bcb0991SDimitry Andric       Register RegToModify = MI.getOperand(III.ZeroIsSpecialNew).getReg();
5090bdd1243dSDimitry Andric       if (RegToModify.isVirtual()) {
50910b57cec5SDimitry Andric         const TargetRegisterClass *NewRC =
50920b57cec5SDimitry Andric           MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
50930b57cec5SDimitry Andric           &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
50940b57cec5SDimitry Andric         MRI.setRegClass(RegToModify, NewRC);
50950b57cec5SDimitry Andric       }
50960b57cec5SDimitry Andric     }
50970b57cec5SDimitry Andric   }
50980b57cec5SDimitry Andric 
50995f757f3fSDimitry Andric   if (PostRA)
51005f757f3fSDimitry Andric     recomputeLivenessFlags(*MI.getParent());
5101bdd1243dSDimitry Andric 
5102bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "With: ");
5103bdd1243dSDimitry Andric   LLVM_DEBUG(MI.dump());
5104bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "\n");
51050b57cec5SDimitry Andric   return true;
51060b57cec5SDimitry Andric }
51070b57cec5SDimitry Andric 
51080b57cec5SDimitry Andric const TargetRegisterClass *
51090b57cec5SDimitry Andric PPCInstrInfo::updatedRC(const TargetRegisterClass *RC) const {
51100b57cec5SDimitry Andric   if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
51110b57cec5SDimitry Andric     return &PPC::VSRCRegClass;
51120b57cec5SDimitry Andric   return RC;
51130b57cec5SDimitry Andric }
51140b57cec5SDimitry Andric 
51150b57cec5SDimitry Andric int PPCInstrInfo::getRecordFormOpcode(unsigned Opcode) {
51160b57cec5SDimitry Andric   return PPC::getRecordFormOpcode(Opcode);
51170b57cec5SDimitry Andric }
51180b57cec5SDimitry Andric 
5119bdd1243dSDimitry Andric static bool isOpZeroOfSubwordPreincLoad(int Opcode) {
5120bdd1243dSDimitry Andric   return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5121bdd1243dSDimitry Andric           Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5122bdd1243dSDimitry Andric           Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5123bdd1243dSDimitry Andric           Opcode == PPC::LHZUX8);
5124bdd1243dSDimitry Andric }
5125bdd1243dSDimitry Andric 
5126bdd1243dSDimitry Andric // This function checks for sign extension from 32 bits to 64 bits.
5127bdd1243dSDimitry Andric static bool definedBySignExtendingOp(const unsigned Reg,
5128bdd1243dSDimitry Andric                                      const MachineRegisterInfo *MRI) {
5129bdd1243dSDimitry Andric   if (!Register::isVirtualRegister(Reg))
5130bdd1243dSDimitry Andric     return false;
5131bdd1243dSDimitry Andric 
5132bdd1243dSDimitry Andric   MachineInstr *MI = MRI->getVRegDef(Reg);
5133bdd1243dSDimitry Andric   if (!MI)
5134bdd1243dSDimitry Andric     return false;
5135bdd1243dSDimitry Andric 
5136bdd1243dSDimitry Andric   int Opcode = MI->getOpcode();
5137bdd1243dSDimitry Andric   const PPCInstrInfo *TII =
5138bdd1243dSDimitry Andric       MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5139bdd1243dSDimitry Andric   if (TII->isSExt32To64(Opcode))
51400b57cec5SDimitry Andric     return true;
51410b57cec5SDimitry Andric 
5142bdd1243dSDimitry Andric   // The first def of LBZU/LHZU is sign extended.
5143bdd1243dSDimitry Andric   if (isOpZeroOfSubwordPreincLoad(Opcode) && MI->getOperand(0).getReg() == Reg)
51440b57cec5SDimitry Andric     return true;
51450b57cec5SDimitry Andric 
5146bdd1243dSDimitry Andric   // RLDICL generates sign-extended output if it clears at least
5147bdd1243dSDimitry Andric   // 33 bits from the left (MSB).
5148bdd1243dSDimitry Andric   if (Opcode == PPC::RLDICL && MI->getOperand(3).getImm() >= 33)
5149bdd1243dSDimitry Andric     return true;
5150bdd1243dSDimitry Andric 
5151bdd1243dSDimitry Andric   // If at least one bit from left in a lower word is masked out,
5152bdd1243dSDimitry Andric   // all of 0 to 32-th bits of the output are cleared.
5153bdd1243dSDimitry Andric   // Hence the output is already sign extended.
5154480093f4SDimitry Andric   if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5155480093f4SDimitry Andric        Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5156bdd1243dSDimitry Andric       MI->getOperand(3).getImm() > 0 &&
5157bdd1243dSDimitry Andric       MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
51580b57cec5SDimitry Andric     return true;
51590b57cec5SDimitry Andric 
5160bdd1243dSDimitry Andric   // If the most significant bit of immediate in ANDIS is zero,
5161bdd1243dSDimitry Andric   // all of 0 to 32-th bits are cleared.
5162bdd1243dSDimitry Andric   if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5163bdd1243dSDimitry Andric     uint16_t Imm = MI->getOperand(2).getImm();
5164bdd1243dSDimitry Andric     if ((Imm & 0x8000) == 0)
5165bdd1243dSDimitry Andric       return true;
5166bdd1243dSDimitry Andric   }
5167bdd1243dSDimitry Andric 
51680b57cec5SDimitry Andric   return false;
51690b57cec5SDimitry Andric }
51700b57cec5SDimitry Andric 
5171bdd1243dSDimitry Andric // This function checks the machine instruction that defines the input register
5172bdd1243dSDimitry Andric // Reg. If that machine instruction always outputs a value that has only zeros
5173bdd1243dSDimitry Andric // in the higher 32 bits then this function will return true.
5174bdd1243dSDimitry Andric static bool definedByZeroExtendingOp(const unsigned Reg,
5175bdd1243dSDimitry Andric                                      const MachineRegisterInfo *MRI) {
5176bdd1243dSDimitry Andric   if (!Register::isVirtualRegister(Reg))
5177bdd1243dSDimitry Andric     return false;
5178bdd1243dSDimitry Andric 
5179bdd1243dSDimitry Andric   MachineInstr *MI = MRI->getVRegDef(Reg);
5180bdd1243dSDimitry Andric   if (!MI)
5181bdd1243dSDimitry Andric     return false;
5182bdd1243dSDimitry Andric 
5183bdd1243dSDimitry Andric   int Opcode = MI->getOpcode();
5184bdd1243dSDimitry Andric   const PPCInstrInfo *TII =
5185bdd1243dSDimitry Andric       MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
5186bdd1243dSDimitry Andric   if (TII->isZExt32To64(Opcode))
5187bdd1243dSDimitry Andric     return true;
5188bdd1243dSDimitry Andric 
5189bdd1243dSDimitry Andric   // The first def of LBZU/LHZU/LWZU are zero extended.
5190bdd1243dSDimitry Andric   if ((isOpZeroOfSubwordPreincLoad(Opcode) || Opcode == PPC::LWZU ||
5191bdd1243dSDimitry Andric        Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5192bdd1243dSDimitry Andric       MI->getOperand(0).getReg() == Reg)
5193bdd1243dSDimitry Andric     return true;
5194bdd1243dSDimitry Andric 
51950b57cec5SDimitry Andric   // The 16-bit immediate is sign-extended in li/lis.
51960b57cec5SDimitry Andric   // If the most significant bit is zero, all higher bits are zero.
51970b57cec5SDimitry Andric   if (Opcode == PPC::LI  || Opcode == PPC::LI8 ||
51980b57cec5SDimitry Andric       Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5199bdd1243dSDimitry Andric     int64_t Imm = MI->getOperand(1).getImm();
52000b57cec5SDimitry Andric     if (((uint64_t)Imm & ~0x7FFFuLL) == 0)
52010b57cec5SDimitry Andric       return true;
52020b57cec5SDimitry Andric   }
52030b57cec5SDimitry Andric 
52040b57cec5SDimitry Andric   // We have some variations of rotate-and-mask instructions
52050b57cec5SDimitry Andric   // that clear higher 32-bits.
5206480093f4SDimitry Andric   if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5207480093f4SDimitry Andric        Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
52080b57cec5SDimitry Andric        Opcode == PPC::RLDICL_32_64) &&
5209bdd1243dSDimitry Andric       MI->getOperand(3).getImm() >= 32)
52100b57cec5SDimitry Andric     return true;
52110b57cec5SDimitry Andric 
5212480093f4SDimitry Andric   if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5213bdd1243dSDimitry Andric       MI->getOperand(3).getImm() >= 32 &&
5214bdd1243dSDimitry Andric       MI->getOperand(3).getImm() <= 63 - MI->getOperand(2).getImm())
52150b57cec5SDimitry Andric     return true;
52160b57cec5SDimitry Andric 
5217480093f4SDimitry Andric   if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5218480093f4SDimitry Andric        Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
52190b57cec5SDimitry Andric        Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5220bdd1243dSDimitry Andric       MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())
52210b57cec5SDimitry Andric     return true;
52220b57cec5SDimitry Andric 
52230b57cec5SDimitry Andric   return false;
52240b57cec5SDimitry Andric }
52250b57cec5SDimitry Andric 
52260b57cec5SDimitry Andric // This function returns true if the input MachineInstr is a TOC save
52270b57cec5SDimitry Andric // instruction.
52280b57cec5SDimitry Andric bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
52290b57cec5SDimitry Andric   if (!MI.getOperand(1).isImm() || !MI.getOperand(2).isReg())
52300b57cec5SDimitry Andric     return false;
52310b57cec5SDimitry Andric   unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
52320b57cec5SDimitry Andric   unsigned StackOffset = MI.getOperand(1).getImm();
52338bcb0991SDimitry Andric   Register StackReg = MI.getOperand(2).getReg();
5234fe6060f1SDimitry Andric   Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
5235fe6060f1SDimitry Andric   if (StackReg == SPReg && StackOffset == TOCSaveOffset)
52360b57cec5SDimitry Andric     return true;
52370b57cec5SDimitry Andric 
52380b57cec5SDimitry Andric   return false;
52390b57cec5SDimitry Andric }
52400b57cec5SDimitry Andric 
52410b57cec5SDimitry Andric // We limit the max depth to track incoming values of PHIs or binary ops
52420b57cec5SDimitry Andric // (e.g. AND) to avoid excessive cost.
5243bdd1243dSDimitry Andric const unsigned MAX_BINOP_DEPTH = 1;
5244bdd1243dSDimitry Andric // The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
5245bdd1243dSDimitry Andric // does not count all of the recursions. The parameter BinOpDepth is incremented
5246bdd1243dSDimitry Andric // only when isSignOrZeroExtended calls itself more than once. This is done to
5247bdd1243dSDimitry Andric // prevent expontential recursion. There is no parameter to track linear
5248bdd1243dSDimitry Andric // recursion.
5249bdd1243dSDimitry Andric std::pair<bool, bool>
5250bdd1243dSDimitry Andric PPCInstrInfo::isSignOrZeroExtended(const unsigned Reg,
5251bdd1243dSDimitry Andric                                    const unsigned BinOpDepth,
5252bdd1243dSDimitry Andric                                    const MachineRegisterInfo *MRI) const {
5253bdd1243dSDimitry Andric   if (!Register::isVirtualRegister(Reg))
5254bdd1243dSDimitry Andric     return std::pair<bool, bool>(false, false);
52550b57cec5SDimitry Andric 
5256bdd1243dSDimitry Andric   MachineInstr *MI = MRI->getVRegDef(Reg);
5257bdd1243dSDimitry Andric   if (!MI)
5258bdd1243dSDimitry Andric     return std::pair<bool, bool>(false, false);
52590b57cec5SDimitry Andric 
5260bdd1243dSDimitry Andric   bool IsSExt = definedBySignExtendingOp(Reg, MRI);
5261bdd1243dSDimitry Andric   bool IsZExt = definedByZeroExtendingOp(Reg, MRI);
52620b57cec5SDimitry Andric 
5263bdd1243dSDimitry Andric   // If we know the instruction always returns sign- and zero-extended result,
5264bdd1243dSDimitry Andric   // return here.
5265bdd1243dSDimitry Andric   if (IsSExt && IsZExt)
5266bdd1243dSDimitry Andric     return std::pair<bool, bool>(IsSExt, IsZExt);
5267bdd1243dSDimitry Andric 
5268bdd1243dSDimitry Andric   switch (MI->getOpcode()) {
52690b57cec5SDimitry Andric   case PPC::COPY: {
5270bdd1243dSDimitry Andric     Register SrcReg = MI->getOperand(1).getReg();
52710b57cec5SDimitry Andric 
52720b57cec5SDimitry Andric     // In both ELFv1 and v2 ABI, method parameters and the return value
52730b57cec5SDimitry Andric     // are sign- or zero-extended.
5274bdd1243dSDimitry Andric     const MachineFunction *MF = MI->getMF();
5275bdd1243dSDimitry Andric 
5276bdd1243dSDimitry Andric     if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
5277bdd1243dSDimitry Andric       // If this is a copy from another register, we recursively check source.
5278bdd1243dSDimitry Andric       auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI);
5279bdd1243dSDimitry Andric       return std::pair<bool, bool>(SrcExt.first || IsSExt,
5280bdd1243dSDimitry Andric                                    SrcExt.second || IsZExt);
5281bdd1243dSDimitry Andric     }
5282bdd1243dSDimitry Andric 
5283bdd1243dSDimitry Andric     // From here on everything is SVR4ABI
52840b57cec5SDimitry Andric     const PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
52850b57cec5SDimitry Andric     // We check the ZExt/SExt flags for a method parameter.
5286bdd1243dSDimitry Andric     if (MI->getParent()->getBasicBlock() ==
52870b57cec5SDimitry Andric         &MF->getFunction().getEntryBlock()) {
5288bdd1243dSDimitry Andric       Register VReg = MI->getOperand(0).getReg();
5289bdd1243dSDimitry Andric       if (MF->getRegInfo().isLiveIn(VReg)) {
5290bdd1243dSDimitry Andric         IsSExt |= FuncInfo->isLiveInSExt(VReg);
5291bdd1243dSDimitry Andric         IsZExt |= FuncInfo->isLiveInZExt(VReg);
5292bdd1243dSDimitry Andric         return std::pair<bool, bool>(IsSExt, IsZExt);
5293bdd1243dSDimitry Andric       }
5294bdd1243dSDimitry Andric     }
5295bdd1243dSDimitry Andric 
5296bdd1243dSDimitry Andric     if (SrcReg != PPC::X3) {
5297bdd1243dSDimitry Andric       // If this is a copy from another register, we recursively check source.
5298bdd1243dSDimitry Andric       auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI);
5299bdd1243dSDimitry Andric       return std::pair<bool, bool>(SrcExt.first || IsSExt,
5300bdd1243dSDimitry Andric                                    SrcExt.second || IsZExt);
53010b57cec5SDimitry Andric     }
53020b57cec5SDimitry Andric 
53030b57cec5SDimitry Andric     // For a method return value, we check the ZExt/SExt flags in attribute.
53040b57cec5SDimitry Andric     // We assume the following code sequence for method call.
53050b57cec5SDimitry Andric     //   ADJCALLSTACKDOWN 32, implicit dead %r1, implicit %r1
53060b57cec5SDimitry Andric     //   BL8_NOP @func,...
53070b57cec5SDimitry Andric     //   ADJCALLSTACKUP 32, 0, implicit dead %r1, implicit %r1
53080b57cec5SDimitry Andric     //   %5 = COPY %x3; G8RC:%5
5309bdd1243dSDimitry Andric     const MachineBasicBlock *MBB = MI->getParent();
5310bdd1243dSDimitry Andric     std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
53110b57cec5SDimitry Andric     MachineBasicBlock::const_instr_iterator II =
5312bdd1243dSDimitry Andric         MachineBasicBlock::const_instr_iterator(MI);
5313bdd1243dSDimitry Andric     if (II == MBB->instr_begin() || (--II)->getOpcode() != PPC::ADJCALLSTACKUP)
5314bdd1243dSDimitry Andric       return IsExtendPair;
5315bdd1243dSDimitry Andric 
53160b57cec5SDimitry Andric     const MachineInstr &CallMI = *(--II);
5317bdd1243dSDimitry Andric     if (!CallMI.isCall() || !CallMI.getOperand(0).isGlobal())
5318bdd1243dSDimitry Andric       return IsExtendPair;
5319bdd1243dSDimitry Andric 
53200b57cec5SDimitry Andric     const Function *CalleeFn =
5321bdd1243dSDimitry Andric         dyn_cast_if_present<Function>(CallMI.getOperand(0).getGlobal());
53220b57cec5SDimitry Andric     if (!CalleeFn)
5323bdd1243dSDimitry Andric       return IsExtendPair;
5324bdd1243dSDimitry Andric     const IntegerType *IntTy = dyn_cast<IntegerType>(CalleeFn->getReturnType());
5325bdd1243dSDimitry Andric     if (IntTy && IntTy->getBitWidth() <= 32) {
5326349cc55cSDimitry Andric       const AttributeSet &Attrs = CalleeFn->getAttributes().getRetAttrs();
5327bdd1243dSDimitry Andric       IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5328bdd1243dSDimitry Andric       IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5329bdd1243dSDimitry Andric       return std::pair<bool, bool>(IsSExt, IsZExt);
53300b57cec5SDimitry Andric     }
53310b57cec5SDimitry Andric 
5332bdd1243dSDimitry Andric     return IsExtendPair;
53330b57cec5SDimitry Andric   }
53340b57cec5SDimitry Andric 
5335bdd1243dSDimitry Andric   // OR, XOR with 16-bit immediate does not change the upper 48 bits.
53360b57cec5SDimitry Andric   // So, we track the operand register as we do for register copy.
5337bdd1243dSDimitry Andric   case PPC::ORI:
5338bdd1243dSDimitry Andric   case PPC::XORI:
5339bdd1243dSDimitry Andric   case PPC::ORI8:
5340bdd1243dSDimitry Andric   case PPC::XORI8: {
5341bdd1243dSDimitry Andric     Register SrcReg = MI->getOperand(1).getReg();
5342bdd1243dSDimitry Andric     auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI);
5343bdd1243dSDimitry Andric     return std::pair<bool, bool>(SrcExt.first || IsSExt,
5344bdd1243dSDimitry Andric                                  SrcExt.second || IsZExt);
5345bdd1243dSDimitry Andric   }
53460b57cec5SDimitry Andric 
5347bdd1243dSDimitry Andric   // OR, XOR with shifted 16-bit immediate does not change the upper
5348bdd1243dSDimitry Andric   // 32 bits. So, we track the operand register for zero extension.
5349bdd1243dSDimitry Andric   // For sign extension when the MSB of the immediate is zero, we also
5350bdd1243dSDimitry Andric   // track the operand register since the upper 33 bits are unchanged.
5351bdd1243dSDimitry Andric   case PPC::ORIS:
5352bdd1243dSDimitry Andric   case PPC::XORIS:
5353bdd1243dSDimitry Andric   case PPC::ORIS8:
5354bdd1243dSDimitry Andric   case PPC::XORIS8: {
5355bdd1243dSDimitry Andric     Register SrcReg = MI->getOperand(1).getReg();
5356bdd1243dSDimitry Andric     auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth, MRI);
5357bdd1243dSDimitry Andric     uint16_t Imm = MI->getOperand(2).getImm();
5358bdd1243dSDimitry Andric     if (Imm & 0x8000)
5359bdd1243dSDimitry Andric       return std::pair<bool, bool>(false, SrcExt.second || IsZExt);
5360bdd1243dSDimitry Andric     else
5361bdd1243dSDimitry Andric       return std::pair<bool, bool>(SrcExt.first || IsSExt,
5362bdd1243dSDimitry Andric                                    SrcExt.second || IsZExt);
53630b57cec5SDimitry Andric   }
53640b57cec5SDimitry Andric 
53650b57cec5SDimitry Andric   // If all incoming values are sign-/zero-extended,
53660b57cec5SDimitry Andric   // the output of OR, ISEL or PHI is also sign-/zero-extended.
53670b57cec5SDimitry Andric   case PPC::OR:
53680b57cec5SDimitry Andric   case PPC::OR8:
53690b57cec5SDimitry Andric   case PPC::ISEL:
53700b57cec5SDimitry Andric   case PPC::PHI: {
5371bdd1243dSDimitry Andric     if (BinOpDepth >= MAX_BINOP_DEPTH)
5372bdd1243dSDimitry Andric       return std::pair<bool, bool>(false, false);
53730b57cec5SDimitry Andric 
53740b57cec5SDimitry Andric     // The input registers for PHI are operand 1, 3, ...
53750b57cec5SDimitry Andric     // The input registers for others are operand 1 and 2.
5376bdd1243dSDimitry Andric     unsigned OperandEnd = 3, OperandStride = 1;
5377bdd1243dSDimitry Andric     if (MI->getOpcode() == PPC::PHI) {
5378bdd1243dSDimitry Andric       OperandEnd = MI->getNumOperands();
5379bdd1243dSDimitry Andric       OperandStride = 2;
53800b57cec5SDimitry Andric     }
53810b57cec5SDimitry Andric 
5382bdd1243dSDimitry Andric     IsSExt = true;
5383bdd1243dSDimitry Andric     IsZExt = true;
5384bdd1243dSDimitry Andric     for (unsigned I = 1; I != OperandEnd; I += OperandStride) {
5385bdd1243dSDimitry Andric       if (!MI->getOperand(I).isReg())
5386bdd1243dSDimitry Andric         return std::pair<bool, bool>(false, false);
5387bdd1243dSDimitry Andric 
5388bdd1243dSDimitry Andric       Register SrcReg = MI->getOperand(I).getReg();
5389bdd1243dSDimitry Andric       auto SrcExt = isSignOrZeroExtended(SrcReg, BinOpDepth + 1, MRI);
5390bdd1243dSDimitry Andric       IsSExt &= SrcExt.first;
5391bdd1243dSDimitry Andric       IsZExt &= SrcExt.second;
53920b57cec5SDimitry Andric     }
5393bdd1243dSDimitry Andric     return std::pair<bool, bool>(IsSExt, IsZExt);
53940b57cec5SDimitry Andric   }
53950b57cec5SDimitry Andric 
53960b57cec5SDimitry Andric   // If at least one of the incoming values of an AND is zero extended
53970b57cec5SDimitry Andric   // then the output is also zero-extended. If both of the incoming values
53980b57cec5SDimitry Andric   // are sign-extended then the output is also sign extended.
53990b57cec5SDimitry Andric   case PPC::AND:
54000b57cec5SDimitry Andric   case PPC::AND8: {
5401bdd1243dSDimitry Andric     if (BinOpDepth >= MAX_BINOP_DEPTH)
5402bdd1243dSDimitry Andric       return std::pair<bool, bool>(false, false);
54030b57cec5SDimitry Andric 
5404bdd1243dSDimitry Andric     Register SrcReg1 = MI->getOperand(1).getReg();
5405bdd1243dSDimitry Andric     Register SrcReg2 = MI->getOperand(2).getReg();
5406bdd1243dSDimitry Andric     auto Src1Ext = isSignOrZeroExtended(SrcReg1, BinOpDepth + 1, MRI);
5407bdd1243dSDimitry Andric     auto Src2Ext = isSignOrZeroExtended(SrcReg2, BinOpDepth + 1, MRI);
5408bdd1243dSDimitry Andric     return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5409bdd1243dSDimitry Andric                                  Src1Ext.second || Src2Ext.second);
54100b57cec5SDimitry Andric   }
54110b57cec5SDimitry Andric 
54120b57cec5SDimitry Andric   default:
54130b57cec5SDimitry Andric     break;
54140b57cec5SDimitry Andric   }
5415bdd1243dSDimitry Andric   return std::pair<bool, bool>(IsSExt, IsZExt);
54160b57cec5SDimitry Andric }
54170b57cec5SDimitry Andric 
54180b57cec5SDimitry Andric bool PPCInstrInfo::isBDNZ(unsigned Opcode) const {
54190b57cec5SDimitry Andric   return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
54200b57cec5SDimitry Andric }
54210b57cec5SDimitry Andric 
54228bcb0991SDimitry Andric namespace {
54238bcb0991SDimitry Andric class PPCPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
54248bcb0991SDimitry Andric   MachineInstr *Loop, *EndLoop, *LoopCount;
54258bcb0991SDimitry Andric   MachineFunction *MF;
54268bcb0991SDimitry Andric   const TargetInstrInfo *TII;
54278bcb0991SDimitry Andric   int64_t TripCount;
54288bcb0991SDimitry Andric 
54298bcb0991SDimitry Andric public:
54308bcb0991SDimitry Andric   PPCPipelinerLoopInfo(MachineInstr *Loop, MachineInstr *EndLoop,
54318bcb0991SDimitry Andric                        MachineInstr *LoopCount)
54328bcb0991SDimitry Andric       : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),
54338bcb0991SDimitry Andric         MF(Loop->getParent()->getParent()),
54348bcb0991SDimitry Andric         TII(MF->getSubtarget().getInstrInfo()) {
54358bcb0991SDimitry Andric     // Inspect the Loop instruction up-front, as it may be deleted when we call
54368bcb0991SDimitry Andric     // createTripCountGreaterCondition.
54378bcb0991SDimitry Andric     if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI)
54388bcb0991SDimitry Andric       TripCount = LoopCount->getOperand(1).getImm();
54398bcb0991SDimitry Andric     else
54408bcb0991SDimitry Andric       TripCount = -1;
54410b57cec5SDimitry Andric   }
54420b57cec5SDimitry Andric 
54438bcb0991SDimitry Andric   bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
54448bcb0991SDimitry Andric     // Only ignore the terminator.
54458bcb0991SDimitry Andric     return MI == EndLoop;
54468bcb0991SDimitry Andric   }
54478bcb0991SDimitry Andric 
5448bdd1243dSDimitry Andric   std::optional<bool> createTripCountGreaterCondition(
5449bdd1243dSDimitry Andric       int TC, MachineBasicBlock &MBB,
54508bcb0991SDimitry Andric       SmallVectorImpl<MachineOperand> &Cond) override {
54518bcb0991SDimitry Andric     if (TripCount == -1) {
54528bcb0991SDimitry Andric       // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
54538bcb0991SDimitry Andric       // so we don't need to generate any thing here.
54548bcb0991SDimitry Andric       Cond.push_back(MachineOperand::CreateImm(0));
54558bcb0991SDimitry Andric       Cond.push_back(MachineOperand::CreateReg(
54568bcb0991SDimitry Andric           MF->getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
54578bcb0991SDimitry Andric           true));
54588bcb0991SDimitry Andric       return {};
54598bcb0991SDimitry Andric     }
54608bcb0991SDimitry Andric 
54618bcb0991SDimitry Andric     return TripCount > TC;
54628bcb0991SDimitry Andric   }
54638bcb0991SDimitry Andric 
54648bcb0991SDimitry Andric   void setPreheader(MachineBasicBlock *NewPreheader) override {
54658bcb0991SDimitry Andric     // Do nothing. We want the LOOP setup instruction to stay in the *old*
54668bcb0991SDimitry Andric     // preheader, so we can use BDZ in the prologs to adapt the loop trip count.
54678bcb0991SDimitry Andric   }
54688bcb0991SDimitry Andric 
54698bcb0991SDimitry Andric   void adjustTripCount(int TripCountAdjust) override {
54708bcb0991SDimitry Andric     // If the loop trip count is a compile-time value, then just change the
54718bcb0991SDimitry Andric     // value.
54728bcb0991SDimitry Andric     if (LoopCount->getOpcode() == PPC::LI8 ||
54738bcb0991SDimitry Andric         LoopCount->getOpcode() == PPC::LI) {
54748bcb0991SDimitry Andric       int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;
54758bcb0991SDimitry Andric       LoopCount->getOperand(1).setImm(TripCount);
54768bcb0991SDimitry Andric       return;
54778bcb0991SDimitry Andric     }
54788bcb0991SDimitry Andric 
54798bcb0991SDimitry Andric     // Since BDZ/BDZ8 that we will insert will also decrease the ctr by 1,
54808bcb0991SDimitry Andric     // so we don't need to generate any thing here.
54818bcb0991SDimitry Andric   }
54828bcb0991SDimitry Andric 
54838bcb0991SDimitry Andric   void disposed() override {
54848bcb0991SDimitry Andric     Loop->eraseFromParent();
54858bcb0991SDimitry Andric     // Ensure the loop setup instruction is deleted too.
54868bcb0991SDimitry Andric     LoopCount->eraseFromParent();
54878bcb0991SDimitry Andric   }
54888bcb0991SDimitry Andric };
54898bcb0991SDimitry Andric } // namespace
54908bcb0991SDimitry Andric 
54918bcb0991SDimitry Andric std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
54928bcb0991SDimitry Andric PPCInstrInfo::analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const {
54938bcb0991SDimitry Andric   // We really "analyze" only hardware loops right now.
54948bcb0991SDimitry Andric   MachineBasicBlock::iterator I = LoopBB->getFirstTerminator();
54958bcb0991SDimitry Andric   MachineBasicBlock *Preheader = *LoopBB->pred_begin();
54968bcb0991SDimitry Andric   if (Preheader == LoopBB)
54978bcb0991SDimitry Andric     Preheader = *std::next(LoopBB->pred_begin());
54988bcb0991SDimitry Andric   MachineFunction *MF = Preheader->getParent();
54998bcb0991SDimitry Andric 
55008bcb0991SDimitry Andric   if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {
55018bcb0991SDimitry Andric     SmallPtrSet<MachineBasicBlock *, 8> Visited;
55028bcb0991SDimitry Andric     if (MachineInstr *LoopInst = findLoopInstr(*Preheader, Visited)) {
55038bcb0991SDimitry Andric       Register LoopCountReg = LoopInst->getOperand(0).getReg();
55048bcb0991SDimitry Andric       MachineRegisterInfo &MRI = MF->getRegInfo();
55058bcb0991SDimitry Andric       MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);
55068bcb0991SDimitry Andric       return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*I, LoopCount);
55078bcb0991SDimitry Andric     }
55088bcb0991SDimitry Andric   }
55098bcb0991SDimitry Andric   return nullptr;
55108bcb0991SDimitry Andric }
55118bcb0991SDimitry Andric 
55128bcb0991SDimitry Andric MachineInstr *PPCInstrInfo::findLoopInstr(
55138bcb0991SDimitry Andric     MachineBasicBlock &PreHeader,
55148bcb0991SDimitry Andric     SmallPtrSet<MachineBasicBlock *, 8> &Visited) const {
55150b57cec5SDimitry Andric 
55160b57cec5SDimitry Andric   unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
55170b57cec5SDimitry Andric 
55180b57cec5SDimitry Andric   // The loop set-up instruction should be in preheader
55190b57cec5SDimitry Andric   for (auto &I : PreHeader.instrs())
55200b57cec5SDimitry Andric     if (I.getOpcode() == LOOPi)
55210b57cec5SDimitry Andric       return &I;
55220b57cec5SDimitry Andric   return nullptr;
55230b57cec5SDimitry Andric }
55240b57cec5SDimitry Andric 
55250b57cec5SDimitry Andric // Return true if get the base operand, byte offset of an instruction and the
55260b57cec5SDimitry Andric // memory width. Width is the size of memory that is being loaded/stored.
55270b57cec5SDimitry Andric bool PPCInstrInfo::getMemOperandWithOffsetWidth(
5528480093f4SDimitry Andric     const MachineInstr &LdSt, const MachineOperand *&BaseReg, int64_t &Offset,
55290fca6ea1SDimitry Andric     LocationSize &Width, const TargetRegisterInfo *TRI) const {
5530e8d8bef9SDimitry Andric   if (!LdSt.mayLoadOrStore() || LdSt.getNumExplicitOperands() != 3)
5531480093f4SDimitry Andric     return false;
55320b57cec5SDimitry Andric 
55330b57cec5SDimitry Andric   // Handle only loads/stores with base register followed by immediate offset.
5534e8d8bef9SDimitry Andric   if (!LdSt.getOperand(1).isImm() ||
5535e8d8bef9SDimitry Andric       (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
55360b57cec5SDimitry Andric     return false;
5537e8d8bef9SDimitry Andric   if (!LdSt.getOperand(1).isImm() ||
5538e8d8bef9SDimitry Andric       (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()))
55390b57cec5SDimitry Andric     return false;
55400b57cec5SDimitry Andric 
55410b57cec5SDimitry Andric   if (!LdSt.hasOneMemOperand())
55420b57cec5SDimitry Andric     return false;
55430b57cec5SDimitry Andric 
55440b57cec5SDimitry Andric   Width = (*LdSt.memoperands_begin())->getSize();
55450b57cec5SDimitry Andric   Offset = LdSt.getOperand(1).getImm();
55460b57cec5SDimitry Andric   BaseReg = &LdSt.getOperand(2);
55470b57cec5SDimitry Andric   return true;
55480b57cec5SDimitry Andric }
55490b57cec5SDimitry Andric 
55500b57cec5SDimitry Andric bool PPCInstrInfo::areMemAccessesTriviallyDisjoint(
55518bcb0991SDimitry Andric     const MachineInstr &MIa, const MachineInstr &MIb) const {
55520b57cec5SDimitry Andric   assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
55530b57cec5SDimitry Andric   assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
55540b57cec5SDimitry Andric 
55550b57cec5SDimitry Andric   if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
55560b57cec5SDimitry Andric       MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
55570b57cec5SDimitry Andric     return false;
55580b57cec5SDimitry Andric 
55590b57cec5SDimitry Andric   // Retrieve the base register, offset from the base register and width. Width
55600b57cec5SDimitry Andric   // is the size of memory that is being loaded/stored (e.g. 1, 2, 4).  If
55610b57cec5SDimitry Andric   // base registers are identical, and the offset of a lower memory access +
55620b57cec5SDimitry Andric   // the width doesn't overlap the offset of a higher memory access,
55630b57cec5SDimitry Andric   // then the memory accesses are different.
55640b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = &getRegisterInfo();
55650b57cec5SDimitry Andric   const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;
55660b57cec5SDimitry Andric   int64_t OffsetA = 0, OffsetB = 0;
55670fca6ea1SDimitry Andric   LocationSize WidthA = 0, WidthB = 0;
55680b57cec5SDimitry Andric   if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, WidthA, TRI) &&
55690b57cec5SDimitry Andric       getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, WidthB, TRI)) {
55700b57cec5SDimitry Andric     if (BaseOpA->isIdenticalTo(*BaseOpB)) {
55710b57cec5SDimitry Andric       int LowOffset = std::min(OffsetA, OffsetB);
55720b57cec5SDimitry Andric       int HighOffset = std::max(OffsetA, OffsetB);
55730fca6ea1SDimitry Andric       LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
55740fca6ea1SDimitry Andric       if (LowWidth.hasValue() &&
55750fca6ea1SDimitry Andric           LowOffset + (int)LowWidth.getValue() <= HighOffset)
55760b57cec5SDimitry Andric         return true;
55770b57cec5SDimitry Andric     }
55780b57cec5SDimitry Andric   }
55790b57cec5SDimitry Andric   return false;
55800b57cec5SDimitry Andric }
5581