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