MSP430ISelDAGToDAG.cpp revision 087340ec12cbd65e0e16e9ac9be194b3b57c8f2e
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 "MSP430ISelLowering.h" 16#include "MSP430TargetMachine.h" 17#include "llvm/DerivedTypes.h" 18#include "llvm/Function.h" 19#include "llvm/Intrinsics.h" 20#include "llvm/CallingConv.h" 21#include "llvm/Constants.h" 22#include "llvm/CodeGen/MachineFrameInfo.h" 23#include "llvm/CodeGen/MachineFunction.h" 24#include "llvm/CodeGen/MachineInstrBuilder.h" 25#include "llvm/CodeGen/MachineRegisterInfo.h" 26#include "llvm/CodeGen/SelectionDAG.h" 27#include "llvm/CodeGen/SelectionDAGISel.h" 28#include "llvm/Target/TargetLowering.h" 29#include "llvm/Support/Compiler.h" 30#include "llvm/Support/Debug.h" 31#include "llvm/Support/ErrorHandling.h" 32#include "llvm/Support/raw_ostream.h" 33using namespace llvm; 34 35namespace { 36 struct MSP430ISelAddressMode { 37 enum { 38 RegBase, 39 FrameIndexBase 40 } BaseType; 41 42 struct { // This is really a union, discriminated by BaseType! 43 SDValue Reg; 44 int FrameIndex; 45 } Base; 46 47 int16_t Disp; 48 GlobalValue *GV; 49 Constant *CP; 50 BlockAddress *BlockAddr; 51 const char *ES; 52 int JT; 53 unsigned Align; // CP alignment. 54 55 MSP430ISelAddressMode() 56 : BaseType(RegBase), Disp(0), GV(0), CP(0), BlockAddr(0), 57 ES(0), JT(-1), Align(0) { 58 } 59 60 bool hasSymbolicDisplacement() const { 61 return GV != 0 || CP != 0 || ES != 0 || JT != -1; 62 } 63 64 bool hasBaseReg() const { 65 return Base.Reg.getNode() != 0; 66 } 67 68 void setBaseReg(SDValue Reg) { 69 BaseType = RegBase; 70 Base.Reg = Reg; 71 } 72 73 void dump() { 74 errs() << "MSP430ISelAddressMode " << this << '\n'; 75 if (BaseType == RegBase && Base.Reg.getNode() != 0) { 76 errs() << "Base.Reg "; 77 Base.Reg.getNode()->dump(); 78 } else if (BaseType == FrameIndexBase) { 79 errs() << " Base.FrameIndex " << Base.FrameIndex << '\n'; 80 } 81 errs() << " Disp " << Disp << '\n'; 82 if (GV) { 83 errs() << "GV "; 84 GV->dump(); 85 } else if (CP) { 86 errs() << " CP "; 87 CP->dump(); 88 errs() << " Align" << Align << '\n'; 89 } else if (ES) { 90 errs() << "ES "; 91 errs() << ES << '\n'; 92 } else if (JT != -1) 93 errs() << " JT" << JT << " Align" << Align << '\n'; 94 } 95 }; 96} 97 98/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine 99/// instructions for SelectionDAG operations. 100/// 101namespace { 102 class MSP430DAGToDAGISel : public SelectionDAGISel { 103 MSP430TargetLowering &Lowering; 104 const MSP430Subtarget &Subtarget; 105 106 public: 107 MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel) 108 : SelectionDAGISel(TM, OptLevel), 109 Lowering(*TM.getTargetLowering()), 110 Subtarget(*TM.getSubtargetImpl()) { } 111 112 virtual const char *getPassName() const { 113 return "MSP430 DAG->DAG Pattern Instruction Selection"; 114 } 115 116 bool MatchAddress(SDValue N, MSP430ISelAddressMode &AM); 117 bool MatchWrapper(SDValue N, MSP430ISelAddressMode &AM); 118 bool MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM); 119 120 virtual bool 121 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 122 std::vector<SDValue> &OutOps); 123 124 // Include the pieces autogenerated from the target description. 125 #include "MSP430GenDAGISel.inc" 126 127 private: 128 SDNode *Select(SDNode *N); 129 SDNode *SelectIndexedLoad(SDNode *Op); 130 SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, 131 unsigned Opc8, unsigned Opc16); 132 133 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp); 134 }; 135} // end anonymous namespace 136 137/// createMSP430ISelDag - This pass converts a legalized DAG into a 138/// MSP430-specific DAG, ready for instruction scheduling. 139/// 140FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM, 141 CodeGenOpt::Level OptLevel) { 142 return new MSP430DAGToDAGISel(TM, OptLevel); 143} 144 145 146/// MatchWrapper - Try to match MSP430ISD::Wrapper node into an addressing mode. 147/// These wrap things that will resolve down into a symbol reference. If no 148/// match is possible, this returns true, otherwise it returns false. 149bool MSP430DAGToDAGISel::MatchWrapper(SDValue N, MSP430ISelAddressMode &AM) { 150 // If the addressing mode already has a symbol as the displacement, we can 151 // never match another symbol. 152 if (AM.hasSymbolicDisplacement()) 153 return true; 154 155 SDValue N0 = N.getOperand(0); 156 157 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) { 158 AM.GV = G->getGlobal(); 159 AM.Disp += G->getOffset(); 160 //AM.SymbolFlags = G->getTargetFlags(); 161 } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 162 AM.CP = CP->getConstVal(); 163 AM.Align = CP->getAlignment(); 164 AM.Disp += CP->getOffset(); 165 //AM.SymbolFlags = CP->getTargetFlags(); 166 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 167 AM.ES = S->getSymbol(); 168 //AM.SymbolFlags = S->getTargetFlags(); 169 } else if (JumpTableSDNode *J = dyn_cast<JumpTableSDNode>(N0)) { 170 AM.JT = J->getIndex(); 171 //AM.SymbolFlags = J->getTargetFlags(); 172 } else { 173 AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); 174 //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); 175 } 176 return false; 177} 178 179/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 180/// specified addressing mode without any further recursion. 181bool MSP430DAGToDAGISel::MatchAddressBase(SDValue N, MSP430ISelAddressMode &AM) { 182 // Is the base register already occupied? 183 if (AM.BaseType != MSP430ISelAddressMode::RegBase || AM.Base.Reg.getNode()) { 184 // If so, we cannot select it. 185 return true; 186 } 187 188 // Default, generate it as a register. 189 AM.BaseType = MSP430ISelAddressMode::RegBase; 190 AM.Base.Reg = N; 191 return false; 192} 193 194bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) { 195 DEBUG(errs() << "MatchAddress: "; AM.dump()); 196 197 switch (N.getOpcode()) { 198 default: break; 199 case ISD::Constant: { 200 uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 201 AM.Disp += Val; 202 return false; 203 } 204 205 case MSP430ISD::Wrapper: 206 if (!MatchWrapper(N, AM)) 207 return false; 208 break; 209 210 case ISD::FrameIndex: 211 if (AM.BaseType == MSP430ISelAddressMode::RegBase 212 && AM.Base.Reg.getNode() == 0) { 213 AM.BaseType = MSP430ISelAddressMode::FrameIndexBase; 214 AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 215 return false; 216 } 217 break; 218 219 case ISD::ADD: { 220 MSP430ISelAddressMode Backup = AM; 221 if (!MatchAddress(N.getNode()->getOperand(0), AM) && 222 !MatchAddress(N.getNode()->getOperand(1), AM)) 223 return false; 224 AM = Backup; 225 if (!MatchAddress(N.getNode()->getOperand(1), AM) && 226 !MatchAddress(N.getNode()->getOperand(0), AM)) 227 return false; 228 AM = Backup; 229 230 break; 231 } 232 233 case ISD::OR: 234 // Handle "X | C" as "X + C" iff X is known to have C bits clear. 235 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 236 MSP430ISelAddressMode Backup = AM; 237 uint64_t Offset = CN->getSExtValue(); 238 // Start with the LHS as an addr mode. 239 if (!MatchAddress(N.getOperand(0), AM) && 240 // Address could not have picked a GV address for the displacement. 241 AM.GV == NULL && 242 // Check to see if the LHS & C is zero. 243 CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 244 AM.Disp += Offset; 245 return false; 246 } 247 AM = Backup; 248 } 249 break; 250 } 251 252 return MatchAddressBase(N, AM); 253} 254 255/// SelectAddr - returns true if it is able pattern match an addressing mode. 256/// It returns the operands which make up the maximal addressing mode it can 257/// match by reference. 258bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, 259 SDValue &Base, SDValue &Disp) { 260 MSP430ISelAddressMode AM; 261 262 if (MatchAddress(N, AM)) 263 return false; 264 265 EVT VT = N.getValueType(); 266 if (AM.BaseType == MSP430ISelAddressMode::RegBase) { 267 if (!AM.Base.Reg.getNode()) 268 AM.Base.Reg = CurDAG->getRegister(0, VT); 269 } 270 271 Base = (AM.BaseType == MSP430ISelAddressMode::FrameIndexBase) ? 272 CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) : 273 AM.Base.Reg; 274 275 if (AM.GV) 276 Disp = CurDAG->getTargetGlobalAddress(AM.GV, 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)) { 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