xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCFastISel.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- PPCFastISel.cpp - PowerPC FastISel implementation -----------------===//
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 defines the PowerPC-specific support for the FastISel class. Some
100b57cec5SDimitry Andric // of the target-specific code is generated by tablegen in the file
110b57cec5SDimitry Andric // PPCGenFastISel.inc, which is #included here.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "MCTargetDesc/PPCPredicates.h"
160b57cec5SDimitry Andric #include "PPC.h"
170b57cec5SDimitry Andric #include "PPCCCState.h"
180b57cec5SDimitry Andric #include "PPCCallingConv.h"
190b57cec5SDimitry Andric #include "PPCISelLowering.h"
200b57cec5SDimitry Andric #include "PPCMachineFunctionInfo.h"
210b57cec5SDimitry Andric #include "PPCSubtarget.h"
220b57cec5SDimitry Andric #include "PPCTargetMachine.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/FastISel.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/FunctionLoweringInfo.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
310b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
320b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
330b57cec5SDimitry Andric #include "llvm/IR/GlobalAlias.h"
340b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h"
350b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
360b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
370b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
380b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
410b57cec5SDimitry Andric //
420b57cec5SDimitry Andric // TBD:
430b57cec5SDimitry Andric //   fastLowerArguments: Handle simple cases.
440b57cec5SDimitry Andric //   PPCMaterializeGV: Handle TLS.
450b57cec5SDimitry Andric //   SelectCall: Handle function pointers.
460b57cec5SDimitry Andric //   SelectCall: Handle multi-register return values.
470b57cec5SDimitry Andric //   SelectCall: Optimize away nops for local calls.
480b57cec5SDimitry Andric //   processCallArgs: Handle bit-converted arguments.
490b57cec5SDimitry Andric //   finishCall: Handle multi-register return values.
500b57cec5SDimitry Andric //   PPCComputeAddress: Handle parameter references as FrameIndex's.
510b57cec5SDimitry Andric //   PPCEmitCmp: Handle immediate as operand 1.
520b57cec5SDimitry Andric //   SelectCall: Handle small byval arguments.
530b57cec5SDimitry Andric //   SelectIntrinsicCall: Implement.
540b57cec5SDimitry Andric //   SelectSelect: Implement.
550b57cec5SDimitry Andric //   Consider factoring isTypeLegal into the base class.
560b57cec5SDimitry Andric //   Implement switches and jump tables.
570b57cec5SDimitry Andric //
580b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
590b57cec5SDimitry Andric using namespace llvm;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric #define DEBUG_TYPE "ppcfastisel"
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric namespace {
640b57cec5SDimitry Andric 
65fe6060f1SDimitry Andric struct Address {
660b57cec5SDimitry Andric   enum {
670b57cec5SDimitry Andric     RegBase,
680b57cec5SDimitry Andric     FrameIndexBase
690b57cec5SDimitry Andric   } BaseType;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   union {
720b57cec5SDimitry Andric     unsigned Reg;
730b57cec5SDimitry Andric     int FI;
740b57cec5SDimitry Andric   } Base;
750b57cec5SDimitry Andric 
76bdd1243dSDimitry Andric   int64_t Offset;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // Innocuous defaults for our address.
790b57cec5SDimitry Andric   Address()
800b57cec5SDimitry Andric    : BaseType(RegBase), Offset(0) {
810b57cec5SDimitry Andric      Base.Reg = 0;
820b57cec5SDimitry Andric    }
83fe6060f1SDimitry Andric };
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric class PPCFastISel final : public FastISel {
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   const TargetMachine &TM;
885ffd83dbSDimitry Andric   const PPCSubtarget *Subtarget;
890b57cec5SDimitry Andric   PPCFunctionInfo *PPCFuncInfo;
900b57cec5SDimitry Andric   const TargetInstrInfo &TII;
910b57cec5SDimitry Andric   const TargetLowering &TLI;
920b57cec5SDimitry Andric   LLVMContext *Context;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   public:
950b57cec5SDimitry Andric     explicit PPCFastISel(FunctionLoweringInfo &FuncInfo,
960b57cec5SDimitry Andric                          const TargetLibraryInfo *LibInfo)
970b57cec5SDimitry Andric         : FastISel(FuncInfo, LibInfo), TM(FuncInfo.MF->getTarget()),
985ffd83dbSDimitry Andric           Subtarget(&FuncInfo.MF->getSubtarget<PPCSubtarget>()),
990b57cec5SDimitry Andric           PPCFuncInfo(FuncInfo.MF->getInfo<PPCFunctionInfo>()),
1005ffd83dbSDimitry Andric           TII(*Subtarget->getInstrInfo()), TLI(*Subtarget->getTargetLowering()),
1010b57cec5SDimitry Andric           Context(&FuncInfo.Fn->getContext()) {}
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric     // Backend specific FastISel code.
1040b57cec5SDimitry Andric   private:
1050b57cec5SDimitry Andric     bool fastSelectInstruction(const Instruction *I) override;
1060b57cec5SDimitry Andric     unsigned fastMaterializeConstant(const Constant *C) override;
1070b57cec5SDimitry Andric     unsigned fastMaterializeAlloca(const AllocaInst *AI) override;
1080b57cec5SDimitry Andric     bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
1090b57cec5SDimitry Andric                              const LoadInst *LI) override;
1100b57cec5SDimitry Andric     bool fastLowerArguments() override;
1110b57cec5SDimitry Andric     unsigned fastEmit_i(MVT Ty, MVT RetTy, unsigned Opc, uint64_t Imm) override;
1120b57cec5SDimitry Andric     unsigned fastEmitInst_ri(unsigned MachineInstOpcode,
1130b57cec5SDimitry Andric                              const TargetRegisterClass *RC,
114fe6060f1SDimitry Andric                              unsigned Op0, uint64_t Imm);
1150b57cec5SDimitry Andric     unsigned fastEmitInst_r(unsigned MachineInstOpcode,
116fe6060f1SDimitry Andric                             const TargetRegisterClass *RC, unsigned Op0);
1170b57cec5SDimitry Andric     unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
1180b57cec5SDimitry Andric                              const TargetRegisterClass *RC,
119fe6060f1SDimitry Andric                              unsigned Op0, unsigned Op1);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric     bool fastLowerCall(CallLoweringInfo &CLI) override;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // Instruction selection routines.
1240b57cec5SDimitry Andric   private:
1250b57cec5SDimitry Andric     bool SelectLoad(const Instruction *I);
1260b57cec5SDimitry Andric     bool SelectStore(const Instruction *I);
1270b57cec5SDimitry Andric     bool SelectBranch(const Instruction *I);
1280b57cec5SDimitry Andric     bool SelectIndirectBr(const Instruction *I);
1290b57cec5SDimitry Andric     bool SelectFPExt(const Instruction *I);
1300b57cec5SDimitry Andric     bool SelectFPTrunc(const Instruction *I);
1310b57cec5SDimitry Andric     bool SelectIToFP(const Instruction *I, bool IsSigned);
1320b57cec5SDimitry Andric     bool SelectFPToI(const Instruction *I, bool IsSigned);
1330b57cec5SDimitry Andric     bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);
1340b57cec5SDimitry Andric     bool SelectRet(const Instruction *I);
1350b57cec5SDimitry Andric     bool SelectTrunc(const Instruction *I);
1360b57cec5SDimitry Andric     bool SelectIntExt(const Instruction *I);
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   // Utility routines.
1390b57cec5SDimitry Andric   private:
1400b57cec5SDimitry Andric     bool isTypeLegal(Type *Ty, MVT &VT);
1410b57cec5SDimitry Andric     bool isLoadTypeLegal(Type *Ty, MVT &VT);
1420b57cec5SDimitry Andric     bool isValueAvailable(const Value *V) const;
1430b57cec5SDimitry Andric     bool isVSFRCRegClass(const TargetRegisterClass *RC) const {
1440b57cec5SDimitry Andric       return RC->getID() == PPC::VSFRCRegClassID;
1450b57cec5SDimitry Andric     }
1460b57cec5SDimitry Andric     bool isVSSRCRegClass(const TargetRegisterClass *RC) const {
1470b57cec5SDimitry Andric       return RC->getID() == PPC::VSSRCRegClassID;
1480b57cec5SDimitry Andric     }
1490b57cec5SDimitry Andric     unsigned copyRegToRegClass(const TargetRegisterClass *ToRC,
1500b57cec5SDimitry Andric                                unsigned SrcReg, unsigned Flag = 0,
1510b57cec5SDimitry Andric                                unsigned SubReg = 0) {
15204eeddc0SDimitry Andric       Register TmpReg = createResultReg(ToRC);
153bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
1540b57cec5SDimitry Andric               TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg, Flag, SubReg);
1550b57cec5SDimitry Andric       return TmpReg;
1560b57cec5SDimitry Andric     }
1570b57cec5SDimitry Andric     bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value,
1580b57cec5SDimitry Andric                     bool isZExt, unsigned DestReg,
1590b57cec5SDimitry Andric                     const PPC::Predicate Pred);
1608bcb0991SDimitry Andric     bool PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
1610b57cec5SDimitry Andric                      const TargetRegisterClass *RC, bool IsZExt = true,
1620b57cec5SDimitry Andric                      unsigned FP64LoadOpc = PPC::LFD);
1630b57cec5SDimitry Andric     bool PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr);
1640b57cec5SDimitry Andric     bool PPCComputeAddress(const Value *Obj, Address &Addr);
1650b57cec5SDimitry Andric     void PPCSimplifyAddress(Address &Addr, bool &UseOffset,
1660b57cec5SDimitry Andric                             unsigned &IndexReg);
1670b57cec5SDimitry Andric     bool PPCEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
1680b57cec5SDimitry Andric                            unsigned DestReg, bool IsZExt);
1690b57cec5SDimitry Andric     unsigned PPCMaterializeFP(const ConstantFP *CFP, MVT VT);
1700b57cec5SDimitry Andric     unsigned PPCMaterializeGV(const GlobalValue *GV, MVT VT);
1710b57cec5SDimitry Andric     unsigned PPCMaterializeInt(const ConstantInt *CI, MVT VT,
1720b57cec5SDimitry Andric                                bool UseSExt = true);
1730b57cec5SDimitry Andric     unsigned PPCMaterialize32BitInt(int64_t Imm,
1740b57cec5SDimitry Andric                                     const TargetRegisterClass *RC);
1750b57cec5SDimitry Andric     unsigned PPCMaterialize64BitInt(int64_t Imm,
1760b57cec5SDimitry Andric                                     const TargetRegisterClass *RC);
1770b57cec5SDimitry Andric     unsigned PPCMoveToIntReg(const Instruction *I, MVT VT,
1780b57cec5SDimitry Andric                              unsigned SrcReg, bool IsSigned);
1790b57cec5SDimitry Andric     unsigned PPCMoveToFPReg(MVT VT, unsigned SrcReg, bool IsSigned);
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   // Call handling routines.
1820b57cec5SDimitry Andric   private:
1830b57cec5SDimitry Andric     bool processCallArgs(SmallVectorImpl<Value*> &Args,
1840b57cec5SDimitry Andric                          SmallVectorImpl<unsigned> &ArgRegs,
1850b57cec5SDimitry Andric                          SmallVectorImpl<MVT> &ArgVTs,
1860b57cec5SDimitry Andric                          SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
1870b57cec5SDimitry Andric                          SmallVectorImpl<unsigned> &RegArgs,
1880b57cec5SDimitry Andric                          CallingConv::ID CC,
1890b57cec5SDimitry Andric                          unsigned &NumBytes,
1900b57cec5SDimitry Andric                          bool IsVarArg);
1910b57cec5SDimitry Andric     bool finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes);
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   private:
1940b57cec5SDimitry Andric   #include "PPCGenFastISel.inc"
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric };
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric } // end anonymous namespace
1990b57cec5SDimitry Andric 
200bdd1243dSDimitry Andric static std::optional<PPC::Predicate> getComparePred(CmpInst::Predicate Pred) {
2010b57cec5SDimitry Andric     switch (Pred) {
2020b57cec5SDimitry Andric     // These are not representable with any single compare.
2030b57cec5SDimitry Andric     case CmpInst::FCMP_FALSE:
2040b57cec5SDimitry Andric     case CmpInst::FCMP_TRUE:
2050b57cec5SDimitry Andric     // Major concern about the following 6 cases is NaN result. The comparison
2060b57cec5SDimitry Andric     // result consists of 4 bits, indicating lt, eq, gt and un (unordered),
2070b57cec5SDimitry Andric     // only one of which will be set. The result is generated by fcmpu
2080b57cec5SDimitry Andric     // instruction. However, bc instruction only inspects one of the first 3
2090b57cec5SDimitry Andric     // bits, so when un is set, bc instruction may jump to an undesired
2100b57cec5SDimitry Andric     // place.
2110b57cec5SDimitry Andric     //
2120b57cec5SDimitry Andric     // More specifically, if we expect an unordered comparison and un is set, we
2130b57cec5SDimitry Andric     // expect to always go to true branch; in such case UEQ, UGT and ULT still
2140b57cec5SDimitry Andric     // give false, which are undesired; but UNE, UGE, ULE happen to give true,
2150b57cec5SDimitry Andric     // since they are tested by inspecting !eq, !lt, !gt, respectively.
2160b57cec5SDimitry Andric     //
2170b57cec5SDimitry Andric     // Similarly, for ordered comparison, when un is set, we always expect the
2180b57cec5SDimitry Andric     // result to be false. In such case OGT, OLT and OEQ is good, since they are
2190b57cec5SDimitry Andric     // actually testing GT, LT, and EQ respectively, which are false. OGE, OLE
2200b57cec5SDimitry Andric     // and ONE are tested through !lt, !gt and !eq, and these are true.
2210b57cec5SDimitry Andric     case CmpInst::FCMP_UEQ:
2220b57cec5SDimitry Andric     case CmpInst::FCMP_UGT:
2230b57cec5SDimitry Andric     case CmpInst::FCMP_ULT:
2240b57cec5SDimitry Andric     case CmpInst::FCMP_OGE:
2250b57cec5SDimitry Andric     case CmpInst::FCMP_OLE:
2260b57cec5SDimitry Andric     case CmpInst::FCMP_ONE:
2270b57cec5SDimitry Andric     default:
228bdd1243dSDimitry Andric       return std::nullopt;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     case CmpInst::FCMP_OEQ:
2310b57cec5SDimitry Andric     case CmpInst::ICMP_EQ:
2320b57cec5SDimitry Andric       return PPC::PRED_EQ;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric     case CmpInst::FCMP_OGT:
2350b57cec5SDimitry Andric     case CmpInst::ICMP_UGT:
2360b57cec5SDimitry Andric     case CmpInst::ICMP_SGT:
2370b57cec5SDimitry Andric       return PPC::PRED_GT;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     case CmpInst::FCMP_UGE:
2400b57cec5SDimitry Andric     case CmpInst::ICMP_UGE:
2410b57cec5SDimitry Andric     case CmpInst::ICMP_SGE:
2420b57cec5SDimitry Andric       return PPC::PRED_GE;
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric     case CmpInst::FCMP_OLT:
2450b57cec5SDimitry Andric     case CmpInst::ICMP_ULT:
2460b57cec5SDimitry Andric     case CmpInst::ICMP_SLT:
2470b57cec5SDimitry Andric       return PPC::PRED_LT;
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric     case CmpInst::FCMP_ULE:
2500b57cec5SDimitry Andric     case CmpInst::ICMP_ULE:
2510b57cec5SDimitry Andric     case CmpInst::ICMP_SLE:
2520b57cec5SDimitry Andric       return PPC::PRED_LE;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric     case CmpInst::FCMP_UNE:
2550b57cec5SDimitry Andric     case CmpInst::ICMP_NE:
2560b57cec5SDimitry Andric       return PPC::PRED_NE;
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric     case CmpInst::FCMP_ORD:
2590b57cec5SDimitry Andric       return PPC::PRED_NU;
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric     case CmpInst::FCMP_UNO:
2620b57cec5SDimitry Andric       return PPC::PRED_UN;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric // Determine whether the type Ty is simple enough to be handled by
2670b57cec5SDimitry Andric // fast-isel, and return its equivalent machine type in VT.
2680b57cec5SDimitry Andric // FIXME: Copied directly from ARM -- factor into base class?
2690b57cec5SDimitry Andric bool PPCFastISel::isTypeLegal(Type *Ty, MVT &VT) {
2700b57cec5SDimitry Andric   EVT Evt = TLI.getValueType(DL, Ty, true);
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   // Only handle simple types.
2730b57cec5SDimitry Andric   if (Evt == MVT::Other || !Evt.isSimple()) return false;
2740b57cec5SDimitry Andric   VT = Evt.getSimpleVT();
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   // Handle all legal types, i.e. a register that will directly hold this
2770b57cec5SDimitry Andric   // value.
2780b57cec5SDimitry Andric   return TLI.isTypeLegal(VT);
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric // Determine whether the type Ty is simple enough to be handled by
2820b57cec5SDimitry Andric // fast-isel as a load target, and return its equivalent machine type in VT.
2830b57cec5SDimitry Andric bool PPCFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {
2840b57cec5SDimitry Andric   if (isTypeLegal(Ty, VT)) return true;
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   // If this is a type than can be sign or zero-extended to a basic operation
2870b57cec5SDimitry Andric   // go ahead and accept it now.
2880b57cec5SDimitry Andric   if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {
2890b57cec5SDimitry Andric     return true;
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   return false;
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric bool PPCFastISel::isValueAvailable(const Value *V) const {
2960b57cec5SDimitry Andric   if (!isa<Instruction>(V))
2970b57cec5SDimitry Andric     return true;
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   const auto *I = cast<Instruction>(V);
3000b57cec5SDimitry Andric   return FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB;
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric // Given a value Obj, create an Address object Addr that represents its
3040b57cec5SDimitry Andric // address.  Return false if we can't handle it.
3050b57cec5SDimitry Andric bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {
3060b57cec5SDimitry Andric   const User *U = nullptr;
3070b57cec5SDimitry Andric   unsigned Opcode = Instruction::UserOp1;
3080b57cec5SDimitry Andric   if (const Instruction *I = dyn_cast<Instruction>(Obj)) {
3090b57cec5SDimitry Andric     // Don't walk into other basic blocks unless the object is an alloca from
3100b57cec5SDimitry Andric     // another block, otherwise it may not have a virtual register assigned.
3110b57cec5SDimitry Andric     if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||
3120b57cec5SDimitry Andric         FuncInfo.MBBMap[I->getParent()] == FuncInfo.MBB) {
3130b57cec5SDimitry Andric       Opcode = I->getOpcode();
3140b57cec5SDimitry Andric       U = I;
3150b57cec5SDimitry Andric     }
3160b57cec5SDimitry Andric   } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) {
3170b57cec5SDimitry Andric     Opcode = C->getOpcode();
3180b57cec5SDimitry Andric     U = C;
3190b57cec5SDimitry Andric   }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   switch (Opcode) {
3220b57cec5SDimitry Andric     default:
3230b57cec5SDimitry Andric       break;
3240b57cec5SDimitry Andric     case Instruction::BitCast:
3250b57cec5SDimitry Andric       // Look through bitcasts.
3260b57cec5SDimitry Andric       return PPCComputeAddress(U->getOperand(0), Addr);
3270b57cec5SDimitry Andric     case Instruction::IntToPtr:
3280b57cec5SDimitry Andric       // Look past no-op inttoptrs.
3290b57cec5SDimitry Andric       if (TLI.getValueType(DL, U->getOperand(0)->getType()) ==
3300b57cec5SDimitry Andric           TLI.getPointerTy(DL))
3310b57cec5SDimitry Andric         return PPCComputeAddress(U->getOperand(0), Addr);
3320b57cec5SDimitry Andric       break;
3330b57cec5SDimitry Andric     case Instruction::PtrToInt:
3340b57cec5SDimitry Andric       // Look past no-op ptrtoints.
3350b57cec5SDimitry Andric       if (TLI.getValueType(DL, U->getType()) == TLI.getPointerTy(DL))
3360b57cec5SDimitry Andric         return PPCComputeAddress(U->getOperand(0), Addr);
3370b57cec5SDimitry Andric       break;
3380b57cec5SDimitry Andric     case Instruction::GetElementPtr: {
3390b57cec5SDimitry Andric       Address SavedAddr = Addr;
340bdd1243dSDimitry Andric       int64_t TmpOffset = Addr.Offset;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric       // Iterate through the GEP folding the constants into offsets where
3430b57cec5SDimitry Andric       // we can.
3440b57cec5SDimitry Andric       gep_type_iterator GTI = gep_type_begin(U);
3450b57cec5SDimitry Andric       for (User::const_op_iterator II = U->op_begin() + 1, IE = U->op_end();
3460b57cec5SDimitry Andric            II != IE; ++II, ++GTI) {
3470b57cec5SDimitry Andric         const Value *Op = *II;
3480b57cec5SDimitry Andric         if (StructType *STy = GTI.getStructTypeOrNull()) {
3490b57cec5SDimitry Andric           const StructLayout *SL = DL.getStructLayout(STy);
3500b57cec5SDimitry Andric           unsigned Idx = cast<ConstantInt>(Op)->getZExtValue();
3510b57cec5SDimitry Andric           TmpOffset += SL->getElementOffset(Idx);
3520b57cec5SDimitry Andric         } else {
3531db9f3b2SDimitry Andric           uint64_t S = GTI.getSequentialElementStride(DL);
3540b57cec5SDimitry Andric           for (;;) {
3550b57cec5SDimitry Andric             if (const ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
3560b57cec5SDimitry Andric               // Constant-offset addressing.
3570b57cec5SDimitry Andric               TmpOffset += CI->getSExtValue() * S;
3580b57cec5SDimitry Andric               break;
3590b57cec5SDimitry Andric             }
3600b57cec5SDimitry Andric             if (canFoldAddIntoGEP(U, Op)) {
3610b57cec5SDimitry Andric               // A compatible add with a constant operand. Fold the constant.
3620b57cec5SDimitry Andric               ConstantInt *CI =
3630b57cec5SDimitry Andric               cast<ConstantInt>(cast<AddOperator>(Op)->getOperand(1));
3640b57cec5SDimitry Andric               TmpOffset += CI->getSExtValue() * S;
3650b57cec5SDimitry Andric               // Iterate on the other operand.
3660b57cec5SDimitry Andric               Op = cast<AddOperator>(Op)->getOperand(0);
3670b57cec5SDimitry Andric               continue;
3680b57cec5SDimitry Andric             }
3690b57cec5SDimitry Andric             // Unsupported
3700b57cec5SDimitry Andric             goto unsupported_gep;
3710b57cec5SDimitry Andric           }
3720b57cec5SDimitry Andric         }
3730b57cec5SDimitry Andric       }
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric       // Try to grab the base operand now.
3760b57cec5SDimitry Andric       Addr.Offset = TmpOffset;
3770b57cec5SDimitry Andric       if (PPCComputeAddress(U->getOperand(0), Addr)) return true;
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric       // We failed, restore everything and try the other options.
3800b57cec5SDimitry Andric       Addr = SavedAddr;
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric       unsupported_gep:
3830b57cec5SDimitry Andric       break;
3840b57cec5SDimitry Andric     }
3850b57cec5SDimitry Andric     case Instruction::Alloca: {
3860b57cec5SDimitry Andric       const AllocaInst *AI = cast<AllocaInst>(Obj);
3870b57cec5SDimitry Andric       DenseMap<const AllocaInst*, int>::iterator SI =
3880b57cec5SDimitry Andric         FuncInfo.StaticAllocaMap.find(AI);
3890b57cec5SDimitry Andric       if (SI != FuncInfo.StaticAllocaMap.end()) {
3900b57cec5SDimitry Andric         Addr.BaseType = Address::FrameIndexBase;
3910b57cec5SDimitry Andric         Addr.Base.FI = SI->second;
3920b57cec5SDimitry Andric         return true;
3930b57cec5SDimitry Andric       }
3940b57cec5SDimitry Andric       break;
3950b57cec5SDimitry Andric     }
3960b57cec5SDimitry Andric   }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   // FIXME: References to parameters fall through to the behavior
3990b57cec5SDimitry Andric   // below.  They should be able to reference a frame index since
4000b57cec5SDimitry Andric   // they are stored to the stack, so we can get "ld rx, offset(r1)"
4010b57cec5SDimitry Andric   // instead of "addi ry, r1, offset / ld rx, 0(ry)".  Obj will
4020b57cec5SDimitry Andric   // just contain the parameter.  Try to handle this with a FI.
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   // Try to get this in a register if nothing else has worked.
4050b57cec5SDimitry Andric   if (Addr.Base.Reg == 0)
4060b57cec5SDimitry Andric     Addr.Base.Reg = getRegForValue(Obj);
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   // Prevent assignment of base register to X0, which is inappropriate
4090b57cec5SDimitry Andric   // for loads and stores alike.
4100b57cec5SDimitry Andric   if (Addr.Base.Reg != 0)
4110b57cec5SDimitry Andric     MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   return Addr.Base.Reg != 0;
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric // Fix up some addresses that can't be used directly.  For example, if
4170b57cec5SDimitry Andric // an offset won't fit in an instruction field, we may need to move it
4180b57cec5SDimitry Andric // into an index register.
4190b57cec5SDimitry Andric void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,
4200b57cec5SDimitry Andric                                      unsigned &IndexReg) {
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric   // Check whether the offset fits in the instruction field.
4230b57cec5SDimitry Andric   if (!isInt<16>(Addr.Offset))
4240b57cec5SDimitry Andric     UseOffset = false;
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   // If this is a stack pointer and the offset needs to be simplified then
4270b57cec5SDimitry Andric   // put the alloca address into a register, set the base type back to
4280b57cec5SDimitry Andric   // register and continue. This should almost never happen.
4290b57cec5SDimitry Andric   if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {
43004eeddc0SDimitry Andric     Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
431bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
4320b57cec5SDimitry Andric             ResultReg).addFrameIndex(Addr.Base.FI).addImm(0);
4330b57cec5SDimitry Andric     Addr.Base.Reg = ResultReg;
4340b57cec5SDimitry Andric     Addr.BaseType = Address::RegBase;
4350b57cec5SDimitry Andric   }
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   if (!UseOffset) {
4380b57cec5SDimitry Andric     IntegerType *OffsetTy = Type::getInt64Ty(*Context);
439bdd1243dSDimitry Andric     const ConstantInt *Offset = ConstantInt::getSigned(OffsetTy, Addr.Offset);
4400b57cec5SDimitry Andric     IndexReg = PPCMaterializeInt(Offset, MVT::i64);
4410b57cec5SDimitry Andric     assert(IndexReg && "Unexpected error in PPCMaterializeInt!");
4420b57cec5SDimitry Andric   }
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric // Emit a load instruction if possible, returning true if we succeeded,
4460b57cec5SDimitry Andric // otherwise false.  See commentary below for how the register class of
4470b57cec5SDimitry Andric // the load is determined.
4488bcb0991SDimitry Andric bool PPCFastISel::PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,
4490b57cec5SDimitry Andric                               const TargetRegisterClass *RC,
4500b57cec5SDimitry Andric                               bool IsZExt, unsigned FP64LoadOpc) {
4510b57cec5SDimitry Andric   unsigned Opc;
4520b57cec5SDimitry Andric   bool UseOffset = true;
4535ffd83dbSDimitry Andric   bool HasSPE = Subtarget->hasSPE();
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   // If ResultReg is given, it determines the register class of the load.
4560b57cec5SDimitry Andric   // Otherwise, RC is the register class to use.  If the result of the
4570b57cec5SDimitry Andric   // load isn't anticipated in this block, both may be zero, in which
4580b57cec5SDimitry Andric   // case we must make a conservative guess.  In particular, don't assign
4590b57cec5SDimitry Andric   // R0 or X0 to the result register, as the result may be used in a load,
4600b57cec5SDimitry Andric   // store, add-immediate, or isel that won't permit this.  (Though
4610b57cec5SDimitry Andric   // perhaps the spill and reload of live-exit values would handle this?)
4620b57cec5SDimitry Andric   const TargetRegisterClass *UseRC =
4630b57cec5SDimitry Andric     (ResultReg ? MRI.getRegClass(ResultReg) :
4640b57cec5SDimitry Andric      (RC ? RC :
4650b57cec5SDimitry Andric       (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :
4668bcb0991SDimitry Andric        (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :
4670b57cec5SDimitry Andric         (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
4680b57cec5SDimitry Andric          &PPC::GPRC_and_GPRC_NOR0RegClass)))));
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   bool Is32BitInt = UseRC->hasSuperClassEq(&PPC::GPRCRegClass);
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   switch (VT.SimpleTy) {
4730b57cec5SDimitry Andric     default: // e.g., vector types not handled
4740b57cec5SDimitry Andric       return false;
4750b57cec5SDimitry Andric     case MVT::i8:
4760b57cec5SDimitry Andric       Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;
4770b57cec5SDimitry Andric       break;
4780b57cec5SDimitry Andric     case MVT::i16:
4790b57cec5SDimitry Andric       Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)
4800b57cec5SDimitry Andric                     : (Is32BitInt ? PPC::LHA : PPC::LHA8));
4810b57cec5SDimitry Andric       break;
4820b57cec5SDimitry Andric     case MVT::i32:
4830b57cec5SDimitry Andric       Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)
4840b57cec5SDimitry Andric                     : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));
4850b57cec5SDimitry Andric       if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))
4860b57cec5SDimitry Andric         UseOffset = false;
4870b57cec5SDimitry Andric       break;
4880b57cec5SDimitry Andric     case MVT::i64:
4890b57cec5SDimitry Andric       Opc = PPC::LD;
4900b57cec5SDimitry Andric       assert(UseRC->hasSuperClassEq(&PPC::G8RCRegClass) &&
4910b57cec5SDimitry Andric              "64-bit load with 32-bit target??");
4920b57cec5SDimitry Andric       UseOffset = ((Addr.Offset & 3) == 0);
4930b57cec5SDimitry Andric       break;
4940b57cec5SDimitry Andric     case MVT::f32:
4955ffd83dbSDimitry Andric       Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;
4960b57cec5SDimitry Andric       break;
4970b57cec5SDimitry Andric     case MVT::f64:
4980b57cec5SDimitry Andric       Opc = FP64LoadOpc;
4990b57cec5SDimitry Andric       break;
5000b57cec5SDimitry Andric   }
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   // If necessary, materialize the offset into a register and use
5030b57cec5SDimitry Andric   // the indexed form.  Also handle stack pointers with special needs.
5040b57cec5SDimitry Andric   unsigned IndexReg = 0;
5050b57cec5SDimitry Andric   PPCSimplifyAddress(Addr, UseOffset, IndexReg);
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric   // If this is a potential VSX load with an offset of 0, a VSX indexed load can
5080b57cec5SDimitry Andric   // be used.
5090b57cec5SDimitry Andric   bool IsVSSRC = isVSSRCRegClass(UseRC);
5100b57cec5SDimitry Andric   bool IsVSFRC = isVSFRCRegClass(UseRC);
5110b57cec5SDimitry Andric   bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;
5120b57cec5SDimitry Andric   bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;
5130b57cec5SDimitry Andric   if ((Is32VSXLoad || Is64VSXLoad) &&
5140b57cec5SDimitry Andric       (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
5150b57cec5SDimitry Andric       (Addr.Offset == 0)) {
5160b57cec5SDimitry Andric     UseOffset = false;
5170b57cec5SDimitry Andric   }
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   if (ResultReg == 0)
5200b57cec5SDimitry Andric     ResultReg = createResultReg(UseRC);
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   // Note: If we still have a frame index here, we know the offset is
5230b57cec5SDimitry Andric   // in range, as otherwise PPCSimplifyAddress would have converted it
5240b57cec5SDimitry Andric   // into a RegBase.
5250b57cec5SDimitry Andric   if (Addr.BaseType == Address::FrameIndexBase) {
5260b57cec5SDimitry Andric     // VSX only provides an indexed load.
5270b57cec5SDimitry Andric     if (Is32VSXLoad || Is64VSXLoad) return false;
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric     MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
5300b57cec5SDimitry Andric         MachinePointerInfo::getFixedStack(*FuncInfo.MF, Addr.Base.FI,
5310b57cec5SDimitry Andric                                           Addr.Offset),
5320b57cec5SDimitry Andric         MachineMemOperand::MOLoad, MFI.getObjectSize(Addr.Base.FI),
5335ffd83dbSDimitry Andric         MFI.getObjectAlign(Addr.Base.FI));
5340b57cec5SDimitry Andric 
535bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
5360b57cec5SDimitry Andric       .addImm(Addr.Offset).addFrameIndex(Addr.Base.FI).addMemOperand(MMO);
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   // Base reg with offset in range.
5390b57cec5SDimitry Andric   } else if (UseOffset) {
5400b57cec5SDimitry Andric     // VSX only provides an indexed load.
5410b57cec5SDimitry Andric     if (Is32VSXLoad || Is64VSXLoad) return false;
5420b57cec5SDimitry Andric 
543bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
5440b57cec5SDimitry Andric       .addImm(Addr.Offset).addReg(Addr.Base.Reg);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   // Indexed form.
5470b57cec5SDimitry Andric   } else {
5480b57cec5SDimitry Andric     // Get the RR opcode corresponding to the RI one.  FIXME: It would be
5490b57cec5SDimitry Andric     // preferable to use the ImmToIdxMap from PPCRegisterInfo.cpp, but it
5500b57cec5SDimitry Andric     // is hard to get at.
5510b57cec5SDimitry Andric     switch (Opc) {
5520b57cec5SDimitry Andric       default:        llvm_unreachable("Unexpected opcode!");
5530b57cec5SDimitry Andric       case PPC::LBZ:    Opc = PPC::LBZX;    break;
5540b57cec5SDimitry Andric       case PPC::LBZ8:   Opc = PPC::LBZX8;   break;
5550b57cec5SDimitry Andric       case PPC::LHZ:    Opc = PPC::LHZX;    break;
5560b57cec5SDimitry Andric       case PPC::LHZ8:   Opc = PPC::LHZX8;   break;
5570b57cec5SDimitry Andric       case PPC::LHA:    Opc = PPC::LHAX;    break;
5580b57cec5SDimitry Andric       case PPC::LHA8:   Opc = PPC::LHAX8;   break;
5590b57cec5SDimitry Andric       case PPC::LWZ:    Opc = PPC::LWZX;    break;
5600b57cec5SDimitry Andric       case PPC::LWZ8:   Opc = PPC::LWZX8;   break;
5610b57cec5SDimitry Andric       case PPC::LWA:    Opc = PPC::LWAX;    break;
5620b57cec5SDimitry Andric       case PPC::LWA_32: Opc = PPC::LWAX_32; break;
5630b57cec5SDimitry Andric       case PPC::LD:     Opc = PPC::LDX;     break;
5640b57cec5SDimitry Andric       case PPC::LFS:    Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX; break;
5650b57cec5SDimitry Andric       case PPC::LFD:    Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX; break;
5660b57cec5SDimitry Andric       case PPC::EVLDD:  Opc = PPC::EVLDDX;  break;
5670b57cec5SDimitry Andric       case PPC::SPELWZ: Opc = PPC::SPELWZX;    break;
5680b57cec5SDimitry Andric     }
5690b57cec5SDimitry Andric 
570bdd1243dSDimitry Andric     auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
5710b57cec5SDimitry Andric                        ResultReg);
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric     // If we have an index register defined we use it in the store inst,
5740b57cec5SDimitry Andric     // otherwise we use X0 as base as it makes the vector instructions to
5750b57cec5SDimitry Andric     // use zero in the computation of the effective address regardless the
5760b57cec5SDimitry Andric     // content of the register.
5770b57cec5SDimitry Andric     if (IndexReg)
5780b57cec5SDimitry Andric       MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
5790b57cec5SDimitry Andric     else
5800b57cec5SDimitry Andric       MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
5810b57cec5SDimitry Andric   }
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric   return true;
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric // Attempt to fast-select a load instruction.
5870b57cec5SDimitry Andric bool PPCFastISel::SelectLoad(const Instruction *I) {
5880b57cec5SDimitry Andric   // FIXME: No atomic loads are supported.
5890b57cec5SDimitry Andric   if (cast<LoadInst>(I)->isAtomic())
5900b57cec5SDimitry Andric     return false;
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   // Verify we have a legal type before going any further.
5930b57cec5SDimitry Andric   MVT VT;
5940b57cec5SDimitry Andric   if (!isLoadTypeLegal(I->getType(), VT))
5950b57cec5SDimitry Andric     return false;
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric   // See if we can handle this address.
5980b57cec5SDimitry Andric   Address Addr;
5990b57cec5SDimitry Andric   if (!PPCComputeAddress(I->getOperand(0), Addr))
6000b57cec5SDimitry Andric     return false;
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   // Look at the currently assigned register for this instruction
6030b57cec5SDimitry Andric   // to determine the required register class.  This is necessary
6040b57cec5SDimitry Andric   // to constrain RA from using R0/X0 when this is not legal.
60504eeddc0SDimitry Andric   Register AssignedReg = FuncInfo.ValueMap[I];
6060b57cec5SDimitry Andric   const TargetRegisterClass *RC =
6070b57cec5SDimitry Andric     AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;
6080b57cec5SDimitry Andric 
6098bcb0991SDimitry Andric   Register ResultReg = 0;
6100b57cec5SDimitry Andric   if (!PPCEmitLoad(VT, ResultReg, Addr, RC, true,
6115ffd83dbSDimitry Andric                    Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
6120b57cec5SDimitry Andric     return false;
6130b57cec5SDimitry Andric   updateValueMap(I, ResultReg);
6140b57cec5SDimitry Andric   return true;
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric // Emit a store instruction to store SrcReg at Addr.
6180b57cec5SDimitry Andric bool PPCFastISel::PPCEmitStore(MVT VT, unsigned SrcReg, Address &Addr) {
6190b57cec5SDimitry Andric   assert(SrcReg && "Nothing to store!");
6200b57cec5SDimitry Andric   unsigned Opc;
6210b57cec5SDimitry Andric   bool UseOffset = true;
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric   const TargetRegisterClass *RC = MRI.getRegClass(SrcReg);
6240b57cec5SDimitry Andric   bool Is32BitInt = RC->hasSuperClassEq(&PPC::GPRCRegClass);
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric   switch (VT.SimpleTy) {
6270b57cec5SDimitry Andric     default: // e.g., vector types not handled
6280b57cec5SDimitry Andric       return false;
6290b57cec5SDimitry Andric     case MVT::i8:
6300b57cec5SDimitry Andric       Opc = Is32BitInt ? PPC::STB : PPC::STB8;
6310b57cec5SDimitry Andric       break;
6320b57cec5SDimitry Andric     case MVT::i16:
6330b57cec5SDimitry Andric       Opc = Is32BitInt ? PPC::STH : PPC::STH8;
6340b57cec5SDimitry Andric       break;
6350b57cec5SDimitry Andric     case MVT::i32:
6360b57cec5SDimitry Andric       assert(Is32BitInt && "Not GPRC for i32??");
6370b57cec5SDimitry Andric       Opc = PPC::STW;
6380b57cec5SDimitry Andric       break;
6390b57cec5SDimitry Andric     case MVT::i64:
6400b57cec5SDimitry Andric       Opc = PPC::STD;
6410b57cec5SDimitry Andric       UseOffset = ((Addr.Offset & 3) == 0);
6420b57cec5SDimitry Andric       break;
6430b57cec5SDimitry Andric     case MVT::f32:
6445ffd83dbSDimitry Andric       Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;
6450b57cec5SDimitry Andric       break;
6460b57cec5SDimitry Andric     case MVT::f64:
6475ffd83dbSDimitry Andric       Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;
6480b57cec5SDimitry Andric       break;
6490b57cec5SDimitry Andric   }
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   // If necessary, materialize the offset into a register and use
6520b57cec5SDimitry Andric   // the indexed form.  Also handle stack pointers with special needs.
6530b57cec5SDimitry Andric   unsigned IndexReg = 0;
6540b57cec5SDimitry Andric   PPCSimplifyAddress(Addr, UseOffset, IndexReg);
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric   // If this is a potential VSX store with an offset of 0, a VSX indexed store
6570b57cec5SDimitry Andric   // can be used.
6580b57cec5SDimitry Andric   bool IsVSSRC = isVSSRCRegClass(RC);
6590b57cec5SDimitry Andric   bool IsVSFRC = isVSFRCRegClass(RC);
6600b57cec5SDimitry Andric   bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;
6610b57cec5SDimitry Andric   bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;
6620b57cec5SDimitry Andric   if ((Is32VSXStore || Is64VSXStore) &&
6630b57cec5SDimitry Andric       (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&
6640b57cec5SDimitry Andric       (Addr.Offset == 0)) {
6650b57cec5SDimitry Andric     UseOffset = false;
6660b57cec5SDimitry Andric   }
6670b57cec5SDimitry Andric 
6680b57cec5SDimitry Andric   // Note: If we still have a frame index here, we know the offset is
6690b57cec5SDimitry Andric   // in range, as otherwise PPCSimplifyAddress would have converted it
6700b57cec5SDimitry Andric   // into a RegBase.
6710b57cec5SDimitry Andric   if (Addr.BaseType == Address::FrameIndexBase) {
6720b57cec5SDimitry Andric     // VSX only provides an indexed store.
6730b57cec5SDimitry Andric     if (Is32VSXStore || Is64VSXStore) return false;
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric     MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
6760b57cec5SDimitry Andric         MachinePointerInfo::getFixedStack(*FuncInfo.MF, Addr.Base.FI,
6770b57cec5SDimitry Andric                                           Addr.Offset),
6780b57cec5SDimitry Andric         MachineMemOperand::MOStore, MFI.getObjectSize(Addr.Base.FI),
6795ffd83dbSDimitry Andric         MFI.getObjectAlign(Addr.Base.FI));
6800b57cec5SDimitry Andric 
681bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
6820b57cec5SDimitry Andric         .addReg(SrcReg)
6830b57cec5SDimitry Andric         .addImm(Addr.Offset)
6840b57cec5SDimitry Andric         .addFrameIndex(Addr.Base.FI)
6850b57cec5SDimitry Andric         .addMemOperand(MMO);
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric   // Base reg with offset in range.
6880b57cec5SDimitry Andric   } else if (UseOffset) {
6890b57cec5SDimitry Andric     // VSX only provides an indexed store.
6900b57cec5SDimitry Andric     if (Is32VSXStore || Is64VSXStore)
6910b57cec5SDimitry Andric       return false;
6920b57cec5SDimitry Andric 
693bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
6940b57cec5SDimitry Andric       .addReg(SrcReg).addImm(Addr.Offset).addReg(Addr.Base.Reg);
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   // Indexed form.
6970b57cec5SDimitry Andric   } else {
6980b57cec5SDimitry Andric     // Get the RR opcode corresponding to the RI one.  FIXME: It would be
6990b57cec5SDimitry Andric     // preferable to use the ImmToIdxMap from PPCRegisterInfo.cpp, but it
7000b57cec5SDimitry Andric     // is hard to get at.
7010b57cec5SDimitry Andric     switch (Opc) {
7020b57cec5SDimitry Andric       default:        llvm_unreachable("Unexpected opcode!");
7030b57cec5SDimitry Andric       case PPC::STB:  Opc = PPC::STBX;  break;
7040b57cec5SDimitry Andric       case PPC::STH : Opc = PPC::STHX;  break;
7050b57cec5SDimitry Andric       case PPC::STW : Opc = PPC::STWX;  break;
7060b57cec5SDimitry Andric       case PPC::STB8: Opc = PPC::STBX8; break;
7070b57cec5SDimitry Andric       case PPC::STH8: Opc = PPC::STHX8; break;
7080b57cec5SDimitry Andric       case PPC::STW8: Opc = PPC::STWX8; break;
7090b57cec5SDimitry Andric       case PPC::STD:  Opc = PPC::STDX;  break;
7100b57cec5SDimitry Andric       case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX; break;
7110b57cec5SDimitry Andric       case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;
7120b57cec5SDimitry Andric       case PPC::EVSTDD: Opc = PPC::EVSTDDX; break;
7130b57cec5SDimitry Andric       case PPC::SPESTW: Opc = PPC::SPESTWX; break;
7140b57cec5SDimitry Andric     }
7150b57cec5SDimitry Andric 
716bdd1243dSDimitry Andric     auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))
7170b57cec5SDimitry Andric         .addReg(SrcReg);
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric     // If we have an index register defined we use it in the store inst,
7200b57cec5SDimitry Andric     // otherwise we use X0 as base as it makes the vector instructions to
7210b57cec5SDimitry Andric     // use zero in the computation of the effective address regardless the
7220b57cec5SDimitry Andric     // content of the register.
7230b57cec5SDimitry Andric     if (IndexReg)
7240b57cec5SDimitry Andric       MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
7250b57cec5SDimitry Andric     else
7260b57cec5SDimitry Andric       MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric   return true;
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric // Attempt to fast-select a store instruction.
7330b57cec5SDimitry Andric bool PPCFastISel::SelectStore(const Instruction *I) {
7340b57cec5SDimitry Andric   Value *Op0 = I->getOperand(0);
7350b57cec5SDimitry Andric   unsigned SrcReg = 0;
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   // FIXME: No atomics loads are supported.
7380b57cec5SDimitry Andric   if (cast<StoreInst>(I)->isAtomic())
7390b57cec5SDimitry Andric     return false;
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric   // Verify we have a legal type before going any further.
7420b57cec5SDimitry Andric   MVT VT;
7430b57cec5SDimitry Andric   if (!isLoadTypeLegal(Op0->getType(), VT))
7440b57cec5SDimitry Andric     return false;
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric   // Get the value to be stored into a register.
7470b57cec5SDimitry Andric   SrcReg = getRegForValue(Op0);
7480b57cec5SDimitry Andric   if (SrcReg == 0)
7490b57cec5SDimitry Andric     return false;
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric   // See if we can handle this address.
7520b57cec5SDimitry Andric   Address Addr;
7530b57cec5SDimitry Andric   if (!PPCComputeAddress(I->getOperand(1), Addr))
7540b57cec5SDimitry Andric     return false;
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   if (!PPCEmitStore(VT, SrcReg, Addr))
7570b57cec5SDimitry Andric     return false;
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   return true;
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric // Attempt to fast-select a branch instruction.
7630b57cec5SDimitry Andric bool PPCFastISel::SelectBranch(const Instruction *I) {
7640b57cec5SDimitry Andric   const BranchInst *BI = cast<BranchInst>(I);
7650b57cec5SDimitry Andric   MachineBasicBlock *BrBB = FuncInfo.MBB;
7660b57cec5SDimitry Andric   MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)];
7670b57cec5SDimitry Andric   MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)];
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric   // For now, just try the simplest case where it's fed by a compare.
7700b57cec5SDimitry Andric   if (const CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition())) {
7710b57cec5SDimitry Andric     if (isValueAvailable(CI)) {
772bdd1243dSDimitry Andric       std::optional<PPC::Predicate> OptPPCPred =
773bdd1243dSDimitry Andric           getComparePred(CI->getPredicate());
7740b57cec5SDimitry Andric       if (!OptPPCPred)
7750b57cec5SDimitry Andric         return false;
7760b57cec5SDimitry Andric 
77781ad6265SDimitry Andric       PPC::Predicate PPCPred = *OptPPCPred;
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric       // Take advantage of fall-through opportunities.
7800b57cec5SDimitry Andric       if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {
7810b57cec5SDimitry Andric         std::swap(TBB, FBB);
7820b57cec5SDimitry Andric         PPCPred = PPC::InvertPredicate(PPCPred);
7830b57cec5SDimitry Andric       }
7840b57cec5SDimitry Andric 
78504eeddc0SDimitry Andric       Register CondReg = createResultReg(&PPC::CRRCRegClass);
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric       if (!PPCEmitCmp(CI->getOperand(0), CI->getOperand(1), CI->isUnsigned(),
7880b57cec5SDimitry Andric                       CondReg, PPCPred))
7890b57cec5SDimitry Andric         return false;
7900b57cec5SDimitry Andric 
791bdd1243dSDimitry Andric       BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCC))
7925ffd83dbSDimitry Andric           .addImm(Subtarget->hasSPE() ? PPC::PRED_SPE : PPCPred)
7935ffd83dbSDimitry Andric           .addReg(CondReg)
7945ffd83dbSDimitry Andric           .addMBB(TBB);
7950b57cec5SDimitry Andric       finishCondBranch(BI->getParent(), TBB, FBB);
7960b57cec5SDimitry Andric       return true;
7970b57cec5SDimitry Andric     }
7980b57cec5SDimitry Andric   } else if (const ConstantInt *CI =
7990b57cec5SDimitry Andric              dyn_cast<ConstantInt>(BI->getCondition())) {
8000b57cec5SDimitry Andric     uint64_t Imm = CI->getZExtValue();
8010b57cec5SDimitry Andric     MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;
802bdd1243dSDimitry Andric     fastEmitBranch(Target, MIMD.getDL());
8030b57cec5SDimitry Andric     return true;
8040b57cec5SDimitry Andric   }
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric   // FIXME: ARM looks for a case where the block containing the compare
8070b57cec5SDimitry Andric   // has been split from the block containing the branch.  If this happens,
8080b57cec5SDimitry Andric   // there is a vreg available containing the result of the compare.  I'm
8090b57cec5SDimitry Andric   // not sure we can do much, as we've lost the predicate information with
8100b57cec5SDimitry Andric   // the compare instruction -- we have a 4-bit CR but don't know which bit
8110b57cec5SDimitry Andric   // to test here.
8120b57cec5SDimitry Andric   return false;
8130b57cec5SDimitry Andric }
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric // Attempt to emit a compare of the two source values.  Signed and unsigned
8160b57cec5SDimitry Andric // comparisons are supported.  Return false if we can't handle it.
8170b57cec5SDimitry Andric bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,
8180b57cec5SDimitry Andric                              bool IsZExt, unsigned DestReg,
8190b57cec5SDimitry Andric                              const PPC::Predicate Pred) {
8200b57cec5SDimitry Andric   Type *Ty = SrcValue1->getType();
8210b57cec5SDimitry Andric   EVT SrcEVT = TLI.getValueType(DL, Ty, true);
8220b57cec5SDimitry Andric   if (!SrcEVT.isSimple())
8230b57cec5SDimitry Andric     return false;
8240b57cec5SDimitry Andric   MVT SrcVT = SrcEVT.getSimpleVT();
8250b57cec5SDimitry Andric 
8265ffd83dbSDimitry Andric   if (SrcVT == MVT::i1 && Subtarget->useCRBits())
8270b57cec5SDimitry Andric     return false;
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   // See if operand 2 is an immediate encodeable in the compare.
8300b57cec5SDimitry Andric   // FIXME: Operands are not in canonical order at -O0, so an immediate
8310b57cec5SDimitry Andric   // operand in position 1 is a lost opportunity for now.  We are
8320b57cec5SDimitry Andric   // similar to ARM in this regard.
83361cfbce3SDimitry Andric   int64_t Imm = 0;
8340b57cec5SDimitry Andric   bool UseImm = false;
8355ffd83dbSDimitry Andric   const bool HasSPE = Subtarget->hasSPE();
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric   // Only 16-bit integer constants can be represented in compares for
8380b57cec5SDimitry Andric   // PowerPC.  Others will be materialized into a register.
8390b57cec5SDimitry Andric   if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(SrcValue2)) {
8400b57cec5SDimitry Andric     if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||
8410b57cec5SDimitry Andric         SrcVT == MVT::i8 || SrcVT == MVT::i1) {
8420b57cec5SDimitry Andric       const APInt &CIVal = ConstInt->getValue();
84361cfbce3SDimitry Andric       Imm = (IsZExt) ? (int64_t)CIVal.getZExtValue() :
84461cfbce3SDimitry Andric                        (int64_t)CIVal.getSExtValue();
8450b57cec5SDimitry Andric       if ((IsZExt && isUInt<16>(Imm)) || (!IsZExt && isInt<16>(Imm)))
8460b57cec5SDimitry Andric         UseImm = true;
8470b57cec5SDimitry Andric     }
8480b57cec5SDimitry Andric   }
8490b57cec5SDimitry Andric 
85004eeddc0SDimitry Andric   Register SrcReg1 = getRegForValue(SrcValue1);
8510b57cec5SDimitry Andric   if (SrcReg1 == 0)
8520b57cec5SDimitry Andric     return false;
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric   unsigned SrcReg2 = 0;
8550b57cec5SDimitry Andric   if (!UseImm) {
8560b57cec5SDimitry Andric     SrcReg2 = getRegForValue(SrcValue2);
8570b57cec5SDimitry Andric     if (SrcReg2 == 0)
8580b57cec5SDimitry Andric       return false;
8590b57cec5SDimitry Andric   }
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric   unsigned CmpOpc;
8620b57cec5SDimitry Andric   bool NeedsExt = false;
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   auto RC1 = MRI.getRegClass(SrcReg1);
8650b57cec5SDimitry Andric   auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) : nullptr;
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   switch (SrcVT.SimpleTy) {
8680b57cec5SDimitry Andric     default: return false;
8690b57cec5SDimitry Andric     case MVT::f32:
8700b57cec5SDimitry Andric       if (HasSPE) {
8710b57cec5SDimitry Andric         switch (Pred) {
8720b57cec5SDimitry Andric           default: return false;
8730b57cec5SDimitry Andric           case PPC::PRED_EQ:
8740b57cec5SDimitry Andric             CmpOpc = PPC::EFSCMPEQ;
8750b57cec5SDimitry Andric             break;
8760b57cec5SDimitry Andric           case PPC::PRED_LT:
8770b57cec5SDimitry Andric             CmpOpc = PPC::EFSCMPLT;
8780b57cec5SDimitry Andric             break;
8790b57cec5SDimitry Andric           case PPC::PRED_GT:
8800b57cec5SDimitry Andric             CmpOpc = PPC::EFSCMPGT;
8810b57cec5SDimitry Andric             break;
8820b57cec5SDimitry Andric         }
8830b57cec5SDimitry Andric       } else {
8840b57cec5SDimitry Andric         CmpOpc = PPC::FCMPUS;
8850b57cec5SDimitry Andric         if (isVSSRCRegClass(RC1))
8860b57cec5SDimitry Andric           SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);
8870b57cec5SDimitry Andric         if (RC2 && isVSSRCRegClass(RC2))
8880b57cec5SDimitry Andric           SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);
8890b57cec5SDimitry Andric       }
8900b57cec5SDimitry Andric       break;
8910b57cec5SDimitry Andric     case MVT::f64:
8920b57cec5SDimitry Andric       if (HasSPE) {
8930b57cec5SDimitry Andric         switch (Pred) {
8940b57cec5SDimitry Andric           default: return false;
8950b57cec5SDimitry Andric           case PPC::PRED_EQ:
8960b57cec5SDimitry Andric             CmpOpc = PPC::EFDCMPEQ;
8970b57cec5SDimitry Andric             break;
8980b57cec5SDimitry Andric           case PPC::PRED_LT:
8990b57cec5SDimitry Andric             CmpOpc = PPC::EFDCMPLT;
9000b57cec5SDimitry Andric             break;
9010b57cec5SDimitry Andric           case PPC::PRED_GT:
9020b57cec5SDimitry Andric             CmpOpc = PPC::EFDCMPGT;
9030b57cec5SDimitry Andric             break;
9040b57cec5SDimitry Andric         }
9050b57cec5SDimitry Andric       } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {
9060b57cec5SDimitry Andric         CmpOpc = PPC::XSCMPUDP;
9070b57cec5SDimitry Andric       } else {
9080b57cec5SDimitry Andric         CmpOpc = PPC::FCMPUD;
9090b57cec5SDimitry Andric       }
9100b57cec5SDimitry Andric       break;
9110b57cec5SDimitry Andric     case MVT::i1:
9120b57cec5SDimitry Andric     case MVT::i8:
9130b57cec5SDimitry Andric     case MVT::i16:
9140b57cec5SDimitry Andric       NeedsExt = true;
915bdd1243dSDimitry Andric       [[fallthrough]];
9160b57cec5SDimitry Andric     case MVT::i32:
9170b57cec5SDimitry Andric       if (!UseImm)
9180b57cec5SDimitry Andric         CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;
9190b57cec5SDimitry Andric       else
9200b57cec5SDimitry Andric         CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;
9210b57cec5SDimitry Andric       break;
9220b57cec5SDimitry Andric     case MVT::i64:
9230b57cec5SDimitry Andric       if (!UseImm)
9240b57cec5SDimitry Andric         CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;
9250b57cec5SDimitry Andric       else
9260b57cec5SDimitry Andric         CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;
9270b57cec5SDimitry Andric       break;
9280b57cec5SDimitry Andric   }
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric   if (NeedsExt) {
93104eeddc0SDimitry Andric     Register ExtReg = createResultReg(&PPC::GPRCRegClass);
9320b57cec5SDimitry Andric     if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))
9330b57cec5SDimitry Andric       return false;
9340b57cec5SDimitry Andric     SrcReg1 = ExtReg;
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric     if (!UseImm) {
93704eeddc0SDimitry Andric       Register ExtReg = createResultReg(&PPC::GPRCRegClass);
9380b57cec5SDimitry Andric       if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))
9390b57cec5SDimitry Andric         return false;
9400b57cec5SDimitry Andric       SrcReg2 = ExtReg;
9410b57cec5SDimitry Andric     }
9420b57cec5SDimitry Andric   }
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric   if (!UseImm)
945bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
9460b57cec5SDimitry Andric       .addReg(SrcReg1).addReg(SrcReg2);
9470b57cec5SDimitry Andric   else
948bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)
9490b57cec5SDimitry Andric       .addReg(SrcReg1).addImm(Imm);
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric   return true;
9520b57cec5SDimitry Andric }
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric // Attempt to fast-select a floating-point extend instruction.
9550b57cec5SDimitry Andric bool PPCFastISel::SelectFPExt(const Instruction *I) {
9560b57cec5SDimitry Andric   Value *Src  = I->getOperand(0);
9570b57cec5SDimitry Andric   EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
9580b57cec5SDimitry Andric   EVT DestVT = TLI.getValueType(DL, I->getType(), true);
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   if (SrcVT != MVT::f32 || DestVT != MVT::f64)
9610b57cec5SDimitry Andric     return false;
9620b57cec5SDimitry Andric 
96304eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
9640b57cec5SDimitry Andric   if (!SrcReg)
9650b57cec5SDimitry Andric     return false;
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   // No code is generated for a FP extend.
9680b57cec5SDimitry Andric   updateValueMap(I, SrcReg);
9690b57cec5SDimitry Andric   return true;
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric // Attempt to fast-select a floating-point truncate instruction.
9730b57cec5SDimitry Andric bool PPCFastISel::SelectFPTrunc(const Instruction *I) {
9740b57cec5SDimitry Andric   Value *Src  = I->getOperand(0);
9750b57cec5SDimitry Andric   EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
9760b57cec5SDimitry Andric   EVT DestVT = TLI.getValueType(DL, I->getType(), true);
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   if (SrcVT != MVT::f64 || DestVT != MVT::f32)
9790b57cec5SDimitry Andric     return false;
9800b57cec5SDimitry Andric 
98104eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
9820b57cec5SDimitry Andric   if (!SrcReg)
9830b57cec5SDimitry Andric     return false;
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric   // Round the result to single precision.
9860b57cec5SDimitry Andric   unsigned DestReg;
9870b57cec5SDimitry Andric   auto RC = MRI.getRegClass(SrcReg);
9885ffd83dbSDimitry Andric   if (Subtarget->hasSPE()) {
9898bcb0991SDimitry Andric     DestReg = createResultReg(&PPC::GPRCRegClass);
990bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::EFSCFD),
991349cc55cSDimitry Andric             DestReg)
9920b57cec5SDimitry Andric         .addReg(SrcReg);
993349cc55cSDimitry Andric   } else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {
9940b57cec5SDimitry Andric     DestReg = createResultReg(&PPC::VSSRCRegClass);
995bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::XSRSP),
996349cc55cSDimitry Andric             DestReg)
9970b57cec5SDimitry Andric         .addReg(SrcReg);
9980b57cec5SDimitry Andric   } else {
999349cc55cSDimitry Andric     SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
10000b57cec5SDimitry Andric     DestReg = createResultReg(&PPC::F4RCRegClass);
1001bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
10020b57cec5SDimitry Andric       TII.get(PPC::FRSP), DestReg)
10030b57cec5SDimitry Andric       .addReg(SrcReg);
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric   updateValueMap(I, DestReg);
10070b57cec5SDimitry Andric   return true;
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric // Move an i32 or i64 value in a GPR to an f64 value in an FPR.
10110b57cec5SDimitry Andric // FIXME: When direct register moves are implemented (see PowerISA 2.07),
10120b57cec5SDimitry Andric // those should be used instead of moving via a stack slot when the
10130b57cec5SDimitry Andric // subtarget permits.
10140b57cec5SDimitry Andric // FIXME: The code here is sloppy for the 4-byte case.  Can use a 4-byte
10150b57cec5SDimitry Andric // stack slot and 4-byte store/load sequence.  Or just sext the 4-byte
10160b57cec5SDimitry Andric // case to 8 bytes which produces tighter code but wastes stack space.
10170b57cec5SDimitry Andric unsigned PPCFastISel::PPCMoveToFPReg(MVT SrcVT, unsigned SrcReg,
10180b57cec5SDimitry Andric                                      bool IsSigned) {
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric   // If necessary, extend 32-bit int to 64-bit.
10210b57cec5SDimitry Andric   if (SrcVT == MVT::i32) {
102204eeddc0SDimitry Andric     Register TmpReg = createResultReg(&PPC::G8RCRegClass);
10230b57cec5SDimitry Andric     if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))
10240b57cec5SDimitry Andric       return 0;
10250b57cec5SDimitry Andric     SrcReg = TmpReg;
10260b57cec5SDimitry Andric   }
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   // Get a stack slot 8 bytes wide, aligned on an 8-byte boundary.
10290b57cec5SDimitry Andric   Address Addr;
10300b57cec5SDimitry Andric   Addr.BaseType = Address::FrameIndexBase;
10315ffd83dbSDimitry Andric   Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric   // Store the value from the GPR.
10340b57cec5SDimitry Andric   if (!PPCEmitStore(MVT::i64, SrcReg, Addr))
10350b57cec5SDimitry Andric     return 0;
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric   // Load the integer value into an FPR.  The kind of load used depends
10380b57cec5SDimitry Andric   // on a number of conditions.
10390b57cec5SDimitry Andric   unsigned LoadOpc = PPC::LFD;
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   if (SrcVT == MVT::i32) {
10420b57cec5SDimitry Andric     if (!IsSigned) {
10430b57cec5SDimitry Andric       LoadOpc = PPC::LFIWZX;
10445ffd83dbSDimitry Andric       Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
10455ffd83dbSDimitry Andric     } else if (Subtarget->hasLFIWAX()) {
10460b57cec5SDimitry Andric       LoadOpc = PPC::LFIWAX;
10475ffd83dbSDimitry Andric       Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
10480b57cec5SDimitry Andric     }
10490b57cec5SDimitry Andric   }
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric   const TargetRegisterClass *RC = &PPC::F8RCRegClass;
10528bcb0991SDimitry Andric   Register ResultReg = 0;
10530b57cec5SDimitry Andric   if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))
10540b57cec5SDimitry Andric     return 0;
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric   return ResultReg;
10570b57cec5SDimitry Andric }
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric // Attempt to fast-select an integer-to-floating-point conversion.
10600b57cec5SDimitry Andric // FIXME: Once fast-isel has better support for VSX, conversions using
10610b57cec5SDimitry Andric //        direct moves should be implemented.
10620b57cec5SDimitry Andric bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned) {
10630b57cec5SDimitry Andric   MVT DstVT;
10640b57cec5SDimitry Andric   Type *DstTy = I->getType();
10650b57cec5SDimitry Andric   if (!isTypeLegal(DstTy, DstVT))
10660b57cec5SDimitry Andric     return false;
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   if (DstVT != MVT::f32 && DstVT != MVT::f64)
10690b57cec5SDimitry Andric     return false;
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric   Value *Src = I->getOperand(0);
10720b57cec5SDimitry Andric   EVT SrcEVT = TLI.getValueType(DL, Src->getType(), true);
10730b57cec5SDimitry Andric   if (!SrcEVT.isSimple())
10740b57cec5SDimitry Andric     return false;
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   MVT SrcVT = SrcEVT.getSimpleVT();
10770b57cec5SDimitry Andric 
10780b57cec5SDimitry Andric   if (SrcVT != MVT::i8  && SrcVT != MVT::i16 &&
10790b57cec5SDimitry Andric       SrcVT != MVT::i32 && SrcVT != MVT::i64)
10800b57cec5SDimitry Andric     return false;
10810b57cec5SDimitry Andric 
108204eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
10830b57cec5SDimitry Andric   if (SrcReg == 0)
10840b57cec5SDimitry Andric     return false;
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   // Shortcut for SPE.  Doesn't need to store/load, since it's all in the GPRs
10875ffd83dbSDimitry Andric   if (Subtarget->hasSPE()) {
10880b57cec5SDimitry Andric     unsigned Opc;
10890b57cec5SDimitry Andric     if (DstVT == MVT::f32)
10900b57cec5SDimitry Andric       Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;
10910b57cec5SDimitry Andric     else
10920b57cec5SDimitry Andric       Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;
10930b57cec5SDimitry Andric 
109404eeddc0SDimitry Andric     Register DestReg = createResultReg(&PPC::SPERCRegClass);
10950b57cec5SDimitry Andric     // Generate the convert.
1096bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
10970b57cec5SDimitry Andric       .addReg(SrcReg);
10980b57cec5SDimitry Andric     updateValueMap(I, DestReg);
10990b57cec5SDimitry Andric     return true;
11000b57cec5SDimitry Andric   }
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric   // We can only lower an unsigned convert if we have the newer
11030b57cec5SDimitry Andric   // floating-point conversion operations.
11045ffd83dbSDimitry Andric   if (!IsSigned && !Subtarget->hasFPCVT())
11050b57cec5SDimitry Andric     return false;
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   // FIXME: For now we require the newer floating-point conversion operations
11080b57cec5SDimitry Andric   // (which are present only on P7 and A2 server models) when converting
11090b57cec5SDimitry Andric   // to single-precision float.  Otherwise we have to generate a lot of
11100b57cec5SDimitry Andric   // fiddly code to avoid double rounding.  If necessary, the fiddly code
11110b57cec5SDimitry Andric   // can be found in PPCTargetLowering::LowerINT_TO_FP().
11125ffd83dbSDimitry Andric   if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())
11130b57cec5SDimitry Andric     return false;
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric   // Extend the input if necessary.
11160b57cec5SDimitry Andric   if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {
111704eeddc0SDimitry Andric     Register TmpReg = createResultReg(&PPC::G8RCRegClass);
11180b57cec5SDimitry Andric     if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))
11190b57cec5SDimitry Andric       return false;
11200b57cec5SDimitry Andric     SrcVT = MVT::i64;
11210b57cec5SDimitry Andric     SrcReg = TmpReg;
11220b57cec5SDimitry Andric   }
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric   // Move the integer value to an FPR.
11250b57cec5SDimitry Andric   unsigned FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);
11260b57cec5SDimitry Andric   if (FPReg == 0)
11270b57cec5SDimitry Andric     return false;
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric   // Determine the opcode for the conversion.
11300b57cec5SDimitry Andric   const TargetRegisterClass *RC = &PPC::F8RCRegClass;
113104eeddc0SDimitry Andric   Register DestReg = createResultReg(RC);
11320b57cec5SDimitry Andric   unsigned Opc;
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric   if (DstVT == MVT::f32)
11350b57cec5SDimitry Andric     Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;
11360b57cec5SDimitry Andric   else
11370b57cec5SDimitry Andric     Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;
11380b57cec5SDimitry Andric 
11390b57cec5SDimitry Andric   // Generate the convert.
1140bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
11410b57cec5SDimitry Andric     .addReg(FPReg);
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric   updateValueMap(I, DestReg);
11440b57cec5SDimitry Andric   return true;
11450b57cec5SDimitry Andric }
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric // Move the floating-point value in SrcReg into an integer destination
11480b57cec5SDimitry Andric // register, and return the register (or zero if we can't handle it).
11490b57cec5SDimitry Andric // FIXME: When direct register moves are implemented (see PowerISA 2.07),
11500b57cec5SDimitry Andric // those should be used instead of moving via a stack slot when the
11510b57cec5SDimitry Andric // subtarget permits.
11520b57cec5SDimitry Andric unsigned PPCFastISel::PPCMoveToIntReg(const Instruction *I, MVT VT,
11530b57cec5SDimitry Andric                                       unsigned SrcReg, bool IsSigned) {
11540b57cec5SDimitry Andric   // Get a stack slot 8 bytes wide, aligned on an 8-byte boundary.
11550b57cec5SDimitry Andric   // Note that if have STFIWX available, we could use a 4-byte stack
11560b57cec5SDimitry Andric   // slot for i32, but this being fast-isel we'll just go with the
11570b57cec5SDimitry Andric   // easiest code gen possible.
11580b57cec5SDimitry Andric   Address Addr;
11590b57cec5SDimitry Andric   Addr.BaseType = Address::FrameIndexBase;
11605ffd83dbSDimitry Andric   Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric   // Store the value from the FPR.
11630b57cec5SDimitry Andric   if (!PPCEmitStore(MVT::f64, SrcReg, Addr))
11640b57cec5SDimitry Andric     return 0;
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   // Reload it into a GPR.  If we want an i32 on big endian, modify the
11670b57cec5SDimitry Andric   // address to have a 4-byte offset so we load from the right place.
11680b57cec5SDimitry Andric   if (VT == MVT::i32)
11695ffd83dbSDimitry Andric     Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   // Look at the currently assigned register for this instruction
11720b57cec5SDimitry Andric   // to determine the required register class.
117304eeddc0SDimitry Andric   Register AssignedReg = FuncInfo.ValueMap[I];
11740b57cec5SDimitry Andric   const TargetRegisterClass *RC =
11750b57cec5SDimitry Andric     AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;
11760b57cec5SDimitry Andric 
11778bcb0991SDimitry Andric   Register ResultReg = 0;
11780b57cec5SDimitry Andric   if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))
11790b57cec5SDimitry Andric     return 0;
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   return ResultReg;
11820b57cec5SDimitry Andric }
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric // Attempt to fast-select a floating-point-to-integer conversion.
11850b57cec5SDimitry Andric // FIXME: Once fast-isel has better support for VSX, conversions using
11860b57cec5SDimitry Andric //        direct moves should be implemented.
11870b57cec5SDimitry Andric bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {
11880b57cec5SDimitry Andric   MVT DstVT, SrcVT;
11890b57cec5SDimitry Andric   Type *DstTy = I->getType();
11900b57cec5SDimitry Andric   if (!isTypeLegal(DstTy, DstVT))
11910b57cec5SDimitry Andric     return false;
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   if (DstVT != MVT::i32 && DstVT != MVT::i64)
11940b57cec5SDimitry Andric     return false;
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric   // If we don't have FCTIDUZ, or SPE, and we need it, punt to SelectionDAG.
11975ffd83dbSDimitry Andric   if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&
11985ffd83dbSDimitry Andric       !Subtarget->hasSPE())
11990b57cec5SDimitry Andric     return false;
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric   Value *Src = I->getOperand(0);
12020b57cec5SDimitry Andric   Type *SrcTy = Src->getType();
12030b57cec5SDimitry Andric   if (!isTypeLegal(SrcTy, SrcVT))
12040b57cec5SDimitry Andric     return false;
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   if (SrcVT != MVT::f32 && SrcVT != MVT::f64)
12070b57cec5SDimitry Andric     return false;
12080b57cec5SDimitry Andric 
120904eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
12100b57cec5SDimitry Andric   if (SrcReg == 0)
12110b57cec5SDimitry Andric     return false;
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric   // Convert f32 to f64 or convert VSSRC to VSFRC if necessary. This is just a
12140b57cec5SDimitry Andric   // meaningless copy to get the register class right.
12150b57cec5SDimitry Andric   const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);
12160b57cec5SDimitry Andric   if (InRC == &PPC::F4RCRegClass)
12170b57cec5SDimitry Andric     SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);
12180b57cec5SDimitry Andric   else if (InRC == &PPC::VSSRCRegClass)
12190b57cec5SDimitry Andric     SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric   // Determine the opcode for the conversion, which takes place
12220b57cec5SDimitry Andric   // entirely within FPRs or VSRs.
12230b57cec5SDimitry Andric   unsigned DestReg;
12240b57cec5SDimitry Andric   unsigned Opc;
12250b57cec5SDimitry Andric   auto RC = MRI.getRegClass(SrcReg);
12260b57cec5SDimitry Andric 
12275ffd83dbSDimitry Andric   if (Subtarget->hasSPE()) {
12280b57cec5SDimitry Andric     DestReg = createResultReg(&PPC::GPRCRegClass);
12290b57cec5SDimitry Andric     if (IsSigned)
12308bcb0991SDimitry Andric       Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;
12310b57cec5SDimitry Andric     else
12328bcb0991SDimitry Andric       Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;
12330b57cec5SDimitry Andric   } else if (isVSFRCRegClass(RC)) {
12340b57cec5SDimitry Andric     DestReg = createResultReg(&PPC::VSFRCRegClass);
12350b57cec5SDimitry Andric     if (DstVT == MVT::i32)
12360b57cec5SDimitry Andric       Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;
12370b57cec5SDimitry Andric     else
12380b57cec5SDimitry Andric       Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
12390b57cec5SDimitry Andric   } else {
12400b57cec5SDimitry Andric     DestReg = createResultReg(&PPC::F8RCRegClass);
12410b57cec5SDimitry Andric     if (DstVT == MVT::i32)
12420b57cec5SDimitry Andric       if (IsSigned)
12430b57cec5SDimitry Andric         Opc = PPC::FCTIWZ;
12440b57cec5SDimitry Andric       else
12455ffd83dbSDimitry Andric         Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;
12460b57cec5SDimitry Andric     else
12470b57cec5SDimitry Andric       Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;
12480b57cec5SDimitry Andric   }
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   // Generate the convert.
1251bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
12520b57cec5SDimitry Andric     .addReg(SrcReg);
12530b57cec5SDimitry Andric 
12540b57cec5SDimitry Andric   // Now move the integer value from a float register to an integer register.
12555ffd83dbSDimitry Andric   unsigned IntReg = Subtarget->hasSPE()
12565ffd83dbSDimitry Andric                         ? DestReg
12575ffd83dbSDimitry Andric                         : PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);
12580b57cec5SDimitry Andric 
12590b57cec5SDimitry Andric   if (IntReg == 0)
12600b57cec5SDimitry Andric     return false;
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   updateValueMap(I, IntReg);
12630b57cec5SDimitry Andric   return true;
12640b57cec5SDimitry Andric }
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric // Attempt to fast-select a binary integer operation that isn't already
12670b57cec5SDimitry Andric // handled automatically.
12680b57cec5SDimitry Andric bool PPCFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {
12690b57cec5SDimitry Andric   EVT DestVT = TLI.getValueType(DL, I->getType(), true);
12700b57cec5SDimitry Andric 
12710b57cec5SDimitry Andric   // We can get here in the case when we have a binary operation on a non-legal
12720b57cec5SDimitry Andric   // type and the target independent selector doesn't know how to handle it.
12730b57cec5SDimitry Andric   if (DestVT != MVT::i16 && DestVT != MVT::i8)
12740b57cec5SDimitry Andric     return false;
12750b57cec5SDimitry Andric 
12760b57cec5SDimitry Andric   // Look at the currently assigned register for this instruction
12770b57cec5SDimitry Andric   // to determine the required register class.  If there is no register,
12780b57cec5SDimitry Andric   // make a conservative choice (don't assign R0).
127904eeddc0SDimitry Andric   Register AssignedReg = FuncInfo.ValueMap[I];
12800b57cec5SDimitry Andric   const TargetRegisterClass *RC =
12810b57cec5SDimitry Andric     (AssignedReg ? MRI.getRegClass(AssignedReg) :
12820b57cec5SDimitry Andric      &PPC::GPRC_and_GPRC_NOR0RegClass);
12830b57cec5SDimitry Andric   bool IsGPRC = RC->hasSuperClassEq(&PPC::GPRCRegClass);
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric   unsigned Opc;
12860b57cec5SDimitry Andric   switch (ISDOpcode) {
12870b57cec5SDimitry Andric     default: return false;
12880b57cec5SDimitry Andric     case ISD::ADD:
12890b57cec5SDimitry Andric       Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;
12900b57cec5SDimitry Andric       break;
12910b57cec5SDimitry Andric     case ISD::OR:
12920b57cec5SDimitry Andric       Opc = IsGPRC ? PPC::OR : PPC::OR8;
12930b57cec5SDimitry Andric       break;
12940b57cec5SDimitry Andric     case ISD::SUB:
12950b57cec5SDimitry Andric       Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;
12960b57cec5SDimitry Andric       break;
12970b57cec5SDimitry Andric   }
12980b57cec5SDimitry Andric 
129904eeddc0SDimitry Andric   Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);
130004eeddc0SDimitry Andric   Register SrcReg1 = getRegForValue(I->getOperand(0));
13010b57cec5SDimitry Andric   if (SrcReg1 == 0) return false;
13020b57cec5SDimitry Andric 
13030b57cec5SDimitry Andric   // Handle case of small immediate operand.
13040b57cec5SDimitry Andric   if (const ConstantInt *ConstInt = dyn_cast<ConstantInt>(I->getOperand(1))) {
13050b57cec5SDimitry Andric     const APInt &CIVal = ConstInt->getValue();
13060b57cec5SDimitry Andric     int Imm = (int)CIVal.getSExtValue();
13070b57cec5SDimitry Andric     bool UseImm = true;
13080b57cec5SDimitry Andric     if (isInt<16>(Imm)) {
13090b57cec5SDimitry Andric       switch (Opc) {
13100b57cec5SDimitry Andric         default:
13110b57cec5SDimitry Andric           llvm_unreachable("Missing case!");
13120b57cec5SDimitry Andric         case PPC::ADD4:
13130b57cec5SDimitry Andric           Opc = PPC::ADDI;
13140b57cec5SDimitry Andric           MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
13150b57cec5SDimitry Andric           break;
13160b57cec5SDimitry Andric         case PPC::ADD8:
13170b57cec5SDimitry Andric           Opc = PPC::ADDI8;
13180b57cec5SDimitry Andric           MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
13190b57cec5SDimitry Andric           break;
13200b57cec5SDimitry Andric         case PPC::OR:
13210b57cec5SDimitry Andric           Opc = PPC::ORI;
13220b57cec5SDimitry Andric           break;
13230b57cec5SDimitry Andric         case PPC::OR8:
13240b57cec5SDimitry Andric           Opc = PPC::ORI8;
13250b57cec5SDimitry Andric           break;
13260b57cec5SDimitry Andric         case PPC::SUBF:
13270b57cec5SDimitry Andric           if (Imm == -32768)
13280b57cec5SDimitry Andric             UseImm = false;
13290b57cec5SDimitry Andric           else {
13300b57cec5SDimitry Andric             Opc = PPC::ADDI;
13310b57cec5SDimitry Andric             MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);
13320b57cec5SDimitry Andric             Imm = -Imm;
13330b57cec5SDimitry Andric           }
13340b57cec5SDimitry Andric           break;
13350b57cec5SDimitry Andric         case PPC::SUBF8:
13360b57cec5SDimitry Andric           if (Imm == -32768)
13370b57cec5SDimitry Andric             UseImm = false;
13380b57cec5SDimitry Andric           else {
13390b57cec5SDimitry Andric             Opc = PPC::ADDI8;
13400b57cec5SDimitry Andric             MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);
13410b57cec5SDimitry Andric             Imm = -Imm;
13420b57cec5SDimitry Andric           }
13430b57cec5SDimitry Andric           break;
13440b57cec5SDimitry Andric       }
13450b57cec5SDimitry Andric 
13460b57cec5SDimitry Andric       if (UseImm) {
1347bdd1243dSDimitry Andric         BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),
13480b57cec5SDimitry Andric                 ResultReg)
13490b57cec5SDimitry Andric             .addReg(SrcReg1)
13500b57cec5SDimitry Andric             .addImm(Imm);
13510b57cec5SDimitry Andric         updateValueMap(I, ResultReg);
13520b57cec5SDimitry Andric         return true;
13530b57cec5SDimitry Andric       }
13540b57cec5SDimitry Andric     }
13550b57cec5SDimitry Andric   }
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   // Reg-reg case.
135804eeddc0SDimitry Andric   Register SrcReg2 = getRegForValue(I->getOperand(1));
13590b57cec5SDimitry Andric   if (SrcReg2 == 0) return false;
13600b57cec5SDimitry Andric 
13610b57cec5SDimitry Andric   // Reverse operands for subtract-from.
13620b57cec5SDimitry Andric   if (ISDOpcode == ISD::SUB)
13630b57cec5SDimitry Andric     std::swap(SrcReg1, SrcReg2);
13640b57cec5SDimitry Andric 
1365bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)
13660b57cec5SDimitry Andric     .addReg(SrcReg1).addReg(SrcReg2);
13670b57cec5SDimitry Andric   updateValueMap(I, ResultReg);
13680b57cec5SDimitry Andric   return true;
13690b57cec5SDimitry Andric }
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric // Handle arguments to a call that we're attempting to fast-select.
13720b57cec5SDimitry Andric // Return false if the arguments are too complex for us at the moment.
13730b57cec5SDimitry Andric bool PPCFastISel::processCallArgs(SmallVectorImpl<Value*> &Args,
13740b57cec5SDimitry Andric                                   SmallVectorImpl<unsigned> &ArgRegs,
13750b57cec5SDimitry Andric                                   SmallVectorImpl<MVT> &ArgVTs,
13760b57cec5SDimitry Andric                                   SmallVectorImpl<ISD::ArgFlagsTy> &ArgFlags,
13770b57cec5SDimitry Andric                                   SmallVectorImpl<unsigned> &RegArgs,
13780b57cec5SDimitry Andric                                   CallingConv::ID CC,
13790b57cec5SDimitry Andric                                   unsigned &NumBytes,
13800b57cec5SDimitry Andric                                   bool IsVarArg) {
13810b57cec5SDimitry Andric   SmallVector<CCValAssign, 16> ArgLocs;
13820b57cec5SDimitry Andric   CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric   // Reserve space for the linkage area on the stack.
13855ffd83dbSDimitry Andric   unsigned LinkageSize = Subtarget->getFrameLowering()->getLinkageSize();
13865ffd83dbSDimitry Andric   CCInfo.AllocateStack(LinkageSize, Align(8));
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric   CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CC_PPC64_ELF_FIS);
13890b57cec5SDimitry Andric 
13900b57cec5SDimitry Andric   // Bail out if we can't handle any of the arguments.
1391*0fca6ea1SDimitry Andric   for (const CCValAssign &VA : ArgLocs) {
13920b57cec5SDimitry Andric     MVT ArgVT = ArgVTs[VA.getValNo()];
13930b57cec5SDimitry Andric 
13940b57cec5SDimitry Andric     // Skip vector arguments for now, as well as long double and
13950b57cec5SDimitry Andric     // uint128_t, and anything that isn't passed in a register.
13960b57cec5SDimitry Andric     if (ArgVT.isVector() || ArgVT.getSizeInBits() > 64 || ArgVT == MVT::i1 ||
13970b57cec5SDimitry Andric         !VA.isRegLoc() || VA.needsCustom())
13980b57cec5SDimitry Andric       return false;
13990b57cec5SDimitry Andric 
14000b57cec5SDimitry Andric     // Skip bit-converted arguments for now.
14010b57cec5SDimitry Andric     if (VA.getLocInfo() == CCValAssign::BCvt)
14020b57cec5SDimitry Andric       return false;
14030b57cec5SDimitry Andric   }
14040b57cec5SDimitry Andric 
14050b57cec5SDimitry Andric   // Get a count of how many bytes are to be pushed onto the stack.
140606c3fb27SDimitry Andric   NumBytes = CCInfo.getStackSize();
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric   // The prolog code of the callee may store up to 8 GPR argument registers to
14090b57cec5SDimitry Andric   // the stack, allowing va_start to index over them in memory if its varargs.
14100b57cec5SDimitry Andric   // Because we cannot tell if this is needed on the caller side, we have to
14110b57cec5SDimitry Andric   // conservatively assume that it is needed.  As such, make sure we have at
14120b57cec5SDimitry Andric   // least enough stack space for the caller to store the 8 GPRs.
14130b57cec5SDimitry Andric   // FIXME: On ELFv2, it may be unnecessary to allocate the parameter area.
14140b57cec5SDimitry Andric   NumBytes = std::max(NumBytes, LinkageSize + 64);
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric   // Issue CALLSEQ_START.
1417bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
14180b57cec5SDimitry Andric           TII.get(TII.getCallFrameSetupOpcode()))
14190b57cec5SDimitry Andric     .addImm(NumBytes).addImm(0);
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric   // Prepare to assign register arguments.  Every argument uses up a
14220b57cec5SDimitry Andric   // GPR protocol register even if it's passed in a floating-point
14230b57cec5SDimitry Andric   // register (unless we're using the fast calling convention).
14240b57cec5SDimitry Andric   unsigned NextGPR = PPC::X3;
14250b57cec5SDimitry Andric   unsigned NextFPR = PPC::F1;
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric   // Process arguments.
1428*0fca6ea1SDimitry Andric   for (const CCValAssign &VA : ArgLocs) {
14290b57cec5SDimitry Andric     unsigned Arg = ArgRegs[VA.getValNo()];
14300b57cec5SDimitry Andric     MVT ArgVT = ArgVTs[VA.getValNo()];
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric     // Handle argument promotion and bitcasts.
14330b57cec5SDimitry Andric     switch (VA.getLocInfo()) {
14340b57cec5SDimitry Andric       default:
14350b57cec5SDimitry Andric         llvm_unreachable("Unknown loc info!");
14360b57cec5SDimitry Andric       case CCValAssign::Full:
14370b57cec5SDimitry Andric         break;
14380b57cec5SDimitry Andric       case CCValAssign::SExt: {
14390b57cec5SDimitry Andric         MVT DestVT = VA.getLocVT();
14400b57cec5SDimitry Andric         const TargetRegisterClass *RC =
14410b57cec5SDimitry Andric           (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
144204eeddc0SDimitry Andric         Register TmpReg = createResultReg(RC);
14430b57cec5SDimitry Andric         if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, /*IsZExt*/false))
14440b57cec5SDimitry Andric           llvm_unreachable("Failed to emit a sext!");
14450b57cec5SDimitry Andric         ArgVT = DestVT;
14460b57cec5SDimitry Andric         Arg = TmpReg;
14470b57cec5SDimitry Andric         break;
14480b57cec5SDimitry Andric       }
14490b57cec5SDimitry Andric       case CCValAssign::AExt:
14500b57cec5SDimitry Andric       case CCValAssign::ZExt: {
14510b57cec5SDimitry Andric         MVT DestVT = VA.getLocVT();
14520b57cec5SDimitry Andric         const TargetRegisterClass *RC =
14530b57cec5SDimitry Andric           (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
145404eeddc0SDimitry Andric         Register TmpReg = createResultReg(RC);
14550b57cec5SDimitry Andric         if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, /*IsZExt*/true))
14560b57cec5SDimitry Andric           llvm_unreachable("Failed to emit a zext!");
14570b57cec5SDimitry Andric         ArgVT = DestVT;
14580b57cec5SDimitry Andric         Arg = TmpReg;
14590b57cec5SDimitry Andric         break;
14600b57cec5SDimitry Andric       }
14610b57cec5SDimitry Andric       case CCValAssign::BCvt: {
14620b57cec5SDimitry Andric         // FIXME: Not yet handled.
14630b57cec5SDimitry Andric         llvm_unreachable("Should have bailed before getting here!");
14640b57cec5SDimitry Andric         break;
14650b57cec5SDimitry Andric       }
14660b57cec5SDimitry Andric     }
14670b57cec5SDimitry Andric 
14680b57cec5SDimitry Andric     // Copy this argument to the appropriate register.
14690b57cec5SDimitry Andric     unsigned ArgReg;
14700b57cec5SDimitry Andric     if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {
14710b57cec5SDimitry Andric       ArgReg = NextFPR++;
14720b57cec5SDimitry Andric       if (CC != CallingConv::Fast)
14730b57cec5SDimitry Andric         ++NextGPR;
14740b57cec5SDimitry Andric     } else
14750b57cec5SDimitry Andric       ArgReg = NextGPR++;
14760b57cec5SDimitry Andric 
1477bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
14780b57cec5SDimitry Andric             TII.get(TargetOpcode::COPY), ArgReg).addReg(Arg);
14790b57cec5SDimitry Andric     RegArgs.push_back(ArgReg);
14800b57cec5SDimitry Andric   }
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric   return true;
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric // For a call that we've determined we can fast-select, finish the
14860b57cec5SDimitry Andric // call sequence and generate a copy to obtain the return value (if any).
14870b57cec5SDimitry Andric bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {
14880b57cec5SDimitry Andric   CallingConv::ID CC = CLI.CallConv;
14890b57cec5SDimitry Andric 
14900b57cec5SDimitry Andric   // Issue CallSEQ_END.
1491bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
14920b57cec5SDimitry Andric           TII.get(TII.getCallFrameDestroyOpcode()))
14930b57cec5SDimitry Andric     .addImm(NumBytes).addImm(0);
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   // Next, generate a copy to obtain the return value.
14960b57cec5SDimitry Andric   // FIXME: No multi-register return values yet, though I don't foresee
14970b57cec5SDimitry Andric   // any real difficulties there.
14980b57cec5SDimitry Andric   if (RetVT != MVT::isVoid) {
14990b57cec5SDimitry Andric     SmallVector<CCValAssign, 16> RVLocs;
15000b57cec5SDimitry Andric     CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);
15010b57cec5SDimitry Andric     CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
15020b57cec5SDimitry Andric     CCValAssign &VA = RVLocs[0];
15030b57cec5SDimitry Andric     assert(RVLocs.size() == 1 && "No support for multi-reg return values!");
15040b57cec5SDimitry Andric     assert(VA.isRegLoc() && "Can only return in registers!");
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric     MVT DestVT = VA.getValVT();
15070b57cec5SDimitry Andric     MVT CopyVT = DestVT;
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric     // Ints smaller than a register still arrive in a full 64-bit
15100b57cec5SDimitry Andric     // register, so make sure we recognize this.
15110b57cec5SDimitry Andric     if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)
15120b57cec5SDimitry Andric       CopyVT = MVT::i64;
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric     unsigned SourcePhysReg = VA.getLocReg();
15150b57cec5SDimitry Andric     unsigned ResultReg = 0;
15160b57cec5SDimitry Andric 
15170b57cec5SDimitry Andric     if (RetVT == CopyVT) {
15180b57cec5SDimitry Andric       const TargetRegisterClass *CpyRC = TLI.getRegClassFor(CopyVT);
15190b57cec5SDimitry Andric       ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric     // If necessary, round the floating result to single precision.
15220b57cec5SDimitry Andric     } else if (CopyVT == MVT::f64) {
15230b57cec5SDimitry Andric       ResultReg = createResultReg(TLI.getRegClassFor(RetVT));
1524bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::FRSP),
15250b57cec5SDimitry Andric               ResultReg).addReg(SourcePhysReg);
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric     // If only the low half of a general register is needed, generate
15280b57cec5SDimitry Andric     // a GPRC copy instead of a G8RC copy.  (EXTRACT_SUBREG can't be
15290b57cec5SDimitry Andric     // used along the fast-isel path (not lowered), and downstream logic
15300b57cec5SDimitry Andric     // also doesn't like a direct subreg copy on a physical reg.)
15310b57cec5SDimitry Andric     } else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {
15320b57cec5SDimitry Andric       // Convert physical register from G8RC to GPRC.
15330b57cec5SDimitry Andric       SourcePhysReg -= PPC::X0 - PPC::R0;
15340b57cec5SDimitry Andric       ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);
15350b57cec5SDimitry Andric     }
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric     assert(ResultReg && "ResultReg unset!");
15380b57cec5SDimitry Andric     CLI.InRegs.push_back(SourcePhysReg);
15390b57cec5SDimitry Andric     CLI.ResultReg = ResultReg;
15400b57cec5SDimitry Andric     CLI.NumResultRegs = 1;
15410b57cec5SDimitry Andric   }
15420b57cec5SDimitry Andric 
15430b57cec5SDimitry Andric   return true;
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {
15470b57cec5SDimitry Andric   CallingConv::ID CC  = CLI.CallConv;
15480b57cec5SDimitry Andric   bool IsTailCall     = CLI.IsTailCall;
15490b57cec5SDimitry Andric   bool IsVarArg       = CLI.IsVarArg;
15500b57cec5SDimitry Andric   const Value *Callee = CLI.Callee;
15510b57cec5SDimitry Andric   const MCSymbol *Symbol = CLI.Symbol;
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   if (!Callee && !Symbol)
15540b57cec5SDimitry Andric     return false;
15550b57cec5SDimitry Andric 
155606c3fb27SDimitry Andric   // Allow SelectionDAG isel to handle tail calls and long calls.
155706c3fb27SDimitry Andric   if (IsTailCall || Subtarget->useLongCalls())
15580b57cec5SDimitry Andric     return false;
15590b57cec5SDimitry Andric 
15600b57cec5SDimitry Andric   // Let SDISel handle vararg functions.
15610b57cec5SDimitry Andric   if (IsVarArg)
15620b57cec5SDimitry Andric     return false;
15630b57cec5SDimitry Andric 
1564e8d8bef9SDimitry Andric   // If this is a PC-Rel function, let SDISel handle the call.
1565e8d8bef9SDimitry Andric   if (Subtarget->isUsingPCRelativeCalls())
1566e8d8bef9SDimitry Andric     return false;
1567e8d8bef9SDimitry Andric 
15680b57cec5SDimitry Andric   // Handle simple calls for now, with legal return types and
15690b57cec5SDimitry Andric   // those that can be extended.
15700b57cec5SDimitry Andric   Type *RetTy = CLI.RetTy;
15710b57cec5SDimitry Andric   MVT RetVT;
15720b57cec5SDimitry Andric   if (RetTy->isVoidTy())
15730b57cec5SDimitry Andric     RetVT = MVT::isVoid;
15740b57cec5SDimitry Andric   else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&
15750b57cec5SDimitry Andric            RetVT != MVT::i8)
15760b57cec5SDimitry Andric     return false;
15775ffd83dbSDimitry Andric   else if (RetVT == MVT::i1 && Subtarget->useCRBits())
15780b57cec5SDimitry Andric     // We can't handle boolean returns when CR bits are in use.
15790b57cec5SDimitry Andric     return false;
15800b57cec5SDimitry Andric 
15810b57cec5SDimitry Andric   // FIXME: No multi-register return values yet.
15820b57cec5SDimitry Andric   if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&
15830b57cec5SDimitry Andric       RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&
15840b57cec5SDimitry Andric       RetVT != MVT::f64) {
15850b57cec5SDimitry Andric     SmallVector<CCValAssign, 16> RVLocs;
15860b57cec5SDimitry Andric     CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);
15870b57cec5SDimitry Andric     CCInfo.AnalyzeCallResult(RetVT, RetCC_PPC64_ELF_FIS);
15880b57cec5SDimitry Andric     if (RVLocs.size() > 1)
15890b57cec5SDimitry Andric       return false;
15900b57cec5SDimitry Andric   }
15910b57cec5SDimitry Andric 
15920b57cec5SDimitry Andric   // Bail early if more than 8 arguments, as we only currently
15930b57cec5SDimitry Andric   // handle arguments passed in registers.
15940b57cec5SDimitry Andric   unsigned NumArgs = CLI.OutVals.size();
15950b57cec5SDimitry Andric   if (NumArgs > 8)
15960b57cec5SDimitry Andric     return false;
15970b57cec5SDimitry Andric 
15980b57cec5SDimitry Andric   // Set up the argument vectors.
15990b57cec5SDimitry Andric   SmallVector<Value*, 8> Args;
16000b57cec5SDimitry Andric   SmallVector<unsigned, 8> ArgRegs;
16010b57cec5SDimitry Andric   SmallVector<MVT, 8> ArgVTs;
16020b57cec5SDimitry Andric   SmallVector<ISD::ArgFlagsTy, 8> ArgFlags;
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric   Args.reserve(NumArgs);
16050b57cec5SDimitry Andric   ArgRegs.reserve(NumArgs);
16060b57cec5SDimitry Andric   ArgVTs.reserve(NumArgs);
16070b57cec5SDimitry Andric   ArgFlags.reserve(NumArgs);
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric   for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {
16100b57cec5SDimitry Andric     // Only handle easy calls for now.  It would be reasonably easy
16110b57cec5SDimitry Andric     // to handle <= 8-byte structures passed ByVal in registers, but we
16120b57cec5SDimitry Andric     // have to ensure they are right-justified in the register.
16130b57cec5SDimitry Andric     ISD::ArgFlagsTy Flags = CLI.OutFlags[i];
16140b57cec5SDimitry Andric     if (Flags.isInReg() || Flags.isSRet() || Flags.isNest() || Flags.isByVal())
16150b57cec5SDimitry Andric       return false;
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric     Value *ArgValue = CLI.OutVals[i];
16180b57cec5SDimitry Andric     Type *ArgTy = ArgValue->getType();
16190b57cec5SDimitry Andric     MVT ArgVT;
16200b57cec5SDimitry Andric     if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)
16210b57cec5SDimitry Andric       return false;
16220b57cec5SDimitry Andric 
1623e8d8bef9SDimitry Andric     // FIXME: FastISel cannot handle non-simple types yet, including 128-bit FP
1624e8d8bef9SDimitry Andric     // types, which is passed through vector register. Skip these types and
1625e8d8bef9SDimitry Andric     // fallback to default SelectionDAG based selection.
1626e8d8bef9SDimitry Andric     if (ArgVT.isVector() || ArgVT == MVT::f128)
16270b57cec5SDimitry Andric       return false;
16280b57cec5SDimitry Andric 
162904eeddc0SDimitry Andric     Register Arg = getRegForValue(ArgValue);
16300b57cec5SDimitry Andric     if (Arg == 0)
16310b57cec5SDimitry Andric       return false;
16320b57cec5SDimitry Andric 
16330b57cec5SDimitry Andric     Args.push_back(ArgValue);
16340b57cec5SDimitry Andric     ArgRegs.push_back(Arg);
16350b57cec5SDimitry Andric     ArgVTs.push_back(ArgVT);
16360b57cec5SDimitry Andric     ArgFlags.push_back(Flags);
16370b57cec5SDimitry Andric   }
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   // Process the arguments.
16400b57cec5SDimitry Andric   SmallVector<unsigned, 8> RegArgs;
16410b57cec5SDimitry Andric   unsigned NumBytes;
16420b57cec5SDimitry Andric 
16430b57cec5SDimitry Andric   if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,
16440b57cec5SDimitry Andric                        RegArgs, CC, NumBytes, IsVarArg))
16450b57cec5SDimitry Andric     return false;
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric   MachineInstrBuilder MIB;
16480b57cec5SDimitry Andric   // FIXME: No handling for function pointers yet.  This requires
16490b57cec5SDimitry Andric   // implementing the function descriptor (OPD) setup.
16500b57cec5SDimitry Andric   const GlobalValue *GV = dyn_cast<GlobalValue>(Callee);
16510b57cec5SDimitry Andric   if (!GV) {
16520b57cec5SDimitry Andric     // patchpoints are a special case; they always dispatch to a pointer value.
16530b57cec5SDimitry Andric     // However, we don't actually want to generate the indirect call sequence
16540b57cec5SDimitry Andric     // here (that will be generated, as necessary, during asm printing), and
16550b57cec5SDimitry Andric     // the call we generate here will be erased by FastISel::selectPatchpoint,
16560b57cec5SDimitry Andric     // so don't try very hard...
16570b57cec5SDimitry Andric     if (CLI.IsPatchPoint)
1658bdd1243dSDimitry Andric       MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::NOP));
16590b57cec5SDimitry Andric     else
16600b57cec5SDimitry Andric       return false;
16610b57cec5SDimitry Andric   } else {
16620b57cec5SDimitry Andric     // Build direct call with NOP for TOC restore.
16630b57cec5SDimitry Andric     // FIXME: We can and should optimize away the NOP for local calls.
1664bdd1243dSDimitry Andric     MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
16650b57cec5SDimitry Andric                   TII.get(PPC::BL8_NOP));
16660b57cec5SDimitry Andric     // Add callee.
16670b57cec5SDimitry Andric     MIB.addGlobalAddress(GV);
16680b57cec5SDimitry Andric   }
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric   // Add implicit physical register uses to the call.
1671*0fca6ea1SDimitry Andric   for (unsigned Reg : RegArgs)
1672*0fca6ea1SDimitry Andric     MIB.addReg(Reg, RegState::Implicit);
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   // Direct calls, in both the ELF V1 and V2 ABIs, need the TOC register live
16750b57cec5SDimitry Andric   // into the call.
16760b57cec5SDimitry Andric   PPCFuncInfo->setUsesTOCBasePtr();
16770b57cec5SDimitry Andric   MIB.addReg(PPC::X2, RegState::Implicit);
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric   // Add a register mask with the call-preserved registers.  Proper
16800b57cec5SDimitry Andric   // defs for return values will be added by setPhysRegsDeadExcept().
16810b57cec5SDimitry Andric   MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric   CLI.Call = MIB;
16840b57cec5SDimitry Andric 
16850b57cec5SDimitry Andric   // Finish off the call including any return values.
16860b57cec5SDimitry Andric   return finishCall(RetVT, CLI, NumBytes);
16870b57cec5SDimitry Andric }
16880b57cec5SDimitry Andric 
16890b57cec5SDimitry Andric // Attempt to fast-select a return instruction.
16900b57cec5SDimitry Andric bool PPCFastISel::SelectRet(const Instruction *I) {
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric   if (!FuncInfo.CanLowerReturn)
16930b57cec5SDimitry Andric     return false;
16940b57cec5SDimitry Andric 
16950b57cec5SDimitry Andric   const ReturnInst *Ret = cast<ReturnInst>(I);
16960b57cec5SDimitry Andric   const Function &F = *I->getParent()->getParent();
16970b57cec5SDimitry Andric 
16980b57cec5SDimitry Andric   // Build a list of return value registers.
16990b57cec5SDimitry Andric   SmallVector<unsigned, 4> RetRegs;
17000b57cec5SDimitry Andric   CallingConv::ID CC = F.getCallingConv();
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric   if (Ret->getNumOperands() > 0) {
17030b57cec5SDimitry Andric     SmallVector<ISD::OutputArg, 4> Outs;
17040b57cec5SDimitry Andric     GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric     // Analyze operands of the call, assigning locations to each operand.
17070b57cec5SDimitry Andric     SmallVector<CCValAssign, 16> ValLocs;
17080b57cec5SDimitry Andric     CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);
17090b57cec5SDimitry Andric     CCInfo.AnalyzeReturn(Outs, RetCC_PPC64_ELF_FIS);
17100b57cec5SDimitry Andric     const Value *RV = Ret->getOperand(0);
17110b57cec5SDimitry Andric 
17120b57cec5SDimitry Andric     // FIXME: Only one output register for now.
17130b57cec5SDimitry Andric     if (ValLocs.size() > 1)
17140b57cec5SDimitry Andric       return false;
17150b57cec5SDimitry Andric 
17160b57cec5SDimitry Andric     // Special case for returning a constant integer of any size - materialize
17170b57cec5SDimitry Andric     // the constant as an i64 and copy it to the return register.
17180b57cec5SDimitry Andric     if (const ConstantInt *CI = dyn_cast<ConstantInt>(RV)) {
17190b57cec5SDimitry Andric       CCValAssign &VA = ValLocs[0];
17200b57cec5SDimitry Andric 
17218bcb0991SDimitry Andric       Register RetReg = VA.getLocReg();
17220b57cec5SDimitry Andric       // We still need to worry about properly extending the sign. For example,
17230b57cec5SDimitry Andric       // we could have only a single bit or a constant that needs zero
17240b57cec5SDimitry Andric       // extension rather than sign extension. Make sure we pass the return
17250b57cec5SDimitry Andric       // value extension property to integer materialization.
17260b57cec5SDimitry Andric       unsigned SrcReg =
17270b57cec5SDimitry Andric           PPCMaterializeInt(CI, MVT::i64, VA.getLocInfo() != CCValAssign::ZExt);
17280b57cec5SDimitry Andric 
1729bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
17300b57cec5SDimitry Andric             TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);
17310b57cec5SDimitry Andric 
17320b57cec5SDimitry Andric       RetRegs.push_back(RetReg);
17330b57cec5SDimitry Andric 
17340b57cec5SDimitry Andric     } else {
173504eeddc0SDimitry Andric       Register Reg = getRegForValue(RV);
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric       if (Reg == 0)
17380b57cec5SDimitry Andric         return false;
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric       // Copy the result values into the output registers.
17410b57cec5SDimitry Andric       for (unsigned i = 0; i < ValLocs.size(); ++i) {
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric         CCValAssign &VA = ValLocs[i];
17440b57cec5SDimitry Andric         assert(VA.isRegLoc() && "Can only return in registers!");
17450b57cec5SDimitry Andric         RetRegs.push_back(VA.getLocReg());
17460b57cec5SDimitry Andric         unsigned SrcReg = Reg + VA.getValNo();
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric         EVT RVEVT = TLI.getValueType(DL, RV->getType());
17490b57cec5SDimitry Andric         if (!RVEVT.isSimple())
17500b57cec5SDimitry Andric           return false;
17510b57cec5SDimitry Andric         MVT RVVT = RVEVT.getSimpleVT();
17520b57cec5SDimitry Andric         MVT DestVT = VA.getLocVT();
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric         if (RVVT != DestVT && RVVT != MVT::i8 &&
17550b57cec5SDimitry Andric             RVVT != MVT::i16 && RVVT != MVT::i32)
17560b57cec5SDimitry Andric           return false;
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric         if (RVVT != DestVT) {
17590b57cec5SDimitry Andric           switch (VA.getLocInfo()) {
17600b57cec5SDimitry Andric             default:
17610b57cec5SDimitry Andric               llvm_unreachable("Unknown loc info!");
17620b57cec5SDimitry Andric             case CCValAssign::Full:
17630b57cec5SDimitry Andric               llvm_unreachable("Full value assign but types don't match?");
17640b57cec5SDimitry Andric             case CCValAssign::AExt:
17650b57cec5SDimitry Andric             case CCValAssign::ZExt: {
17660b57cec5SDimitry Andric               const TargetRegisterClass *RC =
17670b57cec5SDimitry Andric                 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
176804eeddc0SDimitry Andric               Register TmpReg = createResultReg(RC);
17690b57cec5SDimitry Andric               if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, true))
17700b57cec5SDimitry Andric                 return false;
17710b57cec5SDimitry Andric               SrcReg = TmpReg;
17720b57cec5SDimitry Andric               break;
17730b57cec5SDimitry Andric             }
17740b57cec5SDimitry Andric             case CCValAssign::SExt: {
17750b57cec5SDimitry Andric               const TargetRegisterClass *RC =
17760b57cec5SDimitry Andric                 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
177704eeddc0SDimitry Andric               Register TmpReg = createResultReg(RC);
17780b57cec5SDimitry Andric               if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, false))
17790b57cec5SDimitry Andric                 return false;
17800b57cec5SDimitry Andric               SrcReg = TmpReg;
17810b57cec5SDimitry Andric               break;
17820b57cec5SDimitry Andric             }
17830b57cec5SDimitry Andric           }
17840b57cec5SDimitry Andric         }
17850b57cec5SDimitry Andric 
1786bdd1243dSDimitry Andric         BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
17870b57cec5SDimitry Andric                 TII.get(TargetOpcode::COPY), RetRegs[i])
17880b57cec5SDimitry Andric           .addReg(SrcReg);
17890b57cec5SDimitry Andric       }
17900b57cec5SDimitry Andric     }
17910b57cec5SDimitry Andric   }
17920b57cec5SDimitry Andric 
1793bdd1243dSDimitry Andric   MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
17940b57cec5SDimitry Andric                                     TII.get(PPC::BLR8));
17950b57cec5SDimitry Andric 
1796*0fca6ea1SDimitry Andric   for (unsigned Reg : RetRegs)
1797*0fca6ea1SDimitry Andric     MIB.addReg(Reg, RegState::Implicit);
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric   return true;
18000b57cec5SDimitry Andric }
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric // Attempt to emit an integer extend of SrcReg into DestReg.  Both
18030b57cec5SDimitry Andric // signed and zero extensions are supported.  Return false if we
18040b57cec5SDimitry Andric // can't handle it.
18050b57cec5SDimitry Andric bool PPCFastISel::PPCEmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
18060b57cec5SDimitry Andric                                 unsigned DestReg, bool IsZExt) {
18070b57cec5SDimitry Andric   if (DestVT != MVT::i32 && DestVT != MVT::i64)
18080b57cec5SDimitry Andric     return false;
18090b57cec5SDimitry Andric   if (SrcVT != MVT::i8 && SrcVT != MVT::i16 && SrcVT != MVT::i32)
18100b57cec5SDimitry Andric     return false;
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   // Signed extensions use EXTSB, EXTSH, EXTSW.
18130b57cec5SDimitry Andric   if (!IsZExt) {
18140b57cec5SDimitry Andric     unsigned Opc;
18150b57cec5SDimitry Andric     if (SrcVT == MVT::i8)
18160b57cec5SDimitry Andric       Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;
18170b57cec5SDimitry Andric     else if (SrcVT == MVT::i16)
18180b57cec5SDimitry Andric       Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;
18190b57cec5SDimitry Andric     else {
18200b57cec5SDimitry Andric       assert(DestVT == MVT::i64 && "Signed extend from i32 to i32??");
18210b57cec5SDimitry Andric       Opc = PPC::EXTSW_32_64;
18220b57cec5SDimitry Andric     }
1823bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
18240b57cec5SDimitry Andric       .addReg(SrcReg);
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric   // Unsigned 32-bit extensions use RLWINM.
18270b57cec5SDimitry Andric   } else if (DestVT == MVT::i32) {
18280b57cec5SDimitry Andric     unsigned MB;
18290b57cec5SDimitry Andric     if (SrcVT == MVT::i8)
18300b57cec5SDimitry Andric       MB = 24;
18310b57cec5SDimitry Andric     else {
18320b57cec5SDimitry Andric       assert(SrcVT == MVT::i16 && "Unsigned extend from i32 to i32??");
18330b57cec5SDimitry Andric       MB = 16;
18340b57cec5SDimitry Andric     }
1835bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLWINM),
18360b57cec5SDimitry Andric             DestReg)
18370b57cec5SDimitry Andric       .addReg(SrcReg).addImm(/*SH=*/0).addImm(MB).addImm(/*ME=*/31);
18380b57cec5SDimitry Andric 
18390b57cec5SDimitry Andric   // Unsigned 64-bit extensions use RLDICL (with a 32-bit source).
18400b57cec5SDimitry Andric   } else {
18410b57cec5SDimitry Andric     unsigned MB;
18420b57cec5SDimitry Andric     if (SrcVT == MVT::i8)
18430b57cec5SDimitry Andric       MB = 56;
18440b57cec5SDimitry Andric     else if (SrcVT == MVT::i16)
18450b57cec5SDimitry Andric       MB = 48;
18460b57cec5SDimitry Andric     else
18470b57cec5SDimitry Andric       MB = 32;
1848bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
18490b57cec5SDimitry Andric             TII.get(PPC::RLDICL_32_64), DestReg)
18500b57cec5SDimitry Andric       .addReg(SrcReg).addImm(/*SH=*/0).addImm(MB);
18510b57cec5SDimitry Andric   }
18520b57cec5SDimitry Andric 
18530b57cec5SDimitry Andric   return true;
18540b57cec5SDimitry Andric }
18550b57cec5SDimitry Andric 
18560b57cec5SDimitry Andric // Attempt to fast-select an indirect branch instruction.
18570b57cec5SDimitry Andric bool PPCFastISel::SelectIndirectBr(const Instruction *I) {
185804eeddc0SDimitry Andric   Register AddrReg = getRegForValue(I->getOperand(0));
18590b57cec5SDimitry Andric   if (AddrReg == 0)
18600b57cec5SDimitry Andric     return false;
18610b57cec5SDimitry Andric 
1862bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::MTCTR8))
18630b57cec5SDimitry Andric     .addReg(AddrReg);
1864bdd1243dSDimitry Andric   BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCTR8));
18650b57cec5SDimitry Andric 
18660b57cec5SDimitry Andric   const IndirectBrInst *IB = cast<IndirectBrInst>(I);
18670b57cec5SDimitry Andric   for (const BasicBlock *SuccBB : IB->successors())
18680b57cec5SDimitry Andric     FuncInfo.MBB->addSuccessor(FuncInfo.MBBMap[SuccBB]);
18690b57cec5SDimitry Andric 
18700b57cec5SDimitry Andric   return true;
18710b57cec5SDimitry Andric }
18720b57cec5SDimitry Andric 
18730b57cec5SDimitry Andric // Attempt to fast-select an integer truncate instruction.
18740b57cec5SDimitry Andric bool PPCFastISel::SelectTrunc(const Instruction *I) {
18750b57cec5SDimitry Andric   Value *Src  = I->getOperand(0);
18760b57cec5SDimitry Andric   EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);
18770b57cec5SDimitry Andric   EVT DestVT = TLI.getValueType(DL, I->getType(), true);
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric   if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)
18800b57cec5SDimitry Andric     return false;
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric   if (DestVT != MVT::i32 && DestVT != MVT::i16 && DestVT != MVT::i8)
18830b57cec5SDimitry Andric     return false;
18840b57cec5SDimitry Andric 
188504eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
18860b57cec5SDimitry Andric   if (!SrcReg)
18870b57cec5SDimitry Andric     return false;
18880b57cec5SDimitry Andric 
18890b57cec5SDimitry Andric   // The only interesting case is when we need to switch register classes.
18900b57cec5SDimitry Andric   if (SrcVT == MVT::i64)
18910b57cec5SDimitry Andric     SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);
18920b57cec5SDimitry Andric 
18930b57cec5SDimitry Andric   updateValueMap(I, SrcReg);
18940b57cec5SDimitry Andric   return true;
18950b57cec5SDimitry Andric }
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric // Attempt to fast-select an integer extend instruction.
18980b57cec5SDimitry Andric bool PPCFastISel::SelectIntExt(const Instruction *I) {
18990b57cec5SDimitry Andric   Type *DestTy = I->getType();
19000b57cec5SDimitry Andric   Value *Src = I->getOperand(0);
19010b57cec5SDimitry Andric   Type *SrcTy = Src->getType();
19020b57cec5SDimitry Andric 
19030b57cec5SDimitry Andric   bool IsZExt = isa<ZExtInst>(I);
190404eeddc0SDimitry Andric   Register SrcReg = getRegForValue(Src);
19050b57cec5SDimitry Andric   if (!SrcReg) return false;
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric   EVT SrcEVT, DestEVT;
19080b57cec5SDimitry Andric   SrcEVT = TLI.getValueType(DL, SrcTy, true);
19090b57cec5SDimitry Andric   DestEVT = TLI.getValueType(DL, DestTy, true);
19100b57cec5SDimitry Andric   if (!SrcEVT.isSimple())
19110b57cec5SDimitry Andric     return false;
19120b57cec5SDimitry Andric   if (!DestEVT.isSimple())
19130b57cec5SDimitry Andric     return false;
19140b57cec5SDimitry Andric 
19150b57cec5SDimitry Andric   MVT SrcVT = SrcEVT.getSimpleVT();
19160b57cec5SDimitry Andric   MVT DestVT = DestEVT.getSimpleVT();
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric   // If we know the register class needed for the result of this
19190b57cec5SDimitry Andric   // instruction, use it.  Otherwise pick the register class of the
19200b57cec5SDimitry Andric   // correct size that does not contain X0/R0, since we don't know
19210b57cec5SDimitry Andric   // whether downstream uses permit that assignment.
192204eeddc0SDimitry Andric   Register AssignedReg = FuncInfo.ValueMap[I];
19230b57cec5SDimitry Andric   const TargetRegisterClass *RC =
19240b57cec5SDimitry Andric     (AssignedReg ? MRI.getRegClass(AssignedReg) :
19250b57cec5SDimitry Andric      (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :
19260b57cec5SDimitry Andric       &PPC::GPRC_and_GPRC_NOR0RegClass));
192704eeddc0SDimitry Andric   Register ResultReg = createResultReg(RC);
19280b57cec5SDimitry Andric 
19290b57cec5SDimitry Andric   if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))
19300b57cec5SDimitry Andric     return false;
19310b57cec5SDimitry Andric 
19320b57cec5SDimitry Andric   updateValueMap(I, ResultReg);
19330b57cec5SDimitry Andric   return true;
19340b57cec5SDimitry Andric }
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric // Attempt to fast-select an instruction that wasn't handled by
19370b57cec5SDimitry Andric // the table-generated machinery.
19380b57cec5SDimitry Andric bool PPCFastISel::fastSelectInstruction(const Instruction *I) {
19390b57cec5SDimitry Andric 
19400b57cec5SDimitry Andric   switch (I->getOpcode()) {
19410b57cec5SDimitry Andric     case Instruction::Load:
19420b57cec5SDimitry Andric       return SelectLoad(I);
19430b57cec5SDimitry Andric     case Instruction::Store:
19440b57cec5SDimitry Andric       return SelectStore(I);
19450b57cec5SDimitry Andric     case Instruction::Br:
19460b57cec5SDimitry Andric       return SelectBranch(I);
19470b57cec5SDimitry Andric     case Instruction::IndirectBr:
19480b57cec5SDimitry Andric       return SelectIndirectBr(I);
19490b57cec5SDimitry Andric     case Instruction::FPExt:
19500b57cec5SDimitry Andric       return SelectFPExt(I);
19510b57cec5SDimitry Andric     case Instruction::FPTrunc:
19520b57cec5SDimitry Andric       return SelectFPTrunc(I);
19530b57cec5SDimitry Andric     case Instruction::SIToFP:
19540b57cec5SDimitry Andric       return SelectIToFP(I, /*IsSigned*/ true);
19550b57cec5SDimitry Andric     case Instruction::UIToFP:
19560b57cec5SDimitry Andric       return SelectIToFP(I, /*IsSigned*/ false);
19570b57cec5SDimitry Andric     case Instruction::FPToSI:
19580b57cec5SDimitry Andric       return SelectFPToI(I, /*IsSigned*/ true);
19590b57cec5SDimitry Andric     case Instruction::FPToUI:
19600b57cec5SDimitry Andric       return SelectFPToI(I, /*IsSigned*/ false);
19610b57cec5SDimitry Andric     case Instruction::Add:
19620b57cec5SDimitry Andric       return SelectBinaryIntOp(I, ISD::ADD);
19630b57cec5SDimitry Andric     case Instruction::Or:
19640b57cec5SDimitry Andric       return SelectBinaryIntOp(I, ISD::OR);
19650b57cec5SDimitry Andric     case Instruction::Sub:
19660b57cec5SDimitry Andric       return SelectBinaryIntOp(I, ISD::SUB);
19670b57cec5SDimitry Andric     case Instruction::Ret:
19680b57cec5SDimitry Andric       return SelectRet(I);
19690b57cec5SDimitry Andric     case Instruction::Trunc:
19700b57cec5SDimitry Andric       return SelectTrunc(I);
19710b57cec5SDimitry Andric     case Instruction::ZExt:
19720b57cec5SDimitry Andric     case Instruction::SExt:
19730b57cec5SDimitry Andric       return SelectIntExt(I);
19740b57cec5SDimitry Andric     // Here add other flavors of Instruction::XXX that automated
19750b57cec5SDimitry Andric     // cases don't catch.  For example, switches are terminators
19760b57cec5SDimitry Andric     // that aren't yet handled.
19770b57cec5SDimitry Andric     default:
19780b57cec5SDimitry Andric       break;
19790b57cec5SDimitry Andric   }
19800b57cec5SDimitry Andric   return false;
19810b57cec5SDimitry Andric }
19820b57cec5SDimitry Andric 
19830b57cec5SDimitry Andric // Materialize a floating-point constant into a register, and return
19840b57cec5SDimitry Andric // the register number (or zero if we failed to handle it).
19850b57cec5SDimitry Andric unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
1986e8d8bef9SDimitry Andric   // If this is a PC-Rel function, let SDISel handle constant pool.
1987e8d8bef9SDimitry Andric   if (Subtarget->isUsingPCRelativeCalls())
1988e8d8bef9SDimitry Andric     return false;
1989e8d8bef9SDimitry Andric 
19900b57cec5SDimitry Andric   // No plans to handle long double here.
19910b57cec5SDimitry Andric   if (VT != MVT::f32 && VT != MVT::f64)
19920b57cec5SDimitry Andric     return 0;
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric   // All FP constants are loaded from the constant pool.
19955ffd83dbSDimitry Andric   Align Alignment = DL.getPrefTypeAlign(CFP->getType());
19965ffd83dbSDimitry Andric   unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Alignment);
19975ffd83dbSDimitry Andric   const bool HasSPE = Subtarget->hasSPE();
19980b57cec5SDimitry Andric   const TargetRegisterClass *RC;
19990b57cec5SDimitry Andric   if (HasSPE)
20008bcb0991SDimitry Andric     RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);
20010b57cec5SDimitry Andric   else
20020b57cec5SDimitry Andric     RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);
20030b57cec5SDimitry Andric 
200404eeddc0SDimitry Andric   Register DestReg = createResultReg(RC);
20050b57cec5SDimitry Andric   CodeModel::Model CModel = TM.getCodeModel();
20060b57cec5SDimitry Andric 
20070b57cec5SDimitry Andric   MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
20080b57cec5SDimitry Andric       MachinePointerInfo::getConstantPool(*FuncInfo.MF),
20095ffd83dbSDimitry Andric       MachineMemOperand::MOLoad, (VT == MVT::f32) ? 4 : 8, Alignment);
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric   unsigned Opc;
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   if (HasSPE)
20140b57cec5SDimitry Andric     Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);
20150b57cec5SDimitry Andric   else
20160b57cec5SDimitry Andric     Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);
20170b57cec5SDimitry Andric 
201804eeddc0SDimitry Andric   Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
20190b57cec5SDimitry Andric 
20200b57cec5SDimitry Andric   PPCFuncInfo->setUsesTOCBasePtr();
20210b57cec5SDimitry Andric   // For small code model, generate a LF[SD](0, LDtocCPT(Idx, X2)).
20220b57cec5SDimitry Andric   if (CModel == CodeModel::Small) {
2023bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocCPT),
20240b57cec5SDimitry Andric             TmpReg)
20250b57cec5SDimitry Andric       .addConstantPoolIndex(Idx).addReg(PPC::X2);
2026bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
20270b57cec5SDimitry Andric       .addImm(0).addReg(TmpReg).addMemOperand(MMO);
20280b57cec5SDimitry Andric   } else {
20298bcb0991SDimitry Andric     // Otherwise we generate LF[SD](Idx[lo], ADDIStocHA8(X2, Idx)).
2030bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
20310b57cec5SDimitry Andric             TmpReg).addReg(PPC::X2).addConstantPoolIndex(Idx);
20320b57cec5SDimitry Andric     // But for large code model, we must generate a LDtocL followed
20330b57cec5SDimitry Andric     // by the LF[SD].
20340b57cec5SDimitry Andric     if (CModel == CodeModel::Large) {
203504eeddc0SDimitry Andric       Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2036bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
20370b57cec5SDimitry Andric               TmpReg2).addConstantPoolIndex(Idx).addReg(TmpReg);
2038bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
20390b57cec5SDimitry Andric           .addImm(0)
20400b57cec5SDimitry Andric           .addReg(TmpReg2);
20410b57cec5SDimitry Andric     } else
2042bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), DestReg)
20430b57cec5SDimitry Andric         .addConstantPoolIndex(Idx, 0, PPCII::MO_TOC_LO)
20440b57cec5SDimitry Andric         .addReg(TmpReg)
20450b57cec5SDimitry Andric         .addMemOperand(MMO);
20460b57cec5SDimitry Andric   }
20470b57cec5SDimitry Andric 
20480b57cec5SDimitry Andric   return DestReg;
20490b57cec5SDimitry Andric }
20500b57cec5SDimitry Andric 
20510b57cec5SDimitry Andric // Materialize the address of a global value into a register, and return
20520b57cec5SDimitry Andric // the register number (or zero if we failed to handle it).
20530b57cec5SDimitry Andric unsigned PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {
2054e8d8bef9SDimitry Andric   // If this is a PC-Rel function, let SDISel handle GV materialization.
2055e8d8bef9SDimitry Andric   if (Subtarget->isUsingPCRelativeCalls())
2056e8d8bef9SDimitry Andric     return false;
2057e8d8bef9SDimitry Andric 
20580b57cec5SDimitry Andric   assert(VT == MVT::i64 && "Non-address!");
20590b57cec5SDimitry Andric   const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;
206004eeddc0SDimitry Andric   Register DestReg = createResultReg(RC);
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   // Global values may be plain old object addresses, TLS object
20630b57cec5SDimitry Andric   // addresses, constant pool entries, or jump tables.  How we generate
20640b57cec5SDimitry Andric   // code for these may depend on small, medium, or large code model.
20650b57cec5SDimitry Andric   CodeModel::Model CModel = TM.getCodeModel();
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric   // FIXME: Jump tables are not yet required because fast-isel doesn't
20680b57cec5SDimitry Andric   // handle switches; if that changes, we need them as well.  For now,
20690b57cec5SDimitry Andric   // what follows assumes everything's a generic (or TLS) global address.
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric   // FIXME: We don't yet handle the complexity of TLS.
20720b57cec5SDimitry Andric   if (GV->isThreadLocal())
20730b57cec5SDimitry Andric     return 0;
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric   PPCFuncInfo->setUsesTOCBasePtr();
2076*0fca6ea1SDimitry Andric   bool IsAIXTocData = TM.getTargetTriple().isOSAIX() &&
2077*0fca6ea1SDimitry Andric                       isa<GlobalVariable>(GV) &&
2078*0fca6ea1SDimitry Andric                       cast<GlobalVariable>(GV)->hasAttribute("toc-data");
2079*0fca6ea1SDimitry Andric 
20800b57cec5SDimitry Andric   // For small code model, generate a simple TOC load.
2081*0fca6ea1SDimitry Andric   if (CModel == CodeModel::Small) {
2082*0fca6ea1SDimitry Andric     auto MIB = BuildMI(
2083*0fca6ea1SDimitry Andric         *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
2084*0fca6ea1SDimitry Andric         IsAIXTocData ? TII.get(PPC::ADDItoc8) : TII.get(PPC::LDtoc), DestReg);
2085*0fca6ea1SDimitry Andric     if (IsAIXTocData)
2086*0fca6ea1SDimitry Andric       MIB.addReg(PPC::X2).addGlobalAddress(GV);
2087*0fca6ea1SDimitry Andric     else
2088*0fca6ea1SDimitry Andric       MIB.addGlobalAddress(GV).addReg(PPC::X2);
2089*0fca6ea1SDimitry Andric   } else {
20900b57cec5SDimitry Andric     // If the address is an externally defined symbol, a symbol with common
20910b57cec5SDimitry Andric     // or externally available linkage, a non-local function address, or a
20920b57cec5SDimitry Andric     // jump table address (not yet needed), or if we are generating code
20930b57cec5SDimitry Andric     // for large code model, we generate:
20948bcb0991SDimitry Andric     //       LDtocL(GV, ADDIStocHA8(%x2, GV))
20950b57cec5SDimitry Andric     // Otherwise we generate:
2096*0fca6ea1SDimitry Andric     //       ADDItocL8(ADDIStocHA8(%x2, GV), GV)
20978bcb0991SDimitry Andric     // Either way, start with the ADDIStocHA8:
209804eeddc0SDimitry Andric     Register HighPartReg = createResultReg(RC);
2099bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),
21000b57cec5SDimitry Andric             HighPartReg).addReg(PPC::X2).addGlobalAddress(GV);
21010b57cec5SDimitry Andric 
21025ffd83dbSDimitry Andric     if (Subtarget->isGVIndirectSymbol(GV)) {
2103*0fca6ea1SDimitry Andric       assert(!IsAIXTocData && "TOC data should always be direct.");
2104bdd1243dSDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),
21050b57cec5SDimitry Andric               DestReg).addGlobalAddress(GV).addReg(HighPartReg);
21060b57cec5SDimitry Andric     } else {
2107*0fca6ea1SDimitry Andric       // Otherwise generate the ADDItocL8.
2108*0fca6ea1SDimitry Andric       BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDItocL8),
2109*0fca6ea1SDimitry Andric               DestReg)
2110*0fca6ea1SDimitry Andric           .addReg(HighPartReg)
2111*0fca6ea1SDimitry Andric           .addGlobalAddress(GV);
21120b57cec5SDimitry Andric     }
21130b57cec5SDimitry Andric   }
21140b57cec5SDimitry Andric 
21150b57cec5SDimitry Andric   return DestReg;
21160b57cec5SDimitry Andric }
21170b57cec5SDimitry Andric 
21180b57cec5SDimitry Andric // Materialize a 32-bit integer constant into a register, and return
21190b57cec5SDimitry Andric // the register number (or zero if we failed to handle it).
21200b57cec5SDimitry Andric unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
21210b57cec5SDimitry Andric                                              const TargetRegisterClass *RC) {
21220b57cec5SDimitry Andric   unsigned Lo = Imm & 0xFFFF;
21230b57cec5SDimitry Andric   unsigned Hi = (Imm >> 16) & 0xFFFF;
21240b57cec5SDimitry Andric 
212504eeddc0SDimitry Andric   Register ResultReg = createResultReg(RC);
21260b57cec5SDimitry Andric   bool IsGPRC = RC->hasSuperClassEq(&PPC::GPRCRegClass);
21270b57cec5SDimitry Andric 
21280b57cec5SDimitry Andric   if (isInt<16>(Imm))
2129bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
21300b57cec5SDimitry Andric             TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
21310b57cec5SDimitry Andric       .addImm(Imm);
21320b57cec5SDimitry Andric   else if (Lo) {
21330b57cec5SDimitry Andric     // Both Lo and Hi have nonzero bits.
213404eeddc0SDimitry Andric     Register TmpReg = createResultReg(RC);
2135bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
21360b57cec5SDimitry Andric             TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
21370b57cec5SDimitry Andric       .addImm(Hi);
2138bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
21390b57cec5SDimitry Andric             TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
21400b57cec5SDimitry Andric       .addReg(TmpReg).addImm(Lo);
21410b57cec5SDimitry Andric   } else
21420b57cec5SDimitry Andric     // Just Hi bits.
2143bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
21440b57cec5SDimitry Andric             TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
21450b57cec5SDimitry Andric         .addImm(Hi);
21460b57cec5SDimitry Andric 
21470b57cec5SDimitry Andric   return ResultReg;
21480b57cec5SDimitry Andric }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric // Materialize a 64-bit integer constant into a register, and return
21510b57cec5SDimitry Andric // the register number (or zero if we failed to handle it).
21520b57cec5SDimitry Andric unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
21530b57cec5SDimitry Andric                                              const TargetRegisterClass *RC) {
21540b57cec5SDimitry Andric   unsigned Remainder = 0;
21550b57cec5SDimitry Andric   unsigned Shift = 0;
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric   // If the value doesn't fit in 32 bits, see if we can shift it
21580b57cec5SDimitry Andric   // so that it fits in 32 bits.
21590b57cec5SDimitry Andric   if (!isInt<32>(Imm)) {
216006c3fb27SDimitry Andric     Shift = llvm::countr_zero<uint64_t>(Imm);
21610b57cec5SDimitry Andric     int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric     if (isInt<32>(ImmSh))
21640b57cec5SDimitry Andric       Imm = ImmSh;
21650b57cec5SDimitry Andric     else {
21660b57cec5SDimitry Andric       Remainder = Imm;
21670b57cec5SDimitry Andric       Shift = 32;
21680b57cec5SDimitry Andric       Imm >>= 32;
21690b57cec5SDimitry Andric     }
21700b57cec5SDimitry Andric   }
21710b57cec5SDimitry Andric 
21720b57cec5SDimitry Andric   // Handle the high-order 32 bits (if shifted) or the whole 32 bits
21730b57cec5SDimitry Andric   // (if not shifted).
21740b57cec5SDimitry Andric   unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
21750b57cec5SDimitry Andric   if (!Shift)
21760b57cec5SDimitry Andric     return TmpReg1;
21770b57cec5SDimitry Andric 
21780b57cec5SDimitry Andric   // If upper 32 bits were not zero, we've built them and need to shift
21790b57cec5SDimitry Andric   // them into place.
21800b57cec5SDimitry Andric   unsigned TmpReg2;
21810b57cec5SDimitry Andric   if (Imm) {
21820b57cec5SDimitry Andric     TmpReg2 = createResultReg(RC);
2183bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLDICR),
21840b57cec5SDimitry Andric             TmpReg2).addReg(TmpReg1).addImm(Shift).addImm(63 - Shift);
21850b57cec5SDimitry Andric   } else
21860b57cec5SDimitry Andric     TmpReg2 = TmpReg1;
21870b57cec5SDimitry Andric 
21880b57cec5SDimitry Andric   unsigned TmpReg3, Hi, Lo;
21890b57cec5SDimitry Andric   if ((Hi = (Remainder >> 16) & 0xFFFF)) {
21900b57cec5SDimitry Andric     TmpReg3 = createResultReg(RC);
2191bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORIS8),
21920b57cec5SDimitry Andric             TmpReg3).addReg(TmpReg2).addImm(Hi);
21930b57cec5SDimitry Andric   } else
21940b57cec5SDimitry Andric     TmpReg3 = TmpReg2;
21950b57cec5SDimitry Andric 
21960b57cec5SDimitry Andric   if ((Lo = Remainder & 0xFFFF)) {
219704eeddc0SDimitry Andric     Register ResultReg = createResultReg(RC);
2198bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORI8),
21990b57cec5SDimitry Andric             ResultReg).addReg(TmpReg3).addImm(Lo);
22000b57cec5SDimitry Andric     return ResultReg;
22010b57cec5SDimitry Andric   }
22020b57cec5SDimitry Andric 
22030b57cec5SDimitry Andric   return TmpReg3;
22040b57cec5SDimitry Andric }
22050b57cec5SDimitry Andric 
22060b57cec5SDimitry Andric // Materialize an integer constant into a register, and return
22070b57cec5SDimitry Andric // the register number (or zero if we failed to handle it).
22080b57cec5SDimitry Andric unsigned PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT,
22090b57cec5SDimitry Andric                                         bool UseSExt) {
22100b57cec5SDimitry Andric   // If we're using CR bit registers for i1 values, handle that as a special
22110b57cec5SDimitry Andric   // case first.
22125ffd83dbSDimitry Andric   if (VT == MVT::i1 && Subtarget->useCRBits()) {
221304eeddc0SDimitry Andric     Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2214bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
22150b57cec5SDimitry Andric             TII.get(CI->isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);
22160b57cec5SDimitry Andric     return ImmReg;
22170b57cec5SDimitry Andric   }
22180b57cec5SDimitry Andric 
22190b57cec5SDimitry Andric   if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
22200b57cec5SDimitry Andric       VT != MVT::i1)
22210b57cec5SDimitry Andric     return 0;
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric   const TargetRegisterClass *RC =
22240b57cec5SDimitry Andric       ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);
22250b57cec5SDimitry Andric   int64_t Imm = UseSExt ? CI->getSExtValue() : CI->getZExtValue();
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric   // If the constant is in range, use a load-immediate.
22280b57cec5SDimitry Andric   // Since LI will sign extend the constant we need to make sure that for
22290b57cec5SDimitry Andric   // our zeroext constants that the sign extended constant fits into 16-bits -
22300b57cec5SDimitry Andric   // a range of 0..0x7fff.
22310b57cec5SDimitry Andric   if (isInt<16>(Imm)) {
22320b57cec5SDimitry Andric     unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
223304eeddc0SDimitry Andric     Register ImmReg = createResultReg(RC);
2234bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ImmReg)
22350b57cec5SDimitry Andric         .addImm(Imm);
22360b57cec5SDimitry Andric     return ImmReg;
22370b57cec5SDimitry Andric   }
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric   // Construct the constant piecewise.
22400b57cec5SDimitry Andric   if (VT == MVT::i64)
22410b57cec5SDimitry Andric     return PPCMaterialize64BitInt(Imm, RC);
22420b57cec5SDimitry Andric   else if (VT == MVT::i32)
22430b57cec5SDimitry Andric     return PPCMaterialize32BitInt(Imm, RC);
22440b57cec5SDimitry Andric 
22450b57cec5SDimitry Andric   return 0;
22460b57cec5SDimitry Andric }
22470b57cec5SDimitry Andric 
22480b57cec5SDimitry Andric // Materialize a constant into a register, and return the register
22490b57cec5SDimitry Andric // number (or zero if we failed to handle it).
22500b57cec5SDimitry Andric unsigned PPCFastISel::fastMaterializeConstant(const Constant *C) {
22510b57cec5SDimitry Andric   EVT CEVT = TLI.getValueType(DL, C->getType(), true);
22520b57cec5SDimitry Andric 
22530b57cec5SDimitry Andric   // Only handle simple types.
22540b57cec5SDimitry Andric   if (!CEVT.isSimple()) return 0;
22550b57cec5SDimitry Andric   MVT VT = CEVT.getSimpleVT();
22560b57cec5SDimitry Andric 
22570b57cec5SDimitry Andric   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
22580b57cec5SDimitry Andric     return PPCMaterializeFP(CFP, VT);
22590b57cec5SDimitry Andric   else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
22600b57cec5SDimitry Andric     return PPCMaterializeGV(GV, VT);
22610b57cec5SDimitry Andric   else if (const ConstantInt *CI = dyn_cast<ConstantInt>(C))
22620b57cec5SDimitry Andric     // Note that the code in FunctionLoweringInfo::ComputePHILiveOutRegInfo
22630b57cec5SDimitry Andric     // assumes that constant PHI operands will be zero extended, and failure to
22640b57cec5SDimitry Andric     // match that assumption will cause problems if we sign extend here but
22650b57cec5SDimitry Andric     // some user of a PHI is in a block for which we fall back to full SDAG
22660b57cec5SDimitry Andric     // instruction selection.
22670b57cec5SDimitry Andric     return PPCMaterializeInt(CI, VT, false);
22680b57cec5SDimitry Andric 
22690b57cec5SDimitry Andric   return 0;
22700b57cec5SDimitry Andric }
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric // Materialize the address created by an alloca into a register, and
22730b57cec5SDimitry Andric // return the register number (or zero if we failed to handle it).
22740b57cec5SDimitry Andric unsigned PPCFastISel::fastMaterializeAlloca(const AllocaInst *AI) {
22750b57cec5SDimitry Andric   // Don't handle dynamic allocas.
22760b57cec5SDimitry Andric   if (!FuncInfo.StaticAllocaMap.count(AI)) return 0;
22770b57cec5SDimitry Andric 
22780b57cec5SDimitry Andric   MVT VT;
22790b57cec5SDimitry Andric   if (!isLoadTypeLegal(AI->getType(), VT)) return 0;
22800b57cec5SDimitry Andric 
22810b57cec5SDimitry Andric   DenseMap<const AllocaInst*, int>::iterator SI =
22820b57cec5SDimitry Andric     FuncInfo.StaticAllocaMap.find(AI);
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric   if (SI != FuncInfo.StaticAllocaMap.end()) {
228504eeddc0SDimitry Andric     Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
2286bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),
22870b57cec5SDimitry Andric             ResultReg).addFrameIndex(SI->second).addImm(0);
22880b57cec5SDimitry Andric     return ResultReg;
22890b57cec5SDimitry Andric   }
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric   return 0;
22920b57cec5SDimitry Andric }
22930b57cec5SDimitry Andric 
22940b57cec5SDimitry Andric // Fold loads into extends when possible.
22950b57cec5SDimitry Andric // FIXME: We can have multiple redundant extend/trunc instructions
22960b57cec5SDimitry Andric // following a load.  The folding only picks up one.  Extend this
22970b57cec5SDimitry Andric // to check subsequent instructions for the same pattern and remove
22980b57cec5SDimitry Andric // them.  Thus ResultReg should be the def reg for the last redundant
22990b57cec5SDimitry Andric // instruction in a chain, and all intervening instructions can be
23000b57cec5SDimitry Andric // removed from parent.  Change test/CodeGen/PowerPC/fast-isel-fold.ll
23010b57cec5SDimitry Andric // to add ELF64-NOT: rldicl to the appropriate tests when this works.
23020b57cec5SDimitry Andric bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
23030b57cec5SDimitry Andric                                       const LoadInst *LI) {
23040b57cec5SDimitry Andric   // Verify we have a legal type before going any further.
23050b57cec5SDimitry Andric   MVT VT;
23060b57cec5SDimitry Andric   if (!isLoadTypeLegal(LI->getType(), VT))
23070b57cec5SDimitry Andric     return false;
23080b57cec5SDimitry Andric 
23090b57cec5SDimitry Andric   // Combine load followed by zero- or sign-extend.
23100b57cec5SDimitry Andric   bool IsZExt = false;
23110b57cec5SDimitry Andric   switch(MI->getOpcode()) {
23120b57cec5SDimitry Andric     default:
23130b57cec5SDimitry Andric       return false;
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric     case PPC::RLDICL:
23160b57cec5SDimitry Andric     case PPC::RLDICL_32_64: {
23170b57cec5SDimitry Andric       IsZExt = true;
23180b57cec5SDimitry Andric       unsigned MB = MI->getOperand(3).getImm();
23190b57cec5SDimitry Andric       if ((VT == MVT::i8 && MB <= 56) ||
23200b57cec5SDimitry Andric           (VT == MVT::i16 && MB <= 48) ||
23210b57cec5SDimitry Andric           (VT == MVT::i32 && MB <= 32))
23220b57cec5SDimitry Andric         break;
23230b57cec5SDimitry Andric       return false;
23240b57cec5SDimitry Andric     }
23250b57cec5SDimitry Andric 
23260b57cec5SDimitry Andric     case PPC::RLWINM:
23270b57cec5SDimitry Andric     case PPC::RLWINM8: {
23280b57cec5SDimitry Andric       IsZExt = true;
23290b57cec5SDimitry Andric       unsigned MB = MI->getOperand(3).getImm();
23300b57cec5SDimitry Andric       if ((VT == MVT::i8 && MB <= 24) ||
23310b57cec5SDimitry Andric           (VT == MVT::i16 && MB <= 16))
23320b57cec5SDimitry Andric         break;
23330b57cec5SDimitry Andric       return false;
23340b57cec5SDimitry Andric     }
23350b57cec5SDimitry Andric 
23360b57cec5SDimitry Andric     case PPC::EXTSB:
23370b57cec5SDimitry Andric     case PPC::EXTSB8:
23380b57cec5SDimitry Andric     case PPC::EXTSB8_32_64:
23390b57cec5SDimitry Andric       /* There is no sign-extending load-byte instruction. */
23400b57cec5SDimitry Andric       return false;
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric     case PPC::EXTSH:
23430b57cec5SDimitry Andric     case PPC::EXTSH8:
23440b57cec5SDimitry Andric     case PPC::EXTSH8_32_64: {
23450b57cec5SDimitry Andric       if (VT != MVT::i16 && VT != MVT::i8)
23460b57cec5SDimitry Andric         return false;
23470b57cec5SDimitry Andric       break;
23480b57cec5SDimitry Andric     }
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric     case PPC::EXTSW:
23510b57cec5SDimitry Andric     case PPC::EXTSW_32:
23520b57cec5SDimitry Andric     case PPC::EXTSW_32_64: {
23530b57cec5SDimitry Andric       if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8)
23540b57cec5SDimitry Andric         return false;
23550b57cec5SDimitry Andric       break;
23560b57cec5SDimitry Andric     }
23570b57cec5SDimitry Andric   }
23580b57cec5SDimitry Andric 
23590b57cec5SDimitry Andric   // See if we can handle this address.
23600b57cec5SDimitry Andric   Address Addr;
23610b57cec5SDimitry Andric   if (!PPCComputeAddress(LI->getOperand(0), Addr))
23620b57cec5SDimitry Andric     return false;
23630b57cec5SDimitry Andric 
23648bcb0991SDimitry Andric   Register ResultReg = MI->getOperand(0).getReg();
23650b57cec5SDimitry Andric 
23660b57cec5SDimitry Andric   if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt,
23675ffd83dbSDimitry Andric                    Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))
23680b57cec5SDimitry Andric     return false;
23690b57cec5SDimitry Andric 
23700b57cec5SDimitry Andric   MachineBasicBlock::iterator I(MI);
23710b57cec5SDimitry Andric   removeDeadCode(I, std::next(I));
23720b57cec5SDimitry Andric   return true;
23730b57cec5SDimitry Andric }
23740b57cec5SDimitry Andric 
23750b57cec5SDimitry Andric // Attempt to lower call arguments in a faster way than done by
23760b57cec5SDimitry Andric // the selection DAG code.
23770b57cec5SDimitry Andric bool PPCFastISel::fastLowerArguments() {
23780b57cec5SDimitry Andric   // Defer to normal argument lowering for now.  It's reasonably
23790b57cec5SDimitry Andric   // efficient.  Consider doing something like ARM to handle the
23800b57cec5SDimitry Andric   // case where all args fit in registers, no varargs, no float
23810b57cec5SDimitry Andric   // or vector args.
23820b57cec5SDimitry Andric   return false;
23830b57cec5SDimitry Andric }
23840b57cec5SDimitry Andric 
23850b57cec5SDimitry Andric // Handle materializing integer constants into a register.  This is not
23860b57cec5SDimitry Andric // automatically generated for PowerPC, so must be explicitly created here.
23870b57cec5SDimitry Andric unsigned PPCFastISel::fastEmit_i(MVT Ty, MVT VT, unsigned Opc, uint64_t Imm) {
23880b57cec5SDimitry Andric 
23890b57cec5SDimitry Andric   if (Opc != ISD::Constant)
23900b57cec5SDimitry Andric     return 0;
23910b57cec5SDimitry Andric 
23920b57cec5SDimitry Andric   // If we're using CR bit registers for i1 values, handle that as a special
23930b57cec5SDimitry Andric   // case first.
23945ffd83dbSDimitry Andric   if (VT == MVT::i1 && Subtarget->useCRBits()) {
239504eeddc0SDimitry Andric     Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);
2396bdd1243dSDimitry Andric     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,
23970b57cec5SDimitry Andric             TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);
23980b57cec5SDimitry Andric     return ImmReg;
23990b57cec5SDimitry Andric   }
24000b57cec5SDimitry Andric 
24010b57cec5SDimitry Andric   if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&
24020b57cec5SDimitry Andric       VT != MVT::i1)
24030b57cec5SDimitry Andric     return 0;
24040b57cec5SDimitry Andric 
24050b57cec5SDimitry Andric   const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
24060b57cec5SDimitry Andric                                    &PPC::GPRCRegClass);
24070b57cec5SDimitry Andric   if (VT == MVT::i64)
24080b57cec5SDimitry Andric     return PPCMaterialize64BitInt(Imm, RC);
24090b57cec5SDimitry Andric   else
24100b57cec5SDimitry Andric     return PPCMaterialize32BitInt(Imm, RC);
24110b57cec5SDimitry Andric }
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric // Override for ADDI and ADDI8 to set the correct register class
24140b57cec5SDimitry Andric // on RHS operand 0.  The automatic infrastructure naively assumes
24150b57cec5SDimitry Andric // GPRC for i32 and G8RC for i64; the concept of "no R0" is lost
24160b57cec5SDimitry Andric // for these cases.  At the moment, none of the other automatically
24170b57cec5SDimitry Andric // generated RI instructions require special treatment.  However, once
24180b57cec5SDimitry Andric // SelectSelect is implemented, "isel" requires similar handling.
24190b57cec5SDimitry Andric //
24200b57cec5SDimitry Andric // Also be conservative about the output register class.  Avoid
24210b57cec5SDimitry Andric // assigning R0 or X0 to the output register for GPRC and G8RC
24220b57cec5SDimitry Andric // register classes, as any such result could be used in ADDI, etc.,
24230b57cec5SDimitry Andric // where those regs have another meaning.
24240b57cec5SDimitry Andric unsigned PPCFastISel::fastEmitInst_ri(unsigned MachineInstOpcode,
24250b57cec5SDimitry Andric                                       const TargetRegisterClass *RC,
2426fe6060f1SDimitry Andric                                       unsigned Op0,
24270b57cec5SDimitry Andric                                       uint64_t Imm) {
24280b57cec5SDimitry Andric   if (MachineInstOpcode == PPC::ADDI)
24290b57cec5SDimitry Andric     MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);
24300b57cec5SDimitry Andric   else if (MachineInstOpcode == PPC::ADDI8)
24310b57cec5SDimitry Andric     MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);
24320b57cec5SDimitry Andric 
24330b57cec5SDimitry Andric   const TargetRegisterClass *UseRC =
24340b57cec5SDimitry Andric     (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
24350b57cec5SDimitry Andric      (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
24360b57cec5SDimitry Andric 
2437fe6060f1SDimitry Andric   return FastISel::fastEmitInst_ri(MachineInstOpcode, UseRC, Op0, Imm);
24380b57cec5SDimitry Andric }
24390b57cec5SDimitry Andric 
24400b57cec5SDimitry Andric // Override for instructions with one register operand to avoid use of
24410b57cec5SDimitry Andric // R0/X0.  The automatic infrastructure isn't aware of the context so
24420b57cec5SDimitry Andric // we must be conservative.
24430b57cec5SDimitry Andric unsigned PPCFastISel::fastEmitInst_r(unsigned MachineInstOpcode,
24440b57cec5SDimitry Andric                                      const TargetRegisterClass* RC,
2445fe6060f1SDimitry Andric                                      unsigned Op0) {
24460b57cec5SDimitry Andric   const TargetRegisterClass *UseRC =
24470b57cec5SDimitry Andric     (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
24480b57cec5SDimitry Andric      (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
24490b57cec5SDimitry Andric 
2450fe6060f1SDimitry Andric   return FastISel::fastEmitInst_r(MachineInstOpcode, UseRC, Op0);
24510b57cec5SDimitry Andric }
24520b57cec5SDimitry Andric 
24530b57cec5SDimitry Andric // Override for instructions with two register operands to avoid use
24540b57cec5SDimitry Andric // of R0/X0.  The automatic infrastructure isn't aware of the context
24550b57cec5SDimitry Andric // so we must be conservative.
24560b57cec5SDimitry Andric unsigned PPCFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,
24570b57cec5SDimitry Andric                                       const TargetRegisterClass* RC,
2458fe6060f1SDimitry Andric                                       unsigned Op0, unsigned Op1) {
24590b57cec5SDimitry Andric   const TargetRegisterClass *UseRC =
24600b57cec5SDimitry Andric     (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :
24610b57cec5SDimitry Andric      (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));
24620b57cec5SDimitry Andric 
2463fe6060f1SDimitry Andric   return FastISel::fastEmitInst_rr(MachineInstOpcode, UseRC, Op0, Op1);
24640b57cec5SDimitry Andric }
24650b57cec5SDimitry Andric 
24660b57cec5SDimitry Andric namespace llvm {
24670b57cec5SDimitry Andric   // Create the fast instruction selector for PowerPC64 ELF.
24680b57cec5SDimitry Andric   FastISel *PPC::createFastISel(FunctionLoweringInfo &FuncInfo,
24690b57cec5SDimitry Andric                                 const TargetLibraryInfo *LibInfo) {
2470349cc55cSDimitry Andric     // Only available on 64-bit for now.
24710b57cec5SDimitry Andric     const PPCSubtarget &Subtarget = FuncInfo.MF->getSubtarget<PPCSubtarget>();
2472349cc55cSDimitry Andric     if (Subtarget.isPPC64())
24730b57cec5SDimitry Andric       return new PPCFastISel(FuncInfo, LibInfo);
24740b57cec5SDimitry Andric     return nullptr;
24750b57cec5SDimitry Andric   }
24760b57cec5SDimitry Andric }
2477