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