LLVM API Documentation
00001 //===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines an instruction selector for the MIPS target. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "mips-isel" 00015 #include "Mips.h" 00016 #include "MipsISelLowering.h" 00017 #include "MipsMachineFunction.h" 00018 #include "MipsRegisterInfo.h" 00019 #include "MipsSubtarget.h" 00020 #include "MipsTargetMachine.h" 00021 #include "llvm/GlobalValue.h" 00022 #include "llvm/Instructions.h" 00023 #include "llvm/Intrinsics.h" 00024 #include "llvm/Support/CFG.h" 00025 #include "llvm/Type.h" 00026 #include "llvm/CodeGen/MachineConstantPool.h" 00027 #include "llvm/CodeGen/MachineFunction.h" 00028 #include "llvm/CodeGen/MachineFrameInfo.h" 00029 #include "llvm/CodeGen/MachineInstrBuilder.h" 00030 #include "llvm/CodeGen/MachineRegisterInfo.h" 00031 #include "llvm/CodeGen/SelectionDAGISel.h" 00032 #include "llvm/Target/TargetMachine.h" 00033 #include "llvm/Support/Compiler.h" 00034 #include "llvm/Support/Debug.h" 00035 using namespace llvm; 00036 00037 //===----------------------------------------------------------------------===// 00038 // Instruction Selector Implementation 00039 //===----------------------------------------------------------------------===// 00040 00041 //===----------------------------------------------------------------------===// 00042 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine 00043 // instructions for SelectionDAG operations. 00044 //===----------------------------------------------------------------------===// 00045 namespace { 00046 00047 class VISIBILITY_HIDDEN MipsDAGToDAGISel : public SelectionDAGISel { 00048 00049 /// TM - Keep a reference to MipsTargetMachine. 00050 MipsTargetMachine &TM; 00051 00052 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 00053 /// make the right decision when generating code for different targets. 00054 const MipsSubtarget &Subtarget; 00055 00056 public: 00057 explicit MipsDAGToDAGISel(MipsTargetMachine &tm) : 00058 SelectionDAGISel(tm), 00059 TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {} 00060 00061 virtual void InstructionSelect(); 00062 00063 // Pass Name 00064 virtual const char *getPassName() const { 00065 return "MIPS DAG->DAG Pattern Instruction Selection"; 00066 } 00067 00068 00069 private: 00070 // Include the pieces autogenerated from the target description. 00071 #include "MipsGenDAGISel.inc" 00072 00073 SDValue getGlobalBaseReg(); 00074 SDNode *Select(SDValue N); 00075 00076 // Complex Pattern. 00077 bool SelectAddr(SDValue Op, SDValue N, 00078 SDValue &Base, SDValue &Offset); 00079 00080 00081 // getI32Imm - Return a target constant with the specified 00082 // value, of type i32. 00083 inline SDValue getI32Imm(unsigned Imm) { 00084 return CurDAG->getTargetConstant(Imm, MVT::i32); 00085 } 00086 00087 00088 #ifndef NDEBUG 00089 unsigned Indent; 00090 #endif 00091 }; 00092 00093 } 00094 00095 /// InstructionSelect - This callback is invoked by 00096 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00097 void MipsDAGToDAGISel:: 00098 InstructionSelect() 00099 { 00100 DEBUG(BB->dump()); 00101 // Codegen the basic block. 00102 #ifndef NDEBUG 00103 DOUT << "===== Instruction selection begins:\n"; 00104 Indent = 0; 00105 #endif 00106 00107 // Select target instructions for the DAG. 00108 SelectRoot(*CurDAG); 00109 00110 #ifndef NDEBUG 00111 DOUT << "===== Instruction selection ends:\n"; 00112 #endif 00113 00114 CurDAG->RemoveDeadNodes(); 00115 } 00116 00117 /// getGlobalBaseReg - Output the instructions required to put the 00118 /// GOT address into a register. 00119 SDValue MipsDAGToDAGISel::getGlobalBaseReg() { 00120 MachineFunction* MF = BB->getParent(); 00121 unsigned GP = 0; 00122 for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(), 00123 ee = MF->getRegInfo().livein_end(); ii != ee; ++ii) 00124 if (ii->first == Mips::GP) { 00125 GP = ii->second; 00126 break; 00127 } 00128 assert(GP && "GOT PTR not in liveins"); 00129 return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 00130 GP, MVT::i32); 00131 } 00132 00133 /// ComplexPattern used on MipsInstrInfo 00134 /// Used on Mips Load/Store instructions 00135 bool MipsDAGToDAGISel:: 00136 SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base) 00137 { 00138 // if Address is FI, get the TargetFrameIndex. 00139 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 00140 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 00141 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00142 return true; 00143 } 00144 00145 // on PIC code Load GA 00146 if (TM.getRelocationModel() == Reloc::PIC_) { 00147 if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || 00148 (Addr.getOpcode() == ISD::TargetJumpTable)){ 00149 Base = CurDAG->getRegister(Mips::GP, MVT::i32); 00150 Offset = Addr; 00151 return true; 00152 } 00153 } else { 00154 if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 00155 Addr.getOpcode() == ISD::TargetGlobalAddress)) 00156 return false; 00157 } 00158 00159 // Operand is a result from an ADD. 00160 if (Addr.getOpcode() == ISD::ADD) { 00161 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 00162 if (Predicate_immSExt16(CN)) { 00163 00164 // If the first operand is a FI, get the TargetFI Node 00165 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 00166 (Addr.getOperand(0))) { 00167 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 00168 } else { 00169 Base = Addr.getOperand(0); 00170 } 00171 00172 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 00173 return true; 00174 } 00175 } 00176 } 00177 00178 Base = Addr; 00179 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00180 return true; 00181 } 00182 00183 /// Select instructions not customized! Used for 00184 /// expanded, promoted and normal instructions 00185 SDNode* MipsDAGToDAGISel:: 00186 Select(SDValue N) 00187 { 00188 SDNode *Node = N.getNode(); 00189 unsigned Opcode = Node->getOpcode(); 00190 00191 // Dump information about the Node being selected 00192 #ifndef NDEBUG 00193 DOUT << std::string(Indent, ' ') << "Selecting: "; 00194 DEBUG(Node->dump(CurDAG)); 00195 DOUT << "\n"; 00196 Indent += 2; 00197 #endif 00198 00199 // If we have a custom node, we already have selected! 00200 if (Node->isMachineOpcode()) { 00201 #ifndef NDEBUG 00202 DOUT << std::string(Indent-2, ' ') << "== "; 00203 DEBUG(Node->dump(CurDAG)); 00204 DOUT << "\n"; 00205 Indent -= 2; 00206 #endif 00207 return NULL; 00208 } 00209 00210 /// 00211 // Instruction Selection not handled by the auto-generated 00212 // tablegen selection should be handled here. 00213 /// 00214 switch(Opcode) { 00215 00216 default: break; 00217 00218 case ISD::SUBE: 00219 case ISD::ADDE: { 00220 SDValue InFlag = Node->getOperand(2), CmpLHS; 00221 unsigned Opc = InFlag.getOpcode(); Opc=Opc; 00222 assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 00223 (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 00224 "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 00225 00226 unsigned MOp; 00227 if (Opcode == ISD::ADDE) { 00228 CmpLHS = InFlag.getValue(0); 00229 MOp = Mips::ADDu; 00230 } else { 00231 CmpLHS = InFlag.getOperand(0); 00232 MOp = Mips::SUBu; 00233 } 00234 00235 SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 00236 00237 SDValue LHS = Node->getOperand(0); 00238 SDValue RHS = Node->getOperand(1); 00239 00240 MVT VT = LHS.getValueType(); 00241 SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, VT, Ops, 2); 00242 SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, VT, 00243 SDValue(Carry,0), RHS); 00244 00245 return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag, 00246 LHS, SDValue(AddCarry,0)); 00247 } 00248 00249 /// Mul/Div with two results 00250 case ISD::SDIVREM: 00251 case ISD::UDIVREM: 00252 case ISD::SMUL_LOHI: 00253 case ISD::UMUL_LOHI: { 00254 SDValue Op1 = Node->getOperand(0); 00255 SDValue Op2 = Node->getOperand(1); 00256 00257 unsigned Op; 00258 if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI) 00259 Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); 00260 else 00261 Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV); 00262 00263 SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2); 00264 00265 SDValue InFlag = SDValue(Node, 0); 00266 SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, MVT::i32, 00267 MVT::Flag, InFlag); 00268 InFlag = SDValue(Lo,1); 00269 SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag); 00270 00271 if (!N.getValue(0).use_empty()) 00272 ReplaceUses(N.getValue(0), SDValue(Lo,0)); 00273 00274 if (!N.getValue(1).use_empty()) 00275 ReplaceUses(N.getValue(1), SDValue(Hi,0)); 00276 00277 return NULL; 00278 } 00279 00280 /// Special Muls 00281 case ISD::MUL: 00282 case ISD::MULHS: 00283 case ISD::MULHU: { 00284 SDValue MulOp1 = Node->getOperand(0); 00285 SDValue MulOp2 = Node->getOperand(1); 00286 00287 unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); 00288 SDNode *MulNode = CurDAG->getTargetNode(MulOp, MVT::Flag, MulOp1, MulOp2); 00289 00290 SDValue InFlag = SDValue(MulNode, 0); 00291 00292 if (MulOp == ISD::MUL) 00293 return CurDAG->getTargetNode(Mips::MFLO, MVT::i32, InFlag); 00294 else 00295 return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag); 00296 } 00297 00298 /// Div/Rem operations 00299 case ISD::SREM: 00300 case ISD::UREM: 00301 case ISD::SDIV: 00302 case ISD::UDIV: { 00303 SDValue Op1 = Node->getOperand(0); 00304 SDValue Op2 = Node->getOperand(1); 00305 00306 unsigned Op, MOp; 00307 if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) { 00308 Op = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu); 00309 MOp = Mips::MFLO; 00310 } else { 00311 Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu); 00312 MOp = Mips::MFHI; 00313 } 00314 SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2); 00315 00316 SDValue InFlag = SDValue(Node, 0); 00317 return CurDAG->getTargetNode(MOp, MVT::i32, InFlag); 00318 } 00319 00320 // Get target GOT address. 00321 case ISD::GLOBAL_OFFSET_TABLE: { 00322 SDValue Result = getGlobalBaseReg(); 00323 ReplaceUses(N, Result); 00324 return NULL; 00325 } 00326 00327 /// Handle direct and indirect calls when using PIC. On PIC, when 00328 /// GOT is smaller than about 64k (small code) the GA target is 00329 /// loaded with only one instruction. Otherwise GA's target must 00330 /// be loaded with 3 instructions. 00331 case MipsISD::JmpLink: { 00332 if (TM.getRelocationModel() == Reloc::PIC_) { 00333 //bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large); 00334 SDValue Chain = Node->getOperand(0); 00335 SDValue Callee = Node->getOperand(1); 00336 SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32); 00337 SDValue InFlag(0, 0); 00338 00339 if ( (isa<GlobalAddressSDNode>(Callee)) || 00340 (isa<ExternalSymbolSDNode>(Callee)) ) 00341 { 00342 /// Direct call for global addresses and external symbols 00343 SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); 00344 00345 // Use load to get GOT target 00346 SDValue Ops[] = { Callee, GPReg, Chain }; 00347 SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, MVT::i32, 00348 MVT::Other, Ops, 3), 0); 00349 Chain = Load.getValue(1); 00350 00351 // Call target must be on T9 00352 Chain = CurDAG->getCopyToReg(Chain, T9Reg, Load, InFlag); 00353 } else 00354 /// Indirect call 00355 Chain = CurDAG->getCopyToReg(Chain, T9Reg, Callee, InFlag); 00356 00357 // Emit Jump and Link Register 00358 SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, MVT::Other, 00359 MVT::Flag, T9Reg, Chain); 00360 Chain = SDValue(ResNode, 0); 00361 InFlag = SDValue(ResNode, 1); 00362 ReplaceUses(SDValue(Node, 0), Chain); 00363 ReplaceUses(SDValue(Node, 1), InFlag); 00364 return ResNode; 00365 } 00366 } 00367 } 00368 00369 // Select the default instruction 00370 SDNode *ResNode = SelectCode(N); 00371 00372 #ifndef NDEBUG 00373 DOUT << std::string(Indent-2, ' ') << "=> "; 00374 if (ResNode == NULL || ResNode == N.getNode()) 00375 DEBUG(N.getNode()->dump(CurDAG)); 00376 else 00377 DEBUG(ResNode->dump(CurDAG)); 00378 DOUT << "\n"; 00379 Indent -= 2; 00380 #endif 00381 00382 return ResNode; 00383 } 00384 00385 /// createMipsISelDag - This pass converts a legalized DAG into a 00386 /// MIPS-specific DAG, ready for instruction scheduling. 00387 FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { 00388 return new MipsDAGToDAGISel(TM); 00389 }