Home | History | Annotate | Download | only in Mips
      1 //===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
      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 // Subclass of MipsTargetLowering specialized for mips32/64.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include "MipsSEISelLowering.h"
     14 #include "MipsRegisterInfo.h"
     15 #include "MipsTargetMachine.h"
     16 #include "llvm/CodeGen/MachineInstrBuilder.h"
     17 #include "llvm/CodeGen/MachineRegisterInfo.h"
     18 #include "llvm/Support/CommandLine.h"
     19 #include "llvm/Target/TargetInstrInfo.h"
     20 
     21 using namespace llvm;
     22 
     23 static cl::opt<bool>
     24 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
     25                     cl::desc("MIPS: Enable tail calls."), cl::init(false));
     26 
     27 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
     28   : MipsTargetLowering(TM) {
     29   // Set up the register classes
     30   addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
     31 
     32   if (HasMips64)
     33     addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
     34 
     35   if (Subtarget->hasDSP()) {
     36     MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
     37 
     38     for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
     39       addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
     40 
     41       // Expand all builtin opcodes.
     42       for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
     43         setOperationAction(Opc, VecTys[i], Expand);
     44 
     45       setOperationAction(ISD::LOAD, VecTys[i], Legal);
     46       setOperationAction(ISD::STORE, VecTys[i], Legal);
     47       setOperationAction(ISD::BITCAST, VecTys[i], Legal);
     48     }
     49   }
     50 
     51   if (!TM.Options.UseSoftFloat) {
     52     addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
     53 
     54     // When dealing with single precision only, use libcalls
     55     if (!Subtarget->isSingleFloat()) {
     56       if (HasMips64)
     57         addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
     58       else
     59         addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
     60     }
     61   }
     62 
     63   setOperationAction(ISD::MEMBARRIER,         MVT::Other, Custom);
     64   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
     65   setOperationAction(ISD::LOAD,               MVT::i32, Custom);
     66   setOperationAction(ISD::STORE,              MVT::i32, Custom);
     67 
     68   computeRegisterProperties();
     69 }
     70 
     71 const MipsTargetLowering *
     72 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
     73   return new MipsSETargetLowering(TM);
     74 }
     75 
     76 
     77 bool
     78 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
     79   MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
     80 
     81   switch (SVT) {
     82   case MVT::i64:
     83   case MVT::i32:
     84     if (Fast)
     85       *Fast = true;
     86     return true;
     87   default:
     88     return false;
     89   }
     90 }
     91 
     92 MachineBasicBlock *
     93 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
     94                                                   MachineBasicBlock *BB) const {
     95   switch (MI->getOpcode()) {
     96   default:
     97     return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
     98   case Mips::BPOSGE32_PSEUDO:
     99     return emitBPOSGE32(MI, BB);
    100   }
    101 }
    102 
    103 bool MipsSETargetLowering::
    104 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
    105                                   unsigned NextStackOffset,
    106                                   const MipsFunctionInfo& FI) const {
    107   if (!EnableMipsTailCalls)
    108     return false;
    109 
    110   // Return false if either the callee or caller has a byval argument.
    111   if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
    112     return false;
    113 
    114   // Return true if the callee's argument area is no larger than the
    115   // caller's.
    116   return NextStackOffset <= FI.getIncomingArgSize();
    117 }
    118 
    119 void MipsSETargetLowering::
    120 getOpndList(SmallVectorImpl<SDValue> &Ops,
    121             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
    122             bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
    123             CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
    124   // T9 should contain the address of the callee function if
    125   // -reloction-model=pic or it is an indirect call.
    126   if (IsPICCall || !GlobalOrExternal) {
    127     unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
    128     RegsToPass.push_front(std::make_pair(T9Reg, Callee));
    129   } else
    130     Ops.push_back(Callee);
    131 
    132   MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
    133                                   InternalLinkage, CLI, Callee, Chain);
    134 }
    135 
    136 MachineBasicBlock * MipsSETargetLowering::
    137 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
    138   // $bb:
    139   //  bposge32_pseudo $vr0
    140   //  =>
    141   // $bb:
    142   //  bposge32 $tbb
    143   // $fbb:
    144   //  li $vr2, 0
    145   //  b $sink
    146   // $tbb:
    147   //  li $vr1, 1
    148   // $sink:
    149   //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
    150 
    151   MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
    152   const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
    153   const TargetRegisterClass *RC = &Mips::CPURegsRegClass;
    154   DebugLoc DL = MI->getDebugLoc();
    155   const BasicBlock *LLVM_BB = BB->getBasicBlock();
    156   MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
    157   MachineFunction *F = BB->getParent();
    158   MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
    159   MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
    160   MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
    161   F->insert(It, FBB);
    162   F->insert(It, TBB);
    163   F->insert(It, Sink);
    164 
    165   // Transfer the remainder of BB and its successor edges to Sink.
    166   Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
    167                BB->end());
    168   Sink->transferSuccessorsAndUpdatePHIs(BB);
    169 
    170   // Add successors.
    171   BB->addSuccessor(FBB);
    172   BB->addSuccessor(TBB);
    173   FBB->addSuccessor(Sink);
    174   TBB->addSuccessor(Sink);
    175 
    176   // Insert the real bposge32 instruction to $BB.
    177   BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
    178 
    179   // Fill $FBB.
    180   unsigned VR2 = RegInfo.createVirtualRegister(RC);
    181   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
    182     .addReg(Mips::ZERO).addImm(0);
    183   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
    184 
    185   // Fill $TBB.
    186   unsigned VR1 = RegInfo.createVirtualRegister(RC);
    187   BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
    188     .addReg(Mips::ZERO).addImm(1);
    189 
    190   // Insert phi function to $Sink.
    191   BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
    192           MI->getOperand(0).getReg())
    193     .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
    194 
    195   MI->eraseFromParent();   // The pseudo instruction is gone now.
    196   return Sink;
    197 }
    198