MSP430ISelDAGToDAG.cpp revision 208954
1238438Sdteske//===-- MSP430ISelDAGToDAG.cpp - A dag to dag inst selector for MSP430 ----===// 2238438Sdteske// 3249746Sdteske// The LLVM Compiler Infrastructure 4238438Sdteske// 5238438Sdteske// This file is distributed under the University of Illinois Open Source 6238438Sdteske// License. See LICENSE.TXT for details. 7238438Sdteske// 8238438Sdteske//===----------------------------------------------------------------------===// 9238438Sdteske// 10238438Sdteske// This file defines an instruction selector for the MSP430 target. 11238438Sdteske// 12238438Sdteske//===----------------------------------------------------------------------===// 13238438Sdteske 14238438Sdteske#include "MSP430.h" 15238438Sdteske#include "MSP430TargetMachine.h" 16238438Sdteske#include "llvm/DerivedTypes.h" 17238438Sdteske#include "llvm/Function.h" 18238438Sdteske#include "llvm/Intrinsics.h" 19238438Sdteske#include "llvm/CallingConv.h" 20238438Sdteske#include "llvm/Constants.h" 21238438Sdteske#include "llvm/CodeGen/MachineFrameInfo.h" 22238438Sdteske#include "llvm/CodeGen/MachineFunction.h" 23238438Sdteske#include "llvm/CodeGen/MachineInstrBuilder.h" 24238438Sdteske#include "llvm/CodeGen/MachineRegisterInfo.h" 25238438Sdteske#include "llvm/CodeGen/SelectionDAG.h" 26238438Sdteske#include "llvm/CodeGen/SelectionDAGISel.h" 27238438Sdteske#include "llvm/Target/TargetLowering.h" 28238438Sdteske#include "llvm/Support/Compiler.h" 29238438Sdteske#include "llvm/Support/Debug.h" 30238438Sdteske#include "llvm/Support/ErrorHandling.h" 31240684Sdteske#include "llvm/Support/raw_ostream.h" 32240684Sdteskeusing namespace llvm; 33244675Sdteske 34240684Sdteskenamespace { 35240684Sdteske struct MSP430ISelAddressMode { 36240684Sdteske enum { 37238438Sdteske RegBase, 38240684Sdteske FrameIndexBase 39238438Sdteske } BaseType; 40238438Sdteske 41243112Sdteske struct { // This is really a union, discriminated by BaseType! 42238438Sdteske SDValue Reg; 43238438Sdteske int FrameIndex; 44238438Sdteske } Base; 45238438Sdteske 46238438Sdteske int16_t Disp; 47238438Sdteske const GlobalValue *GV; 48238438Sdteske const Constant *CP; 49238438Sdteske const BlockAddress *BlockAddr; 50238438Sdteske const char *ES; 51238438Sdteske int JT; 52251190Sdteske unsigned Align; // CP alignment. 53238438Sdteske 54238438Sdteske MSP430ISelAddressMode() 55238438Sdteske : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0), 56238438Sdteske ES(0), JT(-1), Align(0) { 57238438Sdteske } 58238438Sdteske 59238438Sdteske bool hasSymbolicDisplacement() const { 60238438Sdteske return GV != 0 || CP != 0 || ES != 0 || JT != -1; 61238438Sdteske } 62238438Sdteske 63238438Sdteske bool hasBaseReg() const { 64238438Sdteske return Base.Reg.getNode() != 0; 65238438Sdteske } 66238438Sdteske 67238438Sdteske void setBaseReg(SDValue Reg) { 68238438Sdteske BaseType = RegBase; 69238438Sdteske Base.Reg = Reg; 70238438Sdteske } 71238438Sdteske 72238438Sdteske void dump() { 73251190Sdteske errs() << "MSP430ISelAddressMode " << this << '\n'; 74251190Sdteske if (BaseType == RegBase && Base.Reg.getNode() != 0) { 75251190Sdteske errs() << "Base.Reg "; 76251190Sdteske Base.Reg.getNode()->dump(); 77251190Sdteske } else if (BaseType == FrameIndexBase) { 78251190Sdteske errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 79251190Sdteske } 80238438Sdteske errs() << " Disp " << Disp << '\n'; 81249751Sdteske if (GV) { 82249751Sdteske errs() << "GV "; 83249751Sdteske GV->dump(); 84249751Sdteske } else if (CP) { 85249751Sdteske errs() << " CP "; 86249751Sdteske CP->dump(); 87249751Sdteske errs() << " Align" << Align << '\n'; 88249751Sdteske } else if (ES) { 89249751Sdteske errs() << "ES "; 90249751Sdteske errs() << ES << '\n'; 91249751Sdteske } else if (JT != -1) 92249751Sdteske errs() << " JT" << JT << " Align" << Align << '\n'; 93249751Sdteske } 94249751Sdteske }; 95249751Sdteske} 96249751Sdteske 97251236Sdteske/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 98251236Sdteske/// instructions for SelectionDAG operations. 99249751Sdteske/// 100238438Sdteskenamespace { 101238438Sdteske class MSP430DAGToDAGISel : public SelectionDAGISel { 102238438Sdteske const MSP430TargetLowering &Lowering; 103238438Sdteske const MSP430Subtarget &Subtarget; 104249751Sdteske 105251190Sdteske public: 106251190Sdteske MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 107238438Sdteske : SelectionDAGISel(TM, OptLevel), 108240768Sdteske Lowering(*TM.getTargetLowering()), 109240768Sdteske Subtarget(*TM.getSubtargetImpl()) { } 110240768Sdteske 111251236Sdteske virtual const char *getPassName() const { 112240768Sdteske return "MSP430 DAG->DAG Pattern Instruction Selection"; 113238438Sdteske } 114238438Sdteske 115238438Sdteske bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 116238438Sdteske bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 117238438Sdteske bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 118238438Sdteske 119238438Sdteske virtual bool 120238438Sdteske SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 121238438Sdteske std::vector<SDValue> &OutOps); 122238438Sdteske 123250633Sdteske // Include the pieces autogenerated from the target description. 124238438Sdteske #include "MSP430GenDAGISel.inc" 125238438Sdteske 126238438Sdteske private: 127238438Sdteske SDNode *Select(SDNode *N); 128238438Sdteske SDNode *SelectIndexedLoad(SDNode *Op); 129238438Sdteske SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 130238438Sdteske unsigned Opc8, unsigned Opc16); 131238438Sdteske 132238438Sdteske bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp); 133238438Sdteske }; 134238438Sdteske} // end anonymous namespace 135238438Sdteske 136238438Sdteske/// createMSP430ISelDag - This pass converts a legalized DAG into a 137238438Sdteske/// MSP430-specific DAG, ready for instruction scheduling. 138238438Sdteske/// 139238438SdteskeFunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 140238438Sdteske CodeGenOpt::Level OptLevel) { 141251236Sdteske return new MSP430DAGToDAGISel(TM, OptLevel); 142251236Sdteske} 143238438Sdteske 144238438Sdteske 145238438Sdteske/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 146238438Sdteske/// These wrap things that will resolve down into a symbol reference. If no 147238438Sdteske/// match is possible, this returns true, otherwise it returns false. 148238438Sdteskebool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 149238438Sdteske // If the addressing mode already has a symbol as the displacement, we can 150238438Sdteske // never match another symbol. 151238438Sdteske if (AM.hasSymbolicDisplacement()) 152238438Sdteske return true; 153238438Sdteske 154238438Sdteske SDValue N0 = N.getOperand(0); 155238438Sdteske 156238438Sdteske if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 157238438Sdteske AM.GV = G->getGlobal(); 158238438Sdteske AM.Disp += G->getOffset(); 159238438Sdteske //AM.SymbolFlags = G->getTargetFlags(); 160238438Sdteske } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 161238438Sdteske AM.CP = CP->getConstVal(); 162238438Sdteske AM.Align = CP->getAlignment(); 163238438Sdteske AM.Disp += CP->getOffset(); 164238438Sdteske //AM.SymbolFlags = CP->getTargetFlags(); 165238438Sdteske } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 166238438Sdteske AM.ES = S->getSymbol(); 167238438Sdteske //AM.SymbolFlags = S->getTargetFlags(); 168238438Sdteske } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 169238438Sdteske AM.JT = J->getIndex(); 170238438Sdteske //AM.SymbolFlags = J->getTargetFlags(); 171238438Sdteske } else { 172238438Sdteske AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 173238438Sdteske //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 174238438Sdteske } 175238438Sdteske return false; 176238438Sdteske} 177238438Sdteske 178238438Sdteske/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 179238438Sdteske/// specified addressing mode without any further recursion. 180238438Sdteskebool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 181238438Sdteske // Is the base register already occupied? 182238438Sdteske if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 183238438Sdteske // If so, we cannot select it. 184238438Sdteske return true; 185238438Sdteske } 186251242Sdteske 187251242Sdteske // Default, generate it as a register. 188251242Sdteske AM.BaseType = MSP430ISelAddressMode::RegBase; 189238438Sdteske AM.Base.Reg = N; 190238438Sdteske return false; 191238438Sdteske} 192238438Sdteske 193238438Sdteskebool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 194238438Sdteske DEBUG(errs() << "MatchAddress: "; AM.dump()); 195238438Sdteske 196238438Sdteske switch (N.getOpcode()) { 197238438Sdteske default: break; 198238438Sdteske 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, MVT::i16, AM.Disp, 276 0/*AM.SymbolFlags*/); 277 else if (AM.CP) 278 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i16, 279 AM.Align, AM.Disp, 0/*AM.SymbolFlags*/); 280 else if (AM.ES) 281 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i16, 0/*AM.SymbolFlags*/); 282 else if (AM.JT != -1) 283 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/); 284 else if (AM.BlockAddr) 285 Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32, 286 true, 0/*AM.SymbolFlags*/); 287 else 288 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16); 289 290 return true; 291} 292 293bool MSP430DAGToDAGISel:: 294SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 295 std::vector<SDValue> &OutOps) { 296 SDValue Op0, Op1; 297 switch (ConstraintCode) { 298 default: return true; 299 case 'm': // memory 300 if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) 301 return true; 302 break; 303 } 304 305 OutOps.push_back(Op0); 306 OutOps.push_back(Op1); 307 return false; 308} 309 310static bool isValidIndexedLoad(const LoadSDNode *LD) { 311 ISD::MemIndexedMode AM = LD->getAddressingMode(); 312 if (AM != ISD::POST_INC || LD->getExtensionType() != ISD::NON_EXTLOAD) 313 return false; 314 315 EVT VT = LD->getMemoryVT(); 316 317 switch (VT.getSimpleVT().SimpleTy) { 318 case MVT::i8: 319 // Sanity check 320 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 1) 321 return false; 322 323 break; 324 case MVT::i16: 325 // Sanity check 326 if (cast<ConstantSDNode>(LD->getOffset())->getZExtValue() != 2) 327 return false; 328 329 break; 330 default: 331 return false; 332 } 333 334 return true; 335} 336 337SDNode *MSP430DAGToDAGISel::SelectIndexedLoad(SDNode *N) { 338 LoadSDNode *LD = cast<LoadSDNode>(N); 339 if (!isValidIndexedLoad(LD)) 340 return NULL; 341 342 MVT VT = LD->getMemoryVT().getSimpleVT(); 343 344 unsigned Opcode = 0; 345 switch (VT.SimpleTy) { 346 case MVT::i8: 347 Opcode = MSP430::MOV8rm_POST; 348 break; 349 case MVT::i16: 350 Opcode = MSP430::MOV16rm_POST; 351 break; 352 default: 353 return NULL; 354 } 355 356 return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), 357 VT, MVT::i16, MVT::Other, 358 LD->getBasePtr(), LD->getChain()); 359} 360 361SDNode *MSP430DAGToDAGISel::SelectIndexedBinOp(SDNode *Op, 362 SDValue N1, SDValue N2, 363 unsigned Opc8, unsigned Opc16) { 364 if (N1.getOpcode() == ISD::LOAD && 365 N1.hasOneUse() && 366 IsLegalToFold(N1, Op, Op, OptLevel)) { 367 LoadSDNode *LD = cast<LoadSDNode>(N1); 368 if (!isValidIndexedLoad(LD)) 369 return NULL; 370 371 MVT VT = LD->getMemoryVT().getSimpleVT(); 372 unsigned Opc = (VT == MVT::i16 ? Opc16 : Opc8); 373 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1); 374 MemRefs0[0] = cast<MemSDNode>(N1)->getMemOperand(); 375 SDValue Ops0[] = { N2, LD->getBasePtr(), LD->getChain() }; 376 SDNode *ResNode = 377 CurDAG->SelectNodeTo(Op, Opc, 378 VT, MVT::i16, MVT::Other, 379 Ops0, 3); 380 cast<MachineSDNode>(ResNode)->setMemRefs(MemRefs0, MemRefs0 + 1); 381 // Transfer chain. 382 ReplaceUses(SDValue(N1.getNode(), 2), SDValue(ResNode, 2)); 383 // Transfer writeback. 384 ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 1)); 385 return ResNode; 386 } 387 388 return NULL; 389} 390 391 392SDNode *MSP430DAGToDAGISel::Select(SDNode *Node) { 393 DebugLoc dl = Node->getDebugLoc(); 394 395 // Dump information about the Node being selected 396 DEBUG(errs() << "Selecting: "); 397 DEBUG(Node->dump(CurDAG)); 398 DEBUG(errs() << "\n"); 399 400 // If we have a custom node, we already have selected! 401 if (Node->isMachineOpcode()) { 402 DEBUG(errs() << "== "; 403 Node->dump(CurDAG); 404 errs() << "\n"); 405 return NULL; 406 } 407 408 // Few custom selection stuff. 409 switch (Node->getOpcode()) { 410 default: break; 411 case ISD::FrameIndex: { 412 assert(Node->getValueType(0) == MVT::i16); 413 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 414 SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16); 415 if (Node->hasOneUse()) 416 return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16, 417 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 418 return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, 419 TFI, CurDAG->getTargetConstant(0, MVT::i16)); 420 } 421 case ISD::LOAD: 422 if (SDNode *ResNode = SelectIndexedLoad(Node)) 423 return ResNode; 424 // Other cases are autogenerated. 425 break; 426 case ISD::ADD: 427 if (SDNode *ResNode = 428 SelectIndexedBinOp(Node, 429 Node->getOperand(0), Node->getOperand(1), 430 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 431 return ResNode; 432 else if (SDNode *ResNode = 433 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 434 MSP430::ADD8rm_POST, MSP430::ADD16rm_POST)) 435 return ResNode; 436 437 // Other cases are autogenerated. 438 break; 439 case ISD::SUB: 440 if (SDNode *ResNode = 441 SelectIndexedBinOp(Node, 442 Node->getOperand(0), Node->getOperand(1), 443 MSP430::SUB8rm_POST, MSP430::SUB16rm_POST)) 444 return ResNode; 445 446 // Other cases are autogenerated. 447 break; 448 case ISD::AND: 449 if (SDNode *ResNode = 450 SelectIndexedBinOp(Node, 451 Node->getOperand(0), Node->getOperand(1), 452 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 453 return ResNode; 454 else if (SDNode *ResNode = 455 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 456 MSP430::AND8rm_POST, MSP430::AND16rm_POST)) 457 return ResNode; 458 459 // Other cases are autogenerated. 460 break; 461 case ISD::OR: 462 if (SDNode *ResNode = 463 SelectIndexedBinOp(Node, 464 Node->getOperand(0), Node->getOperand(1), 465 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 466 return ResNode; 467 else if (SDNode *ResNode = 468 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 469 MSP430::OR8rm_POST, MSP430::OR16rm_POST)) 470 return ResNode; 471 472 // Other cases are autogenerated. 473 break; 474 case ISD::XOR: 475 if (SDNode *ResNode = 476 SelectIndexedBinOp(Node, 477 Node->getOperand(0), Node->getOperand(1), 478 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 479 return ResNode; 480 else if (SDNode *ResNode = 481 SelectIndexedBinOp(Node, Node->getOperand(1), Node->getOperand(0), 482 MSP430::XOR8rm_POST, MSP430::XOR16rm_POST)) 483 return ResNode; 484 485 // Other cases are autogenerated. 486 break; 487 } 488 489 // Select the default instruction 490 SDNode *ResNode = SelectCode(Node); 491 492 DEBUG(errs() << "=> "); 493 if (ResNode == NULL || ResNode == Node) 494 DEBUG(Node->dump(CurDAG)); 495 else 496 DEBUG(ResNode->dump(CurDAG)); 497 DEBUG(errs() << "\n"); 498 499 return ResNode; 500} 501