1 //===-- MBlazeISelDAGToDAG.cpp - A dag to dag inst selector for MBlaze ----===// 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 MBlaze target. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "mblaze-isel" 15 #include "MBlaze.h" 16 #include "MBlazeMachineFunction.h" 17 #include "MBlazeRegisterInfo.h" 18 #include "MBlazeSubtarget.h" 19 #include "MBlazeTargetMachine.h" 20 #include "llvm/GlobalValue.h" 21 #include "llvm/Instructions.h" 22 #include "llvm/Intrinsics.h" 23 #include "llvm/Support/CFG.h" 24 #include "llvm/Type.h" 25 #include "llvm/CodeGen/MachineConstantPool.h" 26 #include "llvm/CodeGen/MachineFunction.h" 27 #include "llvm/CodeGen/MachineFrameInfo.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineRegisterInfo.h" 30 #include "llvm/CodeGen/SelectionDAGISel.h" 31 #include "llvm/Target/TargetMachine.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/raw_ostream.h" 35 using namespace llvm; 36 37 //===----------------------------------------------------------------------===// 38 // Instruction Selector Implementation 39 //===----------------------------------------------------------------------===// 40 41 //===----------------------------------------------------------------------===// 42 // MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine 43 // instructions for SelectionDAG operations. 44 //===----------------------------------------------------------------------===// 45 namespace { 46 47 class MBlazeDAGToDAGISel : public SelectionDAGISel { 48 49 /// TM - Keep a reference to MBlazeTargetMachine. 50 MBlazeTargetMachine &TM; 51 52 /// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can 53 /// make the right decision when generating code for different targets. 54 const MBlazeSubtarget &Subtarget; 55 56 public: 57 explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) : 58 SelectionDAGISel(tm), 59 TM(tm), Subtarget(tm.getSubtarget<MBlazeSubtarget>()) {} 60 61 // Pass Name 62 virtual const char *getPassName() const { 63 return "MBlaze DAG->DAG Pattern Instruction Selection"; 64 } 65 private: 66 // Include the pieces autogenerated from the target description. 67 #include "MBlazeGenDAGISel.inc" 68 69 /// getTargetMachine - Return a reference to the TargetMachine, casted 70 /// to the target-specific type. 71 const MBlazeTargetMachine &getTargetMachine() { 72 return static_cast<const MBlazeTargetMachine &>(TM); 73 } 74 75 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted 76 /// to the target-specific type. 77 const MBlazeInstrInfo *getInstrInfo() { 78 return getTargetMachine().getInstrInfo(); 79 } 80 81 SDNode *getGlobalBaseReg(); 82 SDNode *Select(SDNode *N); 83 84 // Address Selection 85 bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index); 86 bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base); 87 88 // getI32Imm - Return a target constant with the specified value, of type i32. 89 inline SDValue getI32Imm(unsigned Imm) { 90 return CurDAG->getTargetConstant(Imm, MVT::i32); 91 } 92 }; 93 94 } 95 96 /// isIntS32Immediate - This method tests to see if the node is either a 32-bit 97 /// or 64-bit immediate, and if the value can be accurately represented as a 98 /// sign extension from a 32-bit value. If so, this returns true and the 99 /// immediate. 100 static bool isIntS32Immediate(SDNode *N, int32_t &Imm) { 101 unsigned Opc = N->getOpcode(); 102 if (Opc != ISD::Constant) 103 return false; 104 105 Imm = (int32_t)cast<ConstantSDNode>(N)->getZExtValue(); 106 if (N->getValueType(0) == MVT::i32) 107 return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue(); 108 else 109 return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue(); 110 } 111 112 static bool isIntS32Immediate(SDValue Op, int32_t &Imm) { 113 return isIntS32Immediate(Op.getNode(), Imm); 114 } 115 116 117 /// SelectAddressRegReg - Given the specified addressed, check to see if it 118 /// can be represented as an indexed [r+r] operation. Returns false if it 119 /// can be more efficiently represented with [r+imm]. 120 bool MBlazeDAGToDAGISel:: 121 SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) { 122 if (N.getOpcode() == ISD::FrameIndex) return false; 123 if (N.getOpcode() == ISD::TargetExternalSymbol || 124 N.getOpcode() == ISD::TargetGlobalAddress) 125 return false; // direct calls. 126 127 int32_t imm = 0; 128 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 129 if (isIntS32Immediate(N.getOperand(1), imm)) 130 return false; // r+i 131 132 if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable || 133 N.getOperand(1).getOpcode() == ISD::TargetJumpTable) 134 return false; // jump tables. 135 136 Base = N.getOperand(0); 137 Index = N.getOperand(1); 138 return true; 139 } 140 141 return false; 142 } 143 144 /// Returns true if the address N can be represented by a base register plus 145 /// a signed 32-bit displacement [r+imm], and if it is not better 146 /// represented as reg+reg. 147 bool MBlazeDAGToDAGISel:: 148 SelectAddrRegImm(SDValue N, SDValue &Base, SDValue &Disp) { 149 // If this can be more profitably realized as r+r, fail. 150 if (SelectAddrRegReg(N, Base, Disp)) 151 return false; 152 153 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 154 int32_t imm = 0; 155 if (isIntS32Immediate(N.getOperand(1), imm)) { 156 Disp = CurDAG->getTargetConstant(imm, MVT::i32); 157 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) { 158 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 159 } else { 160 Base = N.getOperand(0); 161 } 162 return true; // [r+i] 163 } 164 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { 165 // Loading from a constant address. 166 uint32_t Imm = CN->getZExtValue(); 167 Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0)); 168 Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0)); 169 return true; 170 } 171 172 Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy()); 173 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) 174 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 175 else 176 Base = N; 177 return true; // [r+0] 178 } 179 180 /// getGlobalBaseReg - Output the instructions required to put the 181 /// GOT address into a register. 182 SDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() { 183 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); 184 return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); 185 } 186 187 /// Select instructions not customized! Used for 188 /// expanded, promoted and normal instructions 189 SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) { 190 unsigned Opcode = Node->getOpcode(); 191 DebugLoc dl = Node->getDebugLoc(); 192 193 // If we have a custom node, we already have selected! 194 if (Node->isMachineOpcode()) 195 return NULL; 196 197 /// 198 // Instruction Selection not handled by the auto-generated 199 // tablegen selection should be handled here. 200 /// 201 switch (Opcode) { 202 default: break; 203 204 // Get target GOT address. 205 case ISD::GLOBAL_OFFSET_TABLE: 206 return getGlobalBaseReg(); 207 208 case ISD::FrameIndex: { 209 SDValue imm = CurDAG->getTargetConstant(0, MVT::i32); 210 int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex(); 211 EVT VT = Node->getValueType(0); 212 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); 213 unsigned Opc = MBlaze::ADDIK; 214 if (Node->hasOneUse()) 215 return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm); 216 return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm); 217 } 218 219 220 /// Handle direct and indirect calls when using PIC. On PIC, when 221 /// GOT is smaller than about 64k (small code) the GA target is 222 /// loaded with only one instruction. Otherwise GA's target must 223 /// be loaded with 3 instructions. 224 case MBlazeISD::JmpLink: { 225 if (TM.getRelocationModel() == Reloc::PIC_) { 226 SDValue Chain = Node->getOperand(0); 227 SDValue Callee = Node->getOperand(1); 228 SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32); 229 SDValue InFlag(0, 0); 230 231 if ((isa<GlobalAddressSDNode>(Callee)) || 232 (isa<ExternalSymbolSDNode>(Callee))) 233 { 234 /// Direct call for global addresses and external symbols 235 SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32); 236 237 // Use load to get GOT target 238 SDValue Ops[] = { Callee, GPReg, Chain }; 239 SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl, 240 MVT::i32, MVT::Other, Ops, 3), 0); 241 Chain = Load.getValue(1); 242 243 // Call target must be on T9 244 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag); 245 } else 246 /// Indirect call 247 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag); 248 249 // Emit Jump and Link Register 250 SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other, 251 MVT::Glue, R20Reg, Chain); 252 Chain = SDValue(ResNode, 0); 253 InFlag = SDValue(ResNode, 1); 254 ReplaceUses(SDValue(Node, 0), Chain); 255 ReplaceUses(SDValue(Node, 1), InFlag); 256 return ResNode; 257 } 258 } 259 } 260 261 // Select the default instruction 262 SDNode *ResNode = SelectCode(Node); 263 264 DEBUG(errs() << "=> "); 265 if (ResNode == NULL || ResNode == Node) 266 DEBUG(Node->dump(CurDAG)); 267 else 268 DEBUG(ResNode->dump(CurDAG)); 269 DEBUG(errs() << "\n"); 270 return ResNode; 271 } 272 273 /// createMBlazeISelDag - This pass converts a legalized DAG into a 274 /// MBlaze-specific DAG, ready for instruction scheduling. 275 FunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) { 276 return new MBlazeDAGToDAGISel(TM); 277 } 278