MSP430ISelDAGToDAG.cpp revision de09e922a6a82ff48d31328606f691591ae8fa19
1//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===// 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 MSP430 target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MSP430.h" 15#include "MSP430TargetMachine.h" 16#include "llvm/DerivedTypes.h" 17#include "llvm/Function.h" 18#include "llvm/Intrinsics.h" 19#include "llvm/CallingConv.h" 20#include "llvm/Constants.h" 21#include "llvm/CodeGen/MachineFrameInfo.h" 22#include "llvm/CodeGen/MachineFunction.h" 23#include "llvm/CodeGen/MachineInstrBuilder.h" 24#include "llvm/CodeGen/MachineRegisterInfo.h" 25#include "llvm/CodeGen/SelectionDAG.h" 26#include "llvm/CodeGen/SelectionDAGISel.h" 27#include "llvm/Target/TargetLowering.h" 28#include "llvm/Support/Compiler.h" 29#include "llvm/Support/Debug.h" 30#include "llvm/Support/ErrorHandling.h" 31#include "llvm/Support/raw_ostream.h" 32using namespace llvm; 33 34namespace { 35 struct MSP430ISelAddressMode { 36 enum { 37 RegBase, 38 FrameIndexBase 39 } BaseType; 40 41 struct { // This is really a union, discriminated by BaseType! 42 SDValue Reg; 43 int FrameIndex; 44 } Base; 45 46 int16_t Disp; 47 const GlobalValue *GV; 48 const Constant *CP; 49 const BlockAddress *BlockAddr; 50 const char *ES; 51 int JT; 52 unsigned Align; // CP alignment. 53 54 MSP430ISelAddressMode() 55 : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0), 56 ES(0), JT(-1), Align(0) { 57 } 58 59 bool hasSymbolicDisplacement() const { 60 return GV != 0 || CP != 0 || ES != 0 || JT != -1; 61 } 62 63 bool hasBaseReg() const { 64 return Base.Reg.getNode() != 0; 65 } 66 67 void setBaseReg(SDValue Reg) { 68 BaseType = RegBase; 69 Base.Reg = Reg; 70 } 71 72 void dump() { 73 errs() << "MSP430ISelAddressMode " << this << '\n'; 74 if (BaseType == RegBase && Base.Reg.getNode() != 0) { 75 errs() << "Base.Reg "; 76 Base.Reg.getNode()->dump(); 77 } else if (BaseType == FrameIndexBase) { 78 errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 79 } 80 errs() << " Disp " << Disp << '\n'; 81 if (GV) { 82 errs() << "GV "; 83 GV->dump(); 84 } else if (CP) { 85 errs() << " CP "; 86 CP->dump(); 87 errs() << " Align" << Align << '\n'; 88 } else if (ES) { 89 errs() << "ES "; 90 errs() << ES << '\n'; 91 } else if (JT != -1) 92 errs() << " JT" << JT << " Align" << Align << '\n'; 93 } 94 }; 95} 96 97/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 98/// instructions for SelectionDAG operations. 99/// 100namespace { 101 class MSP430DAGToDAGISel : public SelectionDAGISel { 102 const MSP430TargetLowering &Lowering; 103 const MSP430Subtarget &Subtarget; 104 105 public: 106 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 107 : SelectionDAGISel(TM, OptLevel), 108 Lowering(*TM.getTargetLowering()), 109 Subtarget(*TM.getSubtargetImpl()) { } 110 111 virtual const char *getPassName() const { 112 return "MSP430 DAG->DAG Pattern Instruction Selection"; 113 } 114 115 bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 116 bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 117 bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 118 119 virtual bool 120 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 121 std::vector<SDValue> &OutOps); 122 123 // Include the pieces autogenerated from the target description. 124 #include "MSP430GenDAGISel.inc" 125 126 private: 127 SDNode *Select(SDNode *N); 128 SDNode *SelectIndexedLoad(SDNode *Op); 129 SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 130 unsigned Opc8, unsigned Opc16); 131 132 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp); 133 }; 134} // end anonymous namespace 135 136/// createMSP430ISelDag - This pass converts a legalized DAG into a 137/// MSP430-specific DAG, ready for instruction scheduling. 138/// 139FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 140 CodeGenOpt::Level OptLevel) { 141 return new MSP430DAGToDAGISel(TM, OptLevel); 142} 143 144 145/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 146/// These wrap things that will resolve down into a symbol reference. If no 147/// match is possible, this returns true, otherwise it returns false. 148bool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 149 // If the addressing mode already has a symbol as the displacement, we can 150 // never match another symbol. 151 if (AM.hasSymbolicDisplacement()) 152 return true; 153 154 SDValue N0 = N.getOperand(0); 155 156 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 157 AM.GV = G->getGlobal(); 158 AM.Disp += G->getOffset(); 159 //AM.SymbolFlags = G->getTargetFlags(); 160 } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 161 AM.CP = CP->getConstVal(); 162 AM.Align = CP->getAlignment(); 163 AM.Disp += CP->getOffset(); 164 //AM.SymbolFlags = CP->getTargetFlags(); 165 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 166 AM.ES = S->getSymbol(); 167 //AM.SymbolFlags = S->getTargetFlags(); 168 } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 169 AM.JT = J->getIndex(); 170 //AM.SymbolFlags = J->getTargetFlags(); 171 } else { 172 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 173 //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 174 } 175 return false; 176} 177 178/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 179/// specified addressing mode without any further recursion. 180bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 181 // Is the base register already occupied? 182 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 183 // If so, we cannot select it. 184 return true; 185 } 186 187 // Default, generate it as a register. 188 AM.BaseType = MSP430ISelAddressMode::RegBase; 189 AM.Base.Reg = N; 190 return false; 191} 192 193bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 194 DEBUG(errs() << "MatchAddress: "; AM.dump()); 195 196 switch (N.getOpcode()) { 197 default: break; 198 case ISD::Constant: { 199 uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 200 AM.Disp += Val; 201 return false; 202 } 203 204 case MSP430ISD::Wrapper: 205 if (!MatchWrapper(N, AM)) 206 return false; 207 break; 208 209 case ISD::FrameIndex: 210 if (AM.BaseType == MSP430ISelAddressMode::RegBase 211 && AM.Base.Reg.getNode() == 0) { 212 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 213 AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 214 return false; 215 } 216 break; 217 218 case ISD::ADD: { 219 MSP430ISelAddressMode Backup = AM; 220 if (!MatchAddress(N.getNode()->getOperand(0), AM) && 221 !MatchAddress(N.getNode()->getOperand(1), AM)) 222 return false; 223 AM = Backup; 224 if (!MatchAddress(N.getNode()->getOperand(1), AM) && 225 !MatchAddress(N.getNode()->getOperand(0), AM)) 226 return false; 227 AM = Backup; 228 229 break; 230 } 231 232 case ISD::OR: 233 // Handle "X | C" as "X + C" iff X is known to have C bits clear. 234 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 235 MSP430ISelAddressMode Backup = AM; 236 uint64_t Offset = CN->getSExtValue(); 237 // Start with the LHS as an addr mode. 238 if (!MatchAddress(N.getOperand(0), AM) && 239 // Address could not have picked a GV address for the displacement. 240 AM.GV == NULL && 241 // Check to see if the LHS & C is zero. 242 CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 243 AM.Disp += Offset; 244 return false; 245 } 246 AM = Backup; 247 } 248 break; 249 } 250 251 return MatchAddressBase(N, AM); 252} 253 254/// SelectAddr - returns true if it is able pattern match an addressing mode. 255/// It returns the operands which make up the maximal addressing mode it can 256/// match by reference. 257bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, 258 SDValue &Base, SDValue &Disp) { 259 MSP430ISelAddressMode AM; 260 261 if (MatchAddress(N, AM)) 262 return false; 263 264 EVT VT = N.getValueType(); 265 if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 266 if (!AM.Base.Reg.getNode()) 267 AM.Base.Reg = CurDAG->getRegister(0, VT); 268 } 269 270 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? 271 CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) : 272 AM.Base.Reg; 273 274 if (AM.GV) 275 Disp = CurDAG->getTargetGlobalAddress(AM.GV, Op->getDebugLoc(), 276 MVT::i16, AM.Disp, 277 0/*AM.SymbolFlags*/); 278 else if (AM.CP) 279 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 280 AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 281 else if (AM.ES) 282 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 283 else if (AM.JT != -1) 284 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 285 else if (AM.BlockAddr) 286 Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32, 287 true, 0/*AM.SymbolFlags*/); 288 else 289 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16); 290 291 return true; 292} 293 294bool MSP430DAGToDAGISel:: 295SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 296 std::vector<SDValue> &OutOps) { 297 SDValue Op0, Op1; 298 switch (ConstraintCode) { 299 default: return true; 300 case 'm': // memory 301 if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) 302 return true; 303 break; 304 } 305 306 OutOps.push_back(Op0); 307 OutOps.push_back(Op1); 308 return false; 309} 310 311static bool isValidIndexedLoad(const LoadSDNode *LD) { 312 ISD::MemIndexedMode AM = LD->getAddressingMode(); 313 if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 314 return false; 315 316 EVT VT = LD->getMemoryVT(); 317 318 switch (VT.getSimpleVT().SimpleTy) { 319 case MVT::i8: 320 // Sanity check 321 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 322 return false; 323 324 break; 325 case MVT::i16: 326 // Sanity check 327 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 328 return false; 329 330 break; 331 default: 332 return false; 333 } 334 335 return true; 336} 337 338SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { 339 LoadSDNode *LD = cast<LoadSDNode>(N); 340 if (!isValidIndexedLoad(LD)) 341 return NULL; 342 343 MVT VT = LD->getMemoryVT().getSimpleVT(); 344 345 unsigned Opcode = 0; 346 switch (VT.SimpleTy) { 347 case MVT::i8: 348 Opcode = MSP430::MOV8rm_POST; 349 break; 350 case MVT::i16: 351 Opcode = MSP430::MOV16rm_POST; 352 break; 353 default: 354 return NULL; 355 } 356 357 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), 358 VT, MVT::i16, MVT::Other, 359 LD->getBasePtr(), LD->getChain()); 360} 361 362SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, 363 SDValue N1, SDValue N2, 364 unsigned Opc8, unsigned Opc16) { 365 if (N1.getOpcode() == ISD::LOAD && 366 N1.hasOneUse() && 367 IsLegalToFold(N1, Op, Op, OptLevel)) { 368 LoadSDNode *LD = cast<LoadSDNode>(N1); 369 if (!isValidIndexedLoad(LD)) 370 return NULL; 371 372 MVT VT = LD->getMemoryVT().getSimpleVT(); 373 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 374 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 375 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 376 SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 377 SDNode *ResNode = 378 CurDAG->SelectNodeTo(Op, Opc, 379 VT, MVT::i16, MVT::Other, 380 Ops0, 3); 381 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 382 // Transfer chain. 383 ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 384 // Transfer writeback. 385 ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 386 return ResNode; 387 } 388 389 return NULL; 390} 391 392 393SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { 394 DebugLoc dl = Node->getDebugLoc(); 395 396 // Dump information about the Node being selected 397 DEBUG(errs() << "Selecting: "); 398 DEBUG(Node->dump(CurDAG)); 399 DEBUG(errs() << "\n"); 400 401 // If we have a custom node, we already have selected! 402 if (Node->isMachineOpcode()) { 403 DEBUG(errs() << "== "; 404 Node->dump(CurDAG); 405 errs() << "\n"); 406 return NULL; 407 } 408 409 // Few custom selection stuff. 410 switch (Node->getOpcode()) { 411 default: break; 412 case ISD::FrameIndex: { 413 assert(Node->getValueType(0) == MVT::i16); 414 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 415 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 416 if (Node->hasOneUse()) 417 return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, 418 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 419 return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, 420 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 421 } 422 case ISD::LOAD: 423 if (SDNode *ResNode = SelectIndexedLoad(Node)) 424 return ResNode; 425 // Other cases are autogenerated. 426 break; 427 case ISD::ADD: 428 if (SDNode *ResNode = 429 SelectIndexedBinOp(Node, 430 Node->getOperand(0), Node->getOperand(1), 431 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 432 return ResNode; 433 else if (SDNode *ResNode = 434 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 435 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 436 return ResNode; 437 438 // Other cases are autogenerated. 439 break; 440 case ISD::SUB: 441 if (SDNode *ResNode = 442 SelectIndexedBinOp(Node, 443 Node->getOperand(0), Node->getOperand(1), 444 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 445 return ResNode; 446 447 // Other cases are autogenerated. 448 break; 449 case ISD::AND: 450 if (SDNode *ResNode = 451 SelectIndexedBinOp(Node, 452 Node->getOperand(0), Node->getOperand(1), 453 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 454 return ResNode; 455 else if (SDNode *ResNode = 456 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 457 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 458 return ResNode; 459 460 // Other cases are autogenerated. 461 break; 462 case ISD::OR: 463 if (SDNode *ResNode = 464 SelectIndexedBinOp(Node, 465 Node->getOperand(0), Node->getOperand(1), 466 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 467 return ResNode; 468 else if (SDNode *ResNode = 469 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 470 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 471 return ResNode; 472 473 // Other cases are autogenerated. 474 break; 475 case ISD::XOR: 476 if (SDNode *ResNode = 477 SelectIndexedBinOp(Node, 478 Node->getOperand(0), Node->getOperand(1), 479 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 480 return ResNode; 481 else if (SDNode *ResNode = 482 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 483 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 484 return ResNode; 485 486 // Other cases are autogenerated. 487 break; 488 } 489 490 // Select the default instruction 491 SDNode *ResNode = SelectCode(Node); 492 493 DEBUG(errs() << "=> "); 494 if (ResNode == NULL || ResNode == Node) 495 DEBUG(Node->dump(CurDAG)); 496 else 497 DEBUG(ResNode->dump(CurDAG)); 498 DEBUG(errs() << "\n"); 499 500 return ResNode; 501} 502