MipsSEISelLowering.cpp revision f5926fd844a84adcf1ae4f193146f2877997b82c
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 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::SMUL_LOHI, MVT::i32, Custom); 64 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 65 setOperationAction(ISD::MULHS, MVT::i32, Custom); 66 setOperationAction(ISD::MULHU, MVT::i32, Custom); 67 68 if (HasMips64) 69 setOperationAction(ISD::MUL, MVT::i64, Custom); 70 71 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 72 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 73 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 74 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 75 setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); 76 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 77 setOperationAction(ISD::LOAD, MVT::i32, Custom); 78 setOperationAction(ISD::STORE, MVT::i32, Custom); 79 80 computeRegisterProperties(); 81} 82 83const MipsTargetLowering * 84llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 85 return new MipsSETargetLowering(TM); 86} 87 88 89bool 90MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const { 91 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 92 93 switch (SVT) { 94 case MVT::i64: 95 case MVT::i32: 96 if (Fast) 97 *Fast = true; 98 return true; 99 default: 100 return false; 101 } 102} 103 104SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 105 SelectionDAG &DAG) const { 106 switch(Op.getOpcode()) { 107 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 108 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 109 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 110 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 111 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 112 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 113 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, DAG); 114 } 115 116 return MipsTargetLowering::LowerOperation(Op, DAG); 117} 118 119MachineBasicBlock * 120MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 121 MachineBasicBlock *BB) const { 122 switch (MI->getOpcode()) { 123 default: 124 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 125 case Mips::BPOSGE32_PSEUDO: 126 return emitBPOSGE32(MI, BB); 127 } 128} 129 130bool MipsSETargetLowering:: 131isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 132 unsigned NextStackOffset, 133 const MipsFunctionInfo& FI) const { 134 if (!EnableMipsTailCalls) 135 return false; 136 137 // Return false if either the callee or caller has a byval argument. 138 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 139 return false; 140 141 // Return true if the callee's argument area is no larger than the 142 // caller's. 143 return NextStackOffset <= FI.getIncomingArgSize(); 144} 145 146void MipsSETargetLowering:: 147getOpndList(SmallVectorImpl<SDValue> &Ops, 148 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 149 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 150 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 151 // T9 should contain the address of the callee function if 152 // -reloction-model=pic or it is an indirect call. 153 if (IsPICCall || !GlobalOrExternal) { 154 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 155 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 156 } else 157 Ops.push_back(Callee); 158 159 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 160 InternalLinkage, CLI, Callee, Chain); 161} 162 163SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 164 bool HasLo, bool HasHi, 165 SelectionDAG &DAG) const { 166 EVT Ty = Op.getOperand(0).getValueType(); 167 DebugLoc DL = Op.getDebugLoc(); 168 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 169 Op.getOperand(0), Op.getOperand(1)); 170 SDValue Lo, Hi; 171 172 if (HasLo) 173 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 174 DAG.getConstant(Mips::sub_lo, MVT::i32)); 175 if (HasHi) 176 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 177 DAG.getConstant(Mips::sub_hi, MVT::i32)); 178 179 if (!HasLo || !HasHi) 180 return HasLo ? Lo : Hi; 181 182 SDValue Vals[] = { Lo, Hi }; 183 return DAG.getMergeValues(Vals, 2, DL); 184} 185 186MachineBasicBlock * MipsSETargetLowering:: 187emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 188 // $bb: 189 // bposge32_pseudo $vr0 190 // => 191 // $bb: 192 // bposge32 $tbb 193 // $fbb: 194 // li $vr2, 0 195 // b $sink 196 // $tbb: 197 // li $vr1, 1 198 // $sink: 199 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 200 201 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 202 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 203 const TargetRegisterClass *RC = &Mips::CPURegsRegClass; 204 DebugLoc DL = MI->getDebugLoc(); 205 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 206 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 207 MachineFunction *F = BB->getParent(); 208 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 209 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 210 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 211 F->insert(It, FBB); 212 F->insert(It, TBB); 213 F->insert(It, Sink); 214 215 // Transfer the remainder of BB and its successor edges to Sink. 216 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 217 BB->end()); 218 Sink->transferSuccessorsAndUpdatePHIs(BB); 219 220 // Add successors. 221 BB->addSuccessor(FBB); 222 BB->addSuccessor(TBB); 223 FBB->addSuccessor(Sink); 224 TBB->addSuccessor(Sink); 225 226 // Insert the real bposge32 instruction to $BB. 227 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 228 229 // Fill $FBB. 230 unsigned VR2 = RegInfo.createVirtualRegister(RC); 231 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 232 .addReg(Mips::ZERO).addImm(0); 233 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 234 235 // Fill $TBB. 236 unsigned VR1 = RegInfo.createVirtualRegister(RC); 237 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 238 .addReg(Mips::ZERO).addImm(1); 239 240 // Insert phi function to $Sink. 241 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 242 MI->getOperand(0).getReg()) 243 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 244 245 MI->eraseFromParent(); // The pseudo instruction is gone now. 246 return Sink; 247} 248