Home | History | Annotate | Download | only in PowerPC
      1 //===-- PPCFastISel.cpp - PowerPC FastISel implementation -----------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the PowerPC-specific support for the FastISel class. Some
     11 // of the target-specific code is generated by tablegen in the file
     12 // PPCGenFastISel.inc, which is #included here.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #define DEBUG_TYPE "ppcfastisel"
     17 #include "PPC.h"
     18 #include "PPCISelLowering.h"
     19 #include "PPCSubtarget.h"
     20 #include "PPCTargetMachine.h"
     21 #include "MCTargetDesc/PPCPredicates.h"
     22 #include "llvm/ADT/Optional.h"
     23 #include "llvm/CodeGen/CallingConvLower.h"
     24 #include "llvm/CodeGen/FastISel.h"
     25 #include "llvm/CodeGen/FunctionLoweringInfo.h"
     26 #include "llvm/CodeGen/MachineConstantPool.h"
     27 #include "llvm/CodeGen/MachineFrameInfo.h"
     28 #include "llvm/CodeGen/MachineInstrBuilder.h"
     29 #include "llvm/CodeGen/MachineRegisterInfo.h"
     30 #include "llvm/IR/CallingConv.h"
     31 #include "llvm/IR/GlobalAlias.h"
     32 #include "llvm/IR/GlobalVariable.h"
     33 #include "llvm/IR/IntrinsicInst.h"
     34 #include "llvm/IR/Operator.h"
     35 #include "llvm/Support/Debug.h"
     36 #include "llvm/Support/GetElementPtrTypeIterator.h"
     37 #include "llvm/Target/TargetLowering.h"
     38 #include "llvm/Target/TargetMachine.h"
     39 
     40 using namespace llvm;
     41 
     42 namespace {
     43 
     44 typedef struct Address {
     45   enum {
     46     RegBase,
     47     FrameIndexBase
     48   } BaseType;
     49 
     50   union {
     51     unsigned Reg;
     52     int FI;
     53   } Base;
     54 
     55   int Offset;
     56 
     57   // Innocuous defaults for our address.
     58   Address()
     59    : BaseType(RegBase), Offset(0) {
     60      Base.Reg = 0;
     61    }
     62 } Address;
     63 
     64 class PPCFastISel : public FastISel {
     65 
     66   const TargetMachine &TM;
     67   const TargetInstrInfo &TII;
     68   const TargetLowering &TLI;
     69   const PPCSubtarget &PPCSubTarget;
     70   LLVMContext *Context;
     71 
     72   public:
     73     explicit PPCFastISel(FunctionLoweringInfo &FuncInfo,
     74                          const TargetLibraryInfo *LibInfo)
     75     : FastISel(FuncInfo, LibInfo),
     76       TM(FuncInfo.MF->getTarget()),
     77       TII(*TM.getInstrInfo()),
     78       TLI(*TM.getTargetLowering()),
     79       PPCSubTarget(
     80        *((static_cast<const PPCTargetMachine *>(&TM))->getSubtargetImpl())
     81       ),
     82       Context(&FuncInfo.Fn->getContext()) { }
     83 
     84   // Backend specific FastISel code.
     85   private:
     86     virtual bool TargetSelectInstruction(const Instruction *I);
     87     virtual unsigned TargetMaterializeConstant(const Constant *C);
     88     virtual unsigned TargetMaterializeAlloca(const AllocaInst *AI);
     89     virtual bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
     90                                      const LoadInst *LI);
     91     virtual bool FastLowerArguments();
     92 
     93   // Utility routines.
     94   private:
     95     unsigned PPCMaterializeFP(const ConstantFP *CFP, MVT VT);
     96     unsigned PPCMaterializeInt(const Constant *C, MVT VT);
     97     unsigned PPCMaterialize32BitInt(int64_t Imm,
     98                                     const TargetRegisterClass *RC);
     99     unsigned PPCMaterialize64BitInt(int64_t Imm,
    100                                     const TargetRegisterClass *RC);
    101 
    102   private:
    103   #include "PPCGenFastISel.inc"
    104 
    105 };
    106 
    107 } // end anonymous namespace
    108 
    109 // Attempt to fast-select an instruction that wasn't handled by
    110 // the table-generated machinery.  TBD.
    111 bool PPCFastISel::TargetSelectInstruction(const Instruction *I) {
    112   return I && false;
    113 }
    114 
    115 // Materialize a floating-point constant into a register, and return
    116 // the register number (or zero if we failed to handle it).
    117 unsigned PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {
    118   // No plans to handle long double here.
    119   if (VT != MVT::f32 && VT != MVT::f64)
    120     return 0;
    121 
    122   // All FP constants are loaded from the constant pool.
    123   unsigned Align = TD.getPrefTypeAlignment(CFP->getType());
    124   assert(Align > 0 && "Unexpectedly missing alignment information!");
    125   unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
    126   unsigned DestReg = createResultReg(TLI.getRegClassFor(VT));
    127   CodeModel::Model CModel = TM.getCodeModel();
    128 
    129   MachineMemOperand *MMO =
    130     FuncInfo.MF->getMachineMemOperand(
    131       MachinePointerInfo::getConstantPool(), MachineMemOperand::MOLoad,
    132       (VT == MVT::f32) ? 4 : 8, Align);
    133 
    134   // For small code model, generate a LDtocCPT.
    135   if (CModel == CodeModel::Small || CModel == CodeModel::JITDefault)
    136     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(PPC::LDtocCPT),
    137             DestReg)
    138       .addConstantPoolIndex(Idx).addReg(PPC::X2).addMemOperand(MMO);
    139   else {
    140     // Otherwise we generate LF[SD](Idx[lo], ADDIStocHA(X2, Idx)).
    141     unsigned Opc = (VT == MVT::f32) ? PPC::LFS : PPC::LFD;
    142     unsigned TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);
    143     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(PPC::ADDIStocHA),
    144             TmpReg).addReg(PPC::X2).addConstantPoolIndex(Idx);
    145     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg)
    146       .addConstantPoolIndex(Idx, 0, PPCII::MO_TOC_LO)
    147       .addReg(TmpReg)
    148       .addMemOperand(MMO);
    149   }
    150 
    151   return DestReg;
    152 }
    153 
    154 // Materialize a 32-bit integer constant into a register, and return
    155 // the register number (or zero if we failed to handle it).
    156 unsigned PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,
    157                                              const TargetRegisterClass *RC) {
    158   unsigned Lo = Imm & 0xFFFF;
    159   unsigned Hi = (Imm >> 16) & 0xFFFF;
    160 
    161   unsigned ResultReg = createResultReg(RC);
    162   bool IsGPRC = RC->hasSuperClassEq(&PPC::GPRCRegClass);
    163 
    164   if (isInt<16>(Imm))
    165     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
    166             TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)
    167       .addImm(Imm);
    168   else if (Lo) {
    169     // Both Lo and Hi have nonzero bits.
    170     unsigned TmpReg = createResultReg(RC);
    171     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
    172             TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)
    173       .addImm(Hi);
    174     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
    175             TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)
    176       .addReg(TmpReg).addImm(Lo);
    177   } else
    178     // Just Hi bits.
    179     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
    180             TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)
    181       .addImm(Hi);
    182 
    183   return ResultReg;
    184 }
    185 
    186 // Materialize a 64-bit integer constant into a register, and return
    187 // the register number (or zero if we failed to handle it).
    188 unsigned PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,
    189                                              const TargetRegisterClass *RC) {
    190   unsigned Remainder = 0;
    191   unsigned Shift = 0;
    192 
    193   // If the value doesn't fit in 32 bits, see if we can shift it
    194   // so that it fits in 32 bits.
    195   if (!isInt<32>(Imm)) {
    196     Shift = countTrailingZeros<uint64_t>(Imm);
    197     int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;
    198 
    199     if (isInt<32>(ImmSh))
    200       Imm = ImmSh;
    201     else {
    202       Remainder = Imm;
    203       Shift = 32;
    204       Imm >>= 32;
    205     }
    206   }
    207 
    208   // Handle the high-order 32 bits (if shifted) or the whole 32 bits
    209   // (if not shifted).
    210   unsigned TmpReg1 = PPCMaterialize32BitInt(Imm, RC);
    211   if (!Shift)
    212     return TmpReg1;
    213 
    214   // If upper 32 bits were not zero, we've built them and need to shift
    215   // them into place.
    216   unsigned TmpReg2;
    217   if (Imm) {
    218     TmpReg2 = createResultReg(RC);
    219     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(PPC::RLDICR),
    220             TmpReg2).addReg(TmpReg1).addImm(Shift).addImm(63 - Shift);
    221   } else
    222     TmpReg2 = TmpReg1;
    223 
    224   unsigned TmpReg3, Hi, Lo;
    225   if ((Hi = (Remainder >> 16) & 0xFFFF)) {
    226     TmpReg3 = createResultReg(RC);
    227     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(PPC::ORIS8),
    228             TmpReg3).addReg(TmpReg2).addImm(Hi);
    229   } else
    230     TmpReg3 = TmpReg2;
    231 
    232   if ((Lo = Remainder & 0xFFFF)) {
    233     unsigned ResultReg = createResultReg(RC);
    234     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(PPC::ORI8),
    235             ResultReg).addReg(TmpReg3).addImm(Lo);
    236     return ResultReg;
    237   }
    238 
    239   return TmpReg3;
    240 }
    241 
    242 
    243 // Materialize an integer constant into a register, and return
    244 // the register number (or zero if we failed to handle it).
    245 unsigned PPCFastISel::PPCMaterializeInt(const Constant *C, MVT VT) {
    246 
    247   if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 &&
    248       VT != MVT::i8 && VT != MVT::i1)
    249     return 0;
    250 
    251   const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :
    252                                    &PPC::GPRCRegClass);
    253 
    254   // If the constant is in range, use a load-immediate.
    255   const ConstantInt *CI = cast<ConstantInt>(C);
    256   if (isInt<16>(CI->getSExtValue())) {
    257     unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;
    258     unsigned ImmReg = createResultReg(RC);
    259     BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ImmReg)
    260       .addImm(CI->getSExtValue());
    261     return ImmReg;
    262   }
    263 
    264   // Construct the constant piecewise.
    265   int64_t Imm = CI->getZExtValue();
    266 
    267   if (VT == MVT::i64)
    268     return PPCMaterialize64BitInt(Imm, RC);
    269   else if (VT == MVT::i32)
    270     return PPCMaterialize32BitInt(Imm, RC);
    271 
    272   return 0;
    273 }
    274 
    275 // Materialize a constant into a register, and return the register
    276 // number (or zero if we failed to handle it).
    277 unsigned PPCFastISel::TargetMaterializeConstant(const Constant *C) {
    278   EVT CEVT = TLI.getValueType(C->getType(), true);
    279 
    280   // Only handle simple types.
    281   if (!CEVT.isSimple()) return 0;
    282   MVT VT = CEVT.getSimpleVT();
    283 
    284   if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
    285     return PPCMaterializeFP(CFP, VT);
    286   else if (isa<ConstantInt>(C))
    287     return PPCMaterializeInt(C, VT);
    288   // TBD: Global values.
    289 
    290   return 0;
    291 }
    292 
    293 // Materialize the address created by an alloca into a register, and
    294 // return the register number (or zero if we failed to handle it).  TBD.
    295 unsigned PPCFastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
    296   return AI && 0;
    297 }
    298 
    299 // Fold loads into extends when possible.  TBD.
    300 bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,
    301                                       const LoadInst *LI) {
    302   return MI && OpNo && LI && false;
    303 }
    304 
    305 // Attempt to lower call arguments in a faster way than done by
    306 // the selection DAG code.
    307 bool PPCFastISel::FastLowerArguments() {
    308   // Defer to normal argument lowering for now.  It's reasonably
    309   // efficient.  Consider doing something like ARM to handle the
    310   // case where all args fit in registers, no varargs, no float
    311   // or vector args.
    312   return false;
    313 }
    314 
    315 namespace llvm {
    316   // Create the fast instruction selector for PowerPC64 ELF.
    317   FastISel *PPC::createFastISel(FunctionLoweringInfo &FuncInfo,
    318                                 const TargetLibraryInfo *LibInfo) {
    319     const TargetMachine &TM = FuncInfo.MF->getTarget();
    320 
    321     // Only available on 64-bit ELF for now.
    322     const PPCSubtarget *Subtarget = &TM.getSubtarget<PPCSubtarget>();
    323     if (Subtarget->isPPC64() && Subtarget->isSVR4ABI())
    324       return new PPCFastISel(FuncInfo, LibInfo);
    325 
    326     return 0;
    327   }
    328 }
    329