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