MipsSEISelLowering.cpp revision 5ac065a79767cc112eba63136183b7103765d0d3
1//===-- MipsSEISelLowering.h - 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 21using namespace llvm; 22 23static cl::opt<bool> 24EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden, 25 cl::desc("MIPS: Enable tail calls."), cl::init(false)); 26 27MipsSETargetLowering::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 71const MipsTargetLowering * 72llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 73 return new MipsSETargetLowering(TM); 74} 75 76 77bool 78MipsSETargetLowering::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 92MachineBasicBlock * 93MipsSETargetLowering::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 103bool MipsSETargetLowering:: 104isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 105 unsigned NextStackOffset, 106 const MipsFunctionInfo& FI) const { 107 if (!EnableMipsTailCalls) 108 return false; 109 110 // No tail call optimization for mips16. 111 if (Subtarget->inMips16Mode()) 112 return false; 113 114 // Return false if either the callee or caller has a byval argument. 115 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 116 return false; 117 118 // Return true if the callee's argument area is no larger than the 119 // caller's. 120 return NextStackOffset <= FI.getIncomingArgSize(); 121} 122 123void MipsSETargetLowering:: 124getOpndList(SmallVectorImpl<SDValue> &Ops, 125 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 126 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 127 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 128 // T9 should contain the address of the callee function if 129 // -reloction-model=pic or it is an indirect call. 130 if (IsPICCall || !GlobalOrExternal) { 131 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 132 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 133 } else 134 Ops.push_back(Callee); 135 136 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 137 InternalLinkage, CLI, Callee, Chain); 138} 139 140MachineBasicBlock * MipsSETargetLowering:: 141emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 142 // $bb: 143 // bposge32_pseudo $vr0 144 // => 145 // $bb: 146 // bposge32 $tbb 147 // $fbb: 148 // li $vr2, 0 149 // b $sink 150 // $tbb: 151 // li $vr1, 1 152 // $sink: 153 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 154 155 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 156 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 157 const TargetRegisterClass *RC = &Mips::CPURegsRegClass; 158 DebugLoc DL = MI->getDebugLoc(); 159 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 160 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 161 MachineFunction *F = BB->getParent(); 162 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 163 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 164 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 165 F->insert(It, FBB); 166 F->insert(It, TBB); 167 F->insert(It, Sink); 168 169 // Transfer the remainder of BB and its successor edges to Sink. 170 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 171 BB->end()); 172 Sink->transferSuccessorsAndUpdatePHIs(BB); 173 174 // Add successors. 175 BB->addSuccessor(FBB); 176 BB->addSuccessor(TBB); 177 FBB->addSuccessor(Sink); 178 TBB->addSuccessor(Sink); 179 180 // Insert the real bposge32 instruction to $BB. 181 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 182 183 // Fill $FBB. 184 unsigned VR2 = RegInfo.createVirtualRegister(RC); 185 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 186 .addReg(Mips::ZERO).addImm(0); 187 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 188 189 // Fill $TBB. 190 unsigned VR1 = RegInfo.createVirtualRegister(RC); 191 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 192 .addReg(Mips::ZERO).addImm(1); 193 194 // Insert phi function to $Sink. 195 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 196 MI->getOperand(0).getReg()) 197 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 198 199 MI->eraseFromParent(); // The pseudo instruction is gone now. 200 return Sink; 201} 202