1 //===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===// 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 // This file defines an instruction selector for the MIPS target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "mips-isel" 15 #include "Mips.h" 16 #include "MipsISelLowering.h" 17 #include "MipsMachineFunction.h" 18 #include "MipsRegisterInfo.h" 19 #include "MipsSubtarget.h" 20 #include "MipsTargetMachine.h" 21 #include "llvm/GlobalValue.h" 22 #include "llvm/Instructions.h" 23 #include "llvm/Intrinsics.h" 24 #include "llvm/Support/CFG.h" 25 #include "llvm/Type.h" 26 #include "llvm/CodeGen/MachineConstantPool.h" 27 #include "llvm/CodeGen/MachineFunction.h" 28 #include "llvm/CodeGen/MachineFrameInfo.h" 29 #include "llvm/CodeGen/MachineInstrBuilder.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.h" 31 #include "llvm/CodeGen/SelectionDAGISel.h" 32 #include "llvm/Target/TargetMachine.h" 33 #include "llvm/Support/Compiler.h" 34 #include "llvm/Support/Debug.h" 35 using namespace llvm; 36 37 //===----------------------------------------------------------------------===// 38 // Instruction Selector Implementation 39 //===----------------------------------------------------------------------===// 40 41 //===----------------------------------------------------------------------===// 42 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine 43 // instructions for SelectionDAG operations. 44 //===----------------------------------------------------------------------===// 45 namespace { 46 47 class VISIBILITY_HIDDEN MipsDAGToDAGISel : public SelectionDAGISel { 48 49 /// TM - Keep a reference to MipsTargetMachine. 50 MipsTargetMachine &TM; 51 52 /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 53 /// make the right decision when generating code for different targets. 54 const MipsSubtarget &Subtarget; 55 56 public: 57 explicit MipsDAGToDAGISel(MipsTargetMachine &tm) : 58 SelectionDAGISel(tm), 59 TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {} 60 61 virtual void InstructionSelect(); 62 63 // Pass Name 64 virtual const char *getPassName() const { 65 return "MIPS DAG->DAG Pattern Instruction Selection"; 66 } 67 68 69 private: 70 // Include the pieces autogenerated from the target description. 71 #include "MipsGenDAGISel.inc" 72 73 /// getTargetMachine - Return a reference to the TargetMachine, casted 74 /// to the target-specific type. 75 const MipsTargetMachine &getTargetMachine() { 76 return static_cast<const MipsTargetMachine &>(TM); 77 } 78 79 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted 80 /// to the target-specific type. 81 const MipsInstrInfo *getInstrInfo() { 82 return getTargetMachine().getInstrInfo(); 83 } 84 85 SDNode *getGlobalBaseReg(); 86 SDNode *Select(SDValue N); 87 88 // Complex Pattern. 89 bool SelectAddr(SDValue Op, SDValue N, 90 SDValue &Base, SDValue &Offset); 91 92 93 // getI32Imm - Return a target constant with the specified 94 // value, of type i32. 95 inline SDValue getI32Imm(unsigned Imm) { 96 return CurDAG->getTargetConstant(Imm, MVT::i32); 97 } 98 99 100 #ifndef NDEBUG 101 unsigned Indent; 102 #endif 103 }; 104 105 } 106 107 /// InstructionSelect - This callback is invoked by 108 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 109 void MipsDAGToDAGISel:: 110 InstructionSelect() 111 { 112 DEBUG(BB->dump()); 113 // Codegen the basic block. 114 #ifndef NDEBUG 115 DOUT << "===== Instruction selection begins:\n"; 116 Indent = 0; 117 #endif 118 119 // Select target instructions for the DAG. 120 SelectRoot(*CurDAG); 121 122 #ifndef NDEBUG 123 DOUT << "===== Instruction selection ends:\n"; 124 #endif 125 126 CurDAG->RemoveDeadNodes(); 127 } 128 129 /// getGlobalBaseReg - Output the instructions required to put the 130 /// GOT address into a register. 131 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { 132 MachineFunction *MF = BB->getParent(); 133 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); 134 return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); 135 } 136 137 /// ComplexPattern used on MipsInstrInfo 138 /// Used on Mips Load/Store instructions 139 bool MipsDAGToDAGISel:: 140 SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base) 141 { 142 // if Address is FI, get the TargetFrameIndex. 143 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 144 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 145 Offset = CurDAG->getTargetConstant(0, MVT::i32); 146 return true; 147 } 148 149 // on PIC code Load GA 150 if (TM.getRelocationModel() == Reloc::PIC_) { 151 if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || 152 (Addr.getOpcode() == ISD::TargetJumpTable)){ 153 Base = CurDAG->getRegister(Mips::GP, MVT::i32); 154 Offset = Addr; 155 return true; 156 } 157 } else { 158 if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 159 Addr.getOpcode() == ISD::TargetGlobalAddress)) 160 return false; 161 } 162 163 // Operand is a result from an ADD. 164 if (Addr.getOpcode() == ISD::ADD) { 165 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 166 if (Predicate_immSExt16(CN)) { 167 168 // If the first operand is a FI, get the TargetFI Node 169 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 170 (Addr.getOperand(0))) { 171 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 172 } else { 173 Base = Addr.getOperand(0); 174 } 175 176 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); 177 return true; 178 } 179 } 180 } 181 182 Base = Addr; 183 Offset = CurDAG->getTargetConstant(0, MVT::i32); 184 return true; 185 } 186 187 /// Select instructions not customized! Used for 188 /// expanded, promoted and normal instructions 189 SDNode* MipsDAGToDAGISel:: 190 Select(SDValue N) 191 { 192 SDNode *Node = N.getNode(); 193 unsigned Opcode = Node->getOpcode(); 194 DebugLoc dl = Node->getDebugLoc(); 195 196 // Dump information about the Node being selected 197 #ifndef NDEBUG 198 DOUT << std::string(Indent, ' ') << "Selecting: "; 199 DEBUG(Node->dump(CurDAG)); 200 DOUT << "\n"; 201 Indent += 2; 202 #endif 203 204 // If we have a custom node, we already have selected! 205 if (Node->isMachineOpcode()) { 206 #ifndef NDEBUG 207 DOUT << std::string(Indent-2, ' ') << "== "; 208 DEBUG(Node->dump(CurDAG)); 209 DOUT << "\n"; 210 Indent -= 2; 211 #endif 212 return NULL; 213 } 214 215 /// 216 // Instruction Selection not handled by the auto-generated 217 // tablegen selection should be handled here. 218 /// 219 switch(Opcode) { 220 221 default: break; 222 223 case ISD::SUBE: 224 case ISD::ADDE: { 225 SDValue InFlag = Node->getOperand(2), CmpLHS; 226 unsigned Opc = InFlag.getOpcode(); Opc=Opc; 227 assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 228 (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 229 "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 230 231 unsigned MOp; 232 if (Opcode == ISD::ADDE) { 233 CmpLHS = InFlag.getValue(0); 234 MOp = Mips::ADDu; 235 } else { 236 CmpLHS = InFlag.getOperand(0); 237 MOp = Mips::SUBu; 238 } 239 240 SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 241 242 SDValue LHS = Node->getOperand(0); 243 SDValue RHS = Node->getOperand(1); 244 245 MVT VT = LHS.getValueType(); 246 SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, dl, VT, Ops, 2); 247 SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, dl, VT, 248 SDValue(Carry,0), RHS); 249 250 return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag, 251 LHS, SDValue(AddCarry,0)); 252 } 253 254 /// Mul/Div with two results 255 case ISD::SDIVREM: 256 case ISD::UDIVREM: 257 case ISD::SMUL_LOHI: 258 case ISD::UMUL_LOHI: { 259 SDValue Op1 = Node->getOperand(0); 260 SDValue Op2 = Node->getOperand(1); 261 262 unsigned Op; 263 if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI) 264 Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); 265 else 266 Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV); 267 268 SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2); 269 270 SDValue InFlag = SDValue(Node, 0); 271 SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32, 272 MVT::Flag, InFlag); 273 InFlag = SDValue(Lo,1); 274 SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag); 275 276 if (!N.getValue(0).use_empty()) 277 ReplaceUses(N.getValue(0), SDValue(Lo,0)); 278 279 if (!N.getValue(1).use_empty()) 280 ReplaceUses(N.getValue(1), SDValue(Hi,0)); 281 282 return NULL; 283 } 284 285 /// Special Muls 286 case ISD::MUL: 287 case ISD::MULHS: 288 case ISD::MULHU: { 289 SDValue MulOp1 = Node->getOperand(0); 290 SDValue MulOp2 = Node->getOperand(1); 291 292 unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); 293 SDNode *MulNode = CurDAG->getTargetNode(MulOp, dl, 294 MVT::Flag, MulOp1, MulOp2); 295 296 SDValue InFlag = SDValue(MulNode, 0); 297 298 if (MulOp == ISD::MUL) 299 return CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32, InFlag); 300 else 301 return CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag); 302 } 303 304 /// Div/Rem operations 305 case ISD::SREM: 306 case ISD::UREM: 307 case ISD::SDIV: 308 case ISD::UDIV: { 309 SDValue Op1 = Node->getOperand(0); 310 SDValue Op2 = Node->getOperand(1); 311 312 unsigned Op, MOp; 313 if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) { 314 Op = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu); 315 MOp = Mips::MFLO; 316 } else { 317 Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu); 318 MOp = Mips::MFHI; 319 } 320 SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2); 321 322 SDValue InFlag = SDValue(Node, 0); 323 return CurDAG->getTargetNode(MOp, dl, MVT::i32, InFlag); 324 } 325 326 // Get target GOT address. 327 case ISD::GLOBAL_OFFSET_TABLE: 328 return getGlobalBaseReg(); 329 330 /// Handle direct and indirect calls when using PIC. On PIC, when 331 /// GOT is smaller than about 64k (small code) the GA target is 332 /// loaded with only one instruction. Otherwise GA's target must 333 /// be loaded with 3 instructions. 334 case MipsISD::JmpLink: { 335 if (TM.getRelocationModel() == Reloc::PIC_) { 336 //bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large); 337 SDValue Chain = Node->getOperand(0); 338 SDValue Callee = Node->getOperand(1); 339 SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32); 340 SDValue InFlag(0, 0); 341 342 if ( (isa<GlobalAddressSDNode>(Callee)) || 343 (isa<ExternalSymbolSDNode>(Callee)) ) 344 { 345 /// Direct call for global addresses and external symbols 346 SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32); 347 348 // Use load to get GOT target 349 SDValue Ops[] = { Callee, GPReg, Chain }; 350 SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, dl, MVT::i32, 351 MVT::Other, Ops, 3), 0); 352 Chain = Load.getValue(1); 353 354 // Call target must be on T9 355 Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag); 356 } else 357 /// Indirect call 358 Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag); 359 360 // Emit Jump and Link Register 361 SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, dl, MVT::Other, 362 MVT::Flag, T9Reg, Chain); 363 Chain = SDValue(ResNode, 0); 364 InFlag = SDValue(ResNode, 1); 365 ReplaceUses(SDValue(Node, 0), Chain); 366 ReplaceUses(SDValue(Node, 1), InFlag); 367 return ResNode; 368 } 369 } 370 } 371 372 // Select the default instruction 373 SDNode *ResNode = SelectCode(N); 374 375 #ifndef NDEBUG 376 DOUT << std::string(Indent-2, ' ') << "=> "; 377 if (ResNode == NULL || ResNode == N.getNode()) 378 DEBUG(N.getNode()->dump(CurDAG)); 379 else 380 DEBUG(ResNode->dump(CurDAG)); 381 DOUT << "\n"; 382 Indent -= 2; 383 #endif 384 385 return ResNode; 386 } 387 388 /// createMipsISelDag - This pass converts a legalized DAG into a 389 /// MIPS-specific DAG, ready for instruction scheduling. 390 FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { 391 return new MipsDAGToDAGISel(TM); 392 } 393