1 //===-- M68kISelDAGToDAG.cpp - M68k Dag to Dag Inst Selector ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file defines an instruction selector for the M68K target. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "M68k.h" 15 16 #include "M68kMachineFunction.h" 17 #include "M68kRegisterInfo.h" 18 #include "M68kTargetMachine.h" 19 20 #include "llvm/CodeGen/MachineConstantPool.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/SelectionDAGISel.h" 26 #include "llvm/CodeGen/SelectionDAGNodes.h" 27 #include "llvm/IR/CFG.h" 28 #include "llvm/IR/GlobalValue.h" 29 #include "llvm/IR/Instructions.h" 30 #include "llvm/IR/Intrinsics.h" 31 #include "llvm/IR/Type.h" 32 #include "llvm/Support/Alignment.h" 33 #include "llvm/Support/Debug.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include "llvm/Support/MathExtras.h" 36 #include "llvm/Support/raw_ostream.h" 37 #include "llvm/Target/TargetMachine.h" 38 39 using namespace llvm; 40 41 #define DEBUG_TYPE "m68k-isel" 42 #define PASS_NAME "M68k DAG->DAG Pattern Instruction Selection" 43 44 namespace { 45 46 // For reference, the full order of operands for memory references is: 47 // (Operand), Displacement, Base, Index, Scale 48 struct M68kISelAddressMode { 49 enum class AddrType { 50 ARI, // Address Register Indirect 51 ARIPI, // Address Register Indirect with Postincrement 52 ARIPD, // Address Register Indirect with Postdecrement 53 ARID, // Address Register Indirect with Displacement 54 ARII, // Address Register Indirect with Index 55 PCD, // Program Counter Indirect with Displacement 56 PCI, // Program Counter Indirect with Index 57 AL, // Absolute 58 }; 59 AddrType AM; 60 61 enum class Base { RegBase, FrameIndexBase }; 62 Base BaseType; 63 64 int64_t Disp; 65 66 // This is really a union, discriminated by BaseType! 67 SDValue BaseReg; 68 int BaseFrameIndex; 69 70 SDValue IndexReg; 71 unsigned Scale; 72 73 const GlobalValue *GV; 74 const Constant *CP; 75 const BlockAddress *BlockAddr; 76 const char *ES; 77 MCSymbol *MCSym; 78 int JT; 79 Align Alignment; // CP alignment. 80 81 unsigned char SymbolFlags; // M68kII::MO_* 82 83 M68kISelAddressMode(AddrType AT) 84 : AM(AT), BaseType(Base::RegBase), Disp(0), BaseFrameIndex(0), IndexReg(), 85 Scale(1), GV(nullptr), CP(nullptr), BlockAddr(nullptr), ES(nullptr), 86 MCSym(nullptr), JT(-1), Alignment(), SymbolFlags(M68kII::MO_NO_FLAG) {} 87 88 bool hasSymbolicDisplacement() const { 89 return GV != nullptr || CP != nullptr || ES != nullptr || 90 MCSym != nullptr || JT != -1 || BlockAddr != nullptr; 91 } 92 93 bool hasBase() const { 94 return BaseType == Base::FrameIndexBase || BaseReg.getNode() != nullptr; 95 } 96 97 bool hasFrameIndex() const { return BaseType == Base::FrameIndexBase; } 98 99 bool hasBaseReg() const { 100 return BaseType == Base::RegBase && BaseReg.getNode() != nullptr; 101 } 102 103 bool hasIndexReg() const { 104 return BaseType == Base::RegBase && IndexReg.getNode() != nullptr; 105 } 106 107 /// True if address mode type supports displacement 108 bool isDispAddrType() const { 109 return AM == AddrType::ARII || AM == AddrType::PCI || 110 AM == AddrType::ARID || AM == AddrType::PCD || AM == AddrType::AL; 111 } 112 113 unsigned getDispSize() const { 114 switch (AM) { 115 default: 116 return 0; 117 case AddrType::ARII: 118 case AddrType::PCI: 119 return 8; 120 // These two in the next chip generations can hold upto 32 bit 121 case AddrType::ARID: 122 case AddrType::PCD: 123 return 16; 124 case AddrType::AL: 125 return 32; 126 } 127 } 128 129 bool hasDisp() const { return getDispSize() != 0; } 130 bool isDisp8() const { return getDispSize() == 8; } 131 bool isDisp16() const { return getDispSize() == 16; } 132 bool isDisp32() const { return getDispSize() == 32; } 133 134 /// Return true if this addressing mode is already PC-relative. 135 bool isPCRelative() const { 136 if (BaseType != Base::RegBase) 137 return false; 138 if (auto *RegNode = dyn_cast_or_null<RegisterSDNode>(BaseReg.getNode())) 139 return RegNode->getReg() == M68k::PC; 140 return false; 141 } 142 143 void setBaseReg(SDValue Reg) { 144 BaseType = Base::RegBase; 145 BaseReg = Reg; 146 } 147 148 void setIndexReg(SDValue Reg) { IndexReg = Reg; } 149 150 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 151 void dump() { 152 dbgs() << "M68kISelAddressMode " << this; 153 dbgs() << "\nDisp: " << Disp; 154 dbgs() << ", BaseReg: "; 155 if (BaseReg.getNode()) 156 BaseReg.getNode()->dump(); 157 else 158 dbgs() << "null"; 159 dbgs() << ", BaseFI: " << BaseFrameIndex; 160 dbgs() << ", IndexReg: "; 161 if (IndexReg.getNode()) { 162 IndexReg.getNode()->dump(); 163 } else { 164 dbgs() << "null"; 165 dbgs() << ", Scale: " << Scale; 166 } 167 dbgs() << '\n'; 168 } 169 #endif 170 }; 171 } // end anonymous namespace 172 173 namespace { 174 175 class M68kDAGToDAGISel : public SelectionDAGISel { 176 public: 177 M68kDAGToDAGISel() = delete; 178 179 explicit M68kDAGToDAGISel(M68kTargetMachine &TM) 180 : SelectionDAGISel(TM), Subtarget(nullptr) {} 181 182 bool runOnMachineFunction(MachineFunction &MF) override; 183 bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const override; 184 185 private: 186 /// Keep a pointer to the M68kSubtarget around so that we can 187 /// make the right decision when generating code for different targets. 188 const M68kSubtarget *Subtarget; 189 190 // Include the pieces autogenerated from the target description. 191 #include "M68kGenDAGISel.inc" 192 193 /// getTargetMachine - Return a reference to the TargetMachine, casted 194 /// to the target-specific type. 195 const M68kTargetMachine &getTargetMachine() { 196 return static_cast<const M68kTargetMachine &>(TM); 197 } 198 199 void Select(SDNode *N) override; 200 201 // Insert instructions to initialize the global base register in the 202 // first MBB of the function. 203 // HMM... do i need this? 204 void initGlobalBaseReg(MachineFunction &MF); 205 206 bool foldOffsetIntoAddress(uint64_t Offset, M68kISelAddressMode &AM); 207 208 bool matchLoadInAddress(LoadSDNode *N, M68kISelAddressMode &AM); 209 bool matchAddress(SDValue N, M68kISelAddressMode &AM); 210 bool matchAddressBase(SDValue N, M68kISelAddressMode &AM); 211 bool matchAddressRecursively(SDValue N, M68kISelAddressMode &AM, 212 unsigned Depth); 213 bool matchADD(SDValue &N, M68kISelAddressMode &AM, unsigned Depth); 214 bool matchWrapper(SDValue N, M68kISelAddressMode &AM); 215 216 std::pair<bool, SDNode *> selectNode(SDNode *Node); 217 218 bool SelectARI(SDNode *Parent, SDValue N, SDValue &Base); 219 bool SelectARIPI(SDNode *Parent, SDValue N, SDValue &Base); 220 bool SelectARIPD(SDNode *Parent, SDValue N, SDValue &Base); 221 bool SelectARID(SDNode *Parent, SDValue N, SDValue &Imm, SDValue &Base); 222 bool SelectARII(SDNode *Parent, SDValue N, SDValue &Imm, SDValue &Base, 223 SDValue &Index); 224 bool SelectAL(SDNode *Parent, SDValue N, SDValue &Sym); 225 bool SelectPCD(SDNode *Parent, SDValue N, SDValue &Imm); 226 bool SelectPCI(SDNode *Parent, SDValue N, SDValue &Imm, SDValue &Index); 227 228 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 229 InlineAsm::ConstraintCode ConstraintID, 230 std::vector<SDValue> &OutOps) override; 231 232 // If Address Mode represents Frame Index store FI in Disp and 233 // Displacement bit size in Base. These values are read symmetrically by 234 // M68kRegisterInfo::eliminateFrameIndex method 235 inline bool getFrameIndexAddress(M68kISelAddressMode &AM, const SDLoc &DL, 236 SDValue &Disp, SDValue &Base) { 237 if (AM.BaseType == M68kISelAddressMode::Base::FrameIndexBase) { 238 Disp = getI32Imm(AM.Disp, DL); 239 Base = CurDAG->getTargetFrameIndex( 240 AM.BaseFrameIndex, TLI->getPointerTy(CurDAG->getDataLayout())); 241 return true; 242 } 243 244 return false; 245 } 246 247 // Gets a symbol plus optional displacement 248 inline bool getSymbolicDisplacement(M68kISelAddressMode &AM, const SDLoc &DL, 249 SDValue &Sym) { 250 if (AM.GV) { 251 Sym = CurDAG->getTargetGlobalAddress(AM.GV, SDLoc(), MVT::i32, AM.Disp, 252 AM.SymbolFlags); 253 return true; 254 } 255 256 if (AM.CP) { 257 Sym = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Alignment, 258 AM.Disp, AM.SymbolFlags); 259 return true; 260 } 261 262 if (AM.ES) { 263 assert(!AM.Disp && "Non-zero displacement is ignored with ES."); 264 Sym = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags); 265 return true; 266 } 267 268 if (AM.MCSym) { 269 assert(!AM.Disp && "Non-zero displacement is ignored with MCSym."); 270 assert(AM.SymbolFlags == 0 && "oo"); 271 Sym = CurDAG->getMCSymbol(AM.MCSym, MVT::i32); 272 return true; 273 } 274 275 if (AM.JT != -1) { 276 assert(!AM.Disp && "Non-zero displacement is ignored with JT."); 277 Sym = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags); 278 return true; 279 } 280 281 if (AM.BlockAddr) { 282 Sym = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp, 283 AM.SymbolFlags); 284 return true; 285 } 286 287 return false; 288 } 289 290 /// Return a target constant with the specified value of type i8. 291 inline SDValue getI8Imm(int64_t Imm, const SDLoc &DL) { 292 return CurDAG->getTargetConstant(Imm, DL, MVT::i8); 293 } 294 295 /// Return a target constant with the specified value of type i8. 296 inline SDValue getI16Imm(int64_t Imm, const SDLoc &DL) { 297 return CurDAG->getTargetConstant(Imm, DL, MVT::i16); 298 } 299 300 /// Return a target constant with the specified value, of type i32. 301 inline SDValue getI32Imm(int64_t Imm, const SDLoc &DL) { 302 return CurDAG->getTargetConstant(Imm, DL, MVT::i32); 303 } 304 305 /// Return a reference to the TargetInstrInfo, casted to the target-specific 306 /// type. 307 const M68kInstrInfo *getInstrInfo() const { 308 return Subtarget->getInstrInfo(); 309 } 310 311 /// Return an SDNode that returns the value of the global base register. 312 /// Output instructions required to initialize the global base register, 313 /// if necessary. 314 SDNode *getGlobalBaseReg(); 315 }; 316 317 class M68kDAGToDAGISelLegacy : public SelectionDAGISelLegacy { 318 public: 319 static char ID; 320 explicit M68kDAGToDAGISelLegacy(M68kTargetMachine &TM) 321 : SelectionDAGISelLegacy(ID, std::make_unique<M68kDAGToDAGISel>(TM)) {} 322 }; 323 324 char M68kDAGToDAGISelLegacy::ID; 325 326 } // namespace 327 328 INITIALIZE_PASS(M68kDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false) 329 330 bool M68kDAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U, 331 SDNode *Root) const { 332 if (OptLevel == CodeGenOptLevel::None) 333 return false; 334 335 if (U == Root) { 336 switch (U->getOpcode()) { 337 default: 338 return true; 339 case M68kISD::SUB: 340 case ISD::SUB: 341 // Prefer NEG instruction when zero subtracts a value. 342 // e.g. 343 // move.l #0, %d0 344 // sub.l (4,%sp), %d0 345 // vs. 346 // move.l (4,%sp), %d0 347 // neg.l %d0 348 if (llvm::isNullConstant(U->getOperand(0))) 349 return false; 350 break; 351 } 352 } 353 354 return true; 355 } 356 357 bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 358 Subtarget = &MF.getSubtarget<M68kSubtarget>(); 359 return SelectionDAGISel::runOnMachineFunction(MF); 360 } 361 362 /// This pass converts a legalized DAG into a M68k-specific DAG, 363 /// ready for instruction scheduling. 364 FunctionPass *llvm::createM68kISelDag(M68kTargetMachine &TM) { 365 return new M68kDAGToDAGISelLegacy(TM); 366 } 367 368 static bool doesDispFitFI(M68kISelAddressMode &AM) { 369 if (!AM.isDispAddrType()) 370 return false; 371 // -1 to make sure that resolved FI will fit into Disp field 372 return isIntN(AM.getDispSize() - 1, AM.Disp); 373 } 374 375 static bool doesDispFit(M68kISelAddressMode &AM, int64_t Val) { 376 if (!AM.isDispAddrType()) 377 return false; 378 return isIntN(AM.getDispSize(), Val); 379 } 380 381 /// Return an SDNode that returns the value of the global base register. 382 /// Output instructions required to initialize the global base register, 383 /// if necessary. 384 SDNode *M68kDAGToDAGISel::getGlobalBaseReg() { 385 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); 386 auto &DL = MF->getDataLayout(); 387 return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy(DL)).getNode(); 388 } 389 390 bool M68kDAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset, 391 M68kISelAddressMode &AM) { 392 // Cannot combine ExternalSymbol displacements with integer offsets. 393 if (Offset != 0 && (AM.ES || AM.MCSym)) 394 return false; 395 396 int64_t Val = AM.Disp + Offset; 397 398 if (doesDispFit(AM, Val)) { 399 AM.Disp = Val; 400 return true; 401 } 402 403 return false; 404 } 405 406 //===----------------------------------------------------------------------===// 407 // Matchers 408 //===----------------------------------------------------------------------===// 409 410 /// Helper for MatchAddress. Add the specified node to the 411 /// specified addressing mode without any further recursion. 412 bool M68kDAGToDAGISel::matchAddressBase(SDValue N, M68kISelAddressMode &AM) { 413 // Is the base register already occupied? 414 if (AM.hasBase()) { 415 // If so, check to see if the scale index register is set. 416 if (!AM.hasIndexReg()) { 417 AM.IndexReg = N; 418 AM.Scale = 1; 419 return true; 420 } 421 422 // Otherwise, we cannot select it. 423 return false; 424 } 425 426 // Default, generate it as a register. 427 AM.BaseType = M68kISelAddressMode::Base::RegBase; 428 AM.BaseReg = N; 429 return true; 430 } 431 432 /// TODO Add TLS support 433 bool M68kDAGToDAGISel::matchLoadInAddress(LoadSDNode *N, 434 M68kISelAddressMode &AM) { 435 return false; 436 } 437 438 bool M68kDAGToDAGISel::matchAddressRecursively(SDValue N, 439 M68kISelAddressMode &AM, 440 unsigned Depth) { 441 SDLoc DL(N); 442 443 // Limit recursion. 444 if (Depth > 5) 445 return matchAddressBase(N, AM); 446 447 // If this is already a %PC relative address, we can only merge immediates 448 // into it. Instead of handling this in every case, we handle it here. 449 // PC relative addressing: %PC + 16-bit displacement! 450 if (AM.isPCRelative()) { 451 // FIXME JumpTable and ExternalSymbol address currently don't like 452 // displacements. It isn't very important, but should be fixed for 453 // consistency. 454 455 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(N)) 456 if (foldOffsetIntoAddress(Cst->getSExtValue(), AM)) 457 return true; 458 return false; 459 } 460 461 switch (N.getOpcode()) { 462 default: 463 break; 464 465 case ISD::Constant: { 466 uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 467 if (foldOffsetIntoAddress(Val, AM)) 468 return true; 469 break; 470 } 471 472 case M68kISD::Wrapper: 473 case M68kISD::WrapperPC: 474 if (matchWrapper(N, AM)) 475 return true; 476 break; 477 478 case ISD::LOAD: 479 if (matchLoadInAddress(cast<LoadSDNode>(N), AM)) 480 return true; 481 break; 482 483 case ISD::OR: 484 // We want to look through a transform in InstCombine and DAGCombiner that 485 // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'. 486 // Example: (or (and x, 1), (shl y, 3)) --> (add (and x, 1), (shl y, 3)) 487 // An 'lea' can then be used to match the shift (multiply) and add: 488 // and $1, %esi 489 // lea (%rsi, %rdi, 8), %rax 490 if (CurDAG->haveNoCommonBitsSet(N.getOperand(0), N.getOperand(1)) && 491 matchADD(N, AM, Depth)) 492 return true; 493 break; 494 495 case ISD::ADD: 496 if (matchADD(N, AM, Depth)) 497 return true; 498 break; 499 500 case ISD::FrameIndex: 501 if (AM.isDispAddrType() && 502 AM.BaseType == M68kISelAddressMode::Base::RegBase && 503 AM.BaseReg.getNode() == nullptr && doesDispFitFI(AM)) { 504 AM.BaseType = M68kISelAddressMode::Base::FrameIndexBase; 505 AM.BaseFrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 506 return true; 507 } 508 break; 509 510 case ISD::TargetGlobalTLSAddress: { 511 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N); 512 AM.GV = GA->getGlobal(); 513 AM.SymbolFlags = GA->getTargetFlags(); 514 return true; 515 } 516 } 517 518 return matchAddressBase(N, AM); 519 } 520 521 /// Add the specified node to the specified addressing mode, returning true if 522 /// it cannot be done. This just pattern matches for the addressing mode. 523 bool M68kDAGToDAGISel::matchAddress(SDValue N, M68kISelAddressMode &AM) { 524 // TODO: Post-processing: Convert lea(,%reg,2) to lea(%reg,%reg), which has 525 // a smaller encoding and avoids a scaled-index. 526 // And make sure it is an indexed mode 527 528 // TODO: Post-processing: Convert foo to foo(%pc), even in non-PIC mode, 529 // because it has a smaller encoding. 530 // Make sure this must be done only if PC* modes are currently being matched 531 return matchAddressRecursively(N, AM, 0); 532 } 533 534 bool M68kDAGToDAGISel::matchADD(SDValue &N, M68kISelAddressMode &AM, 535 unsigned Depth) { 536 // Add an artificial use to this node so that we can keep track of 537 // it if it gets CSE'd with a different node. 538 HandleSDNode Handle(N); 539 540 M68kISelAddressMode Backup = AM; 541 if (matchAddressRecursively(N.getOperand(0), AM, Depth + 1) && 542 matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth + 1)) { 543 return true; 544 } 545 AM = Backup; 546 547 // Try again after commuting the operands. 548 if (matchAddressRecursively(Handle.getValue().getOperand(1), AM, Depth + 1) && 549 matchAddressRecursively(Handle.getValue().getOperand(0), AM, Depth + 1)) { 550 return true; 551 } 552 AM = Backup; 553 554 // If we couldn't fold both operands into the address at the same time, 555 // see if we can just put each operand into a register and fold at least 556 // the add. 557 if (!AM.hasBase() && !AM.hasIndexReg()) { 558 N = Handle.getValue(); 559 AM.BaseReg = N.getOperand(0); 560 AM.IndexReg = N.getOperand(1); 561 AM.Scale = 1; 562 return true; 563 } 564 565 N = Handle.getValue(); 566 return false; 567 } 568 569 /// Try to match M68kISD::Wrapper and M68kISD::WrapperPC nodes into an 570 /// addressing mode. These wrap things that will resolve down into a symbol 571 /// reference. If no match is possible, this returns true, otherwise it returns 572 /// false. 573 bool M68kDAGToDAGISel::matchWrapper(SDValue N, M68kISelAddressMode &AM) { 574 // If the addressing mode already has a symbol as the displacement, we can 575 // never match another symbol. 576 if (AM.hasSymbolicDisplacement()) 577 return false; 578 579 SDValue N0 = N.getOperand(0); 580 581 if (N.getOpcode() == M68kISD::WrapperPC) { 582 583 // If cannot match here just restore the old version 584 M68kISelAddressMode Backup = AM; 585 586 if (AM.hasBase()) { 587 return false; 588 } 589 590 if (auto *G = dyn_cast<GlobalAddressSDNode>(N0)) { 591 AM.GV = G->getGlobal(); 592 AM.SymbolFlags = G->getTargetFlags(); 593 if (!foldOffsetIntoAddress(G->getOffset(), AM)) { 594 AM = Backup; 595 return false; 596 } 597 } else if (auto *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 598 AM.CP = CP->getConstVal(); 599 AM.Alignment = CP->getAlign(); 600 AM.SymbolFlags = CP->getTargetFlags(); 601 if (!foldOffsetIntoAddress(CP->getOffset(), AM)) { 602 AM = Backup; 603 return false; 604 } 605 } else if (auto *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 606 AM.ES = S->getSymbol(); 607 AM.SymbolFlags = S->getTargetFlags(); 608 } else if (auto *S = dyn_cast<MCSymbolSDNode>(N0)) { 609 AM.MCSym = S->getMCSymbol(); 610 } else if (auto *J = dyn_cast<JumpTableSDNode>(N0)) { 611 AM.JT = J->getIndex(); 612 AM.SymbolFlags = J->getTargetFlags(); 613 } else if (auto *BA = dyn_cast<BlockAddressSDNode>(N0)) { 614 AM.BlockAddr = BA->getBlockAddress(); 615 AM.SymbolFlags = BA->getTargetFlags(); 616 if (!foldOffsetIntoAddress(BA->getOffset(), AM)) { 617 AM = Backup; 618 return false; 619 } 620 } else 621 llvm_unreachable("Unhandled symbol reference node."); 622 623 AM.setBaseReg(CurDAG->getRegister(M68k::PC, MVT::i32)); 624 return true; 625 } 626 627 // This wrapper requires 32bit disp/imm field for Medium CM 628 if (!AM.isDisp32()) { 629 return false; 630 } 631 632 if (N.getOpcode() == M68kISD::Wrapper) { 633 if (auto *G = dyn_cast<GlobalAddressSDNode>(N0)) { 634 AM.GV = G->getGlobal(); 635 AM.Disp += G->getOffset(); 636 AM.SymbolFlags = G->getTargetFlags(); 637 } else if (auto *CP = dyn_cast<ConstantPoolSDNode>(N0)) { 638 AM.CP = CP->getConstVal(); 639 AM.Alignment = CP->getAlign(); 640 AM.Disp += CP->getOffset(); 641 AM.SymbolFlags = CP->getTargetFlags(); 642 } else if (auto *S = dyn_cast<ExternalSymbolSDNode>(N0)) { 643 AM.ES = S->getSymbol(); 644 AM.SymbolFlags = S->getTargetFlags(); 645 } else if (auto *S = dyn_cast<MCSymbolSDNode>(N0)) { 646 AM.MCSym = S->getMCSymbol(); 647 } else if (auto *J = dyn_cast<JumpTableSDNode>(N0)) { 648 AM.JT = J->getIndex(); 649 AM.SymbolFlags = J->getTargetFlags(); 650 } else if (auto *BA = dyn_cast<BlockAddressSDNode>(N0)) { 651 AM.BlockAddr = BA->getBlockAddress(); 652 AM.Disp += BA->getOffset(); 653 AM.SymbolFlags = BA->getTargetFlags(); 654 } else 655 llvm_unreachable("Unhandled symbol reference node."); 656 return true; 657 } 658 659 return false; 660 } 661 662 //===----------------------------------------------------------------------===// 663 // Selectors 664 //===----------------------------------------------------------------------===// 665 666 void M68kDAGToDAGISel::Select(SDNode *Node) { 667 unsigned Opcode = Node->getOpcode(); 668 SDLoc DL(Node); 669 670 LLVM_DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << '\n'); 671 672 if (Node->isMachineOpcode()) { 673 LLVM_DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << '\n'); 674 Node->setNodeId(-1); 675 return; // Already selected. 676 } 677 678 switch (Opcode) { 679 default: 680 break; 681 682 case ISD::GLOBAL_OFFSET_TABLE: { 683 SDValue GOT = CurDAG->getTargetExternalSymbol( 684 "_GLOBAL_OFFSET_TABLE_", MVT::i32, M68kII::MO_GOTPCREL); 685 MachineSDNode *Res = 686 CurDAG->getMachineNode(M68k::LEA32q, DL, MVT::i32, GOT); 687 ReplaceNode(Node, Res); 688 return; 689 } 690 691 case M68kISD::GLOBAL_BASE_REG: 692 ReplaceNode(Node, getGlobalBaseReg()); 693 return; 694 } 695 696 SelectCode(Node); 697 } 698 699 bool M68kDAGToDAGISel::SelectARIPI(SDNode *Parent, SDValue N, SDValue &Base) { 700 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARIPI: "); 701 LLVM_DEBUG(dbgs() << "NOT IMPLEMENTED\n"); 702 return false; 703 } 704 705 bool M68kDAGToDAGISel::SelectARIPD(SDNode *Parent, SDValue N, SDValue &Base) { 706 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARIPD: "); 707 LLVM_DEBUG(dbgs() << "NOT IMPLEMENTED\n"); 708 return false; 709 } 710 711 bool M68kDAGToDAGISel::SelectARID(SDNode *Parent, SDValue N, SDValue &Disp, 712 SDValue &Base) { 713 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARID: "); 714 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARID); 715 716 if (!matchAddress(N, AM)) 717 return false; 718 719 if (AM.isPCRelative()) { 720 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n"); 721 return false; 722 } 723 724 // If this is a frame index, grab it 725 if (getFrameIndexAddress(AM, SDLoc(N), Disp, Base)) { 726 LLVM_DEBUG(dbgs() << "SUCCESS matched FI\n"); 727 return true; 728 } 729 730 if (AM.hasIndexReg()) { 731 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n"); 732 return false; 733 } 734 735 if (!AM.hasBaseReg()) { 736 LLVM_DEBUG(dbgs() << "REJECT: No Base reg\n"); 737 return false; 738 } 739 740 Base = AM.BaseReg; 741 742 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) { 743 assert(!AM.Disp && "Should not be any displacement"); 744 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n"); 745 return true; 746 } 747 748 // Give a chance to AddrType::ARI 749 if (AM.Disp == 0) { 750 LLVM_DEBUG(dbgs() << "REJECT: No displacement\n"); 751 return false; 752 } 753 754 Disp = getI16Imm(AM.Disp, SDLoc(N)); 755 756 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 757 return true; 758 } 759 760 static bool isAddressBase(const SDValue &N) { 761 switch (N.getOpcode()) { 762 case ISD::ADD: 763 case ISD::ADDC: 764 return llvm::any_of(N.getNode()->ops(), 765 [](const SDUse &U) { return isAddressBase(U.get()); }); 766 case M68kISD::Wrapper: 767 case M68kISD::WrapperPC: 768 case M68kISD::GLOBAL_BASE_REG: 769 return true; 770 default: 771 return false; 772 } 773 } 774 775 bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp, 776 SDValue &Base, SDValue &Index) { 777 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARII); 778 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARII: "); 779 780 if (!matchAddress(N, AM)) 781 return false; 782 783 if (AM.isPCRelative()) { 784 LLVM_DEBUG(dbgs() << "REJECT: PC relative\n"); 785 return false; 786 } 787 788 if (!AM.hasIndexReg()) { 789 LLVM_DEBUG(dbgs() << "REJECT: No Index\n"); 790 return false; 791 } 792 793 if (!AM.hasBaseReg()) { 794 LLVM_DEBUG(dbgs() << "REJECT: No Base\n"); 795 return false; 796 } 797 798 if (!isAddressBase(AM.BaseReg) && isAddressBase(AM.IndexReg)) { 799 Base = AM.IndexReg; 800 Index = AM.BaseReg; 801 } else { 802 Base = AM.BaseReg; 803 Index = AM.IndexReg; 804 } 805 806 if (AM.hasSymbolicDisplacement()) { 807 LLVM_DEBUG(dbgs() << "REJECT, Cannot match symbolic displacement\n"); 808 return false; 809 } 810 811 // The idea here is that we want to use AddrType::ARII without displacement 812 // only if necessary like memory operations, otherwise this must be lowered 813 // into addition 814 if (AM.Disp == 0 && (!Parent || (Parent->getOpcode() != ISD::LOAD && 815 Parent->getOpcode() != ISD::STORE))) { 816 LLVM_DEBUG(dbgs() << "REJECT: Displacement is Zero\n"); 817 return false; 818 } 819 820 Disp = getI8Imm(AM.Disp, SDLoc(N)); 821 822 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 823 return true; 824 } 825 826 bool M68kDAGToDAGISel::SelectAL(SDNode *Parent, SDValue N, SDValue &Sym) { 827 LLVM_DEBUG(dbgs() << "Selecting AddrType::AL: "); 828 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::AL); 829 830 if (!matchAddress(N, AM)) { 831 LLVM_DEBUG(dbgs() << "REJECT: Match failed\n"); 832 return false; 833 } 834 835 if (AM.isPCRelative()) { 836 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n"); 837 return false; 838 } 839 840 if (AM.hasBase()) { 841 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Base\n"); 842 return false; 843 } 844 845 if (AM.hasIndexReg()) { 846 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n"); 847 return false; 848 } 849 850 if (getSymbolicDisplacement(AM, SDLoc(N), Sym)) { 851 LLVM_DEBUG(dbgs() << "SUCCESS: Matched symbol\n"); 852 return true; 853 } 854 855 if (AM.Disp) { 856 Sym = getI32Imm(AM.Disp, SDLoc(N)); 857 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 858 return true; 859 } 860 861 LLVM_DEBUG(dbgs() << "REJECT: Not Symbol or Disp\n"); 862 return false; 863 ; 864 } 865 866 bool M68kDAGToDAGISel::SelectPCD(SDNode *Parent, SDValue N, SDValue &Disp) { 867 LLVM_DEBUG(dbgs() << "Selecting AddrType::PCD: "); 868 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCD); 869 870 if (!matchAddress(N, AM)) 871 return false; 872 873 if (!AM.isPCRelative()) { 874 LLVM_DEBUG(dbgs() << "REJECT: Not PC relative\n"); 875 return false; 876 } 877 878 if (AM.hasIndexReg()) { 879 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n"); 880 return false; 881 } 882 883 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) { 884 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n"); 885 return true; 886 } 887 888 Disp = getI16Imm(AM.Disp, SDLoc(N)); 889 890 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 891 return true; 892 } 893 894 bool M68kDAGToDAGISel::SelectPCI(SDNode *Parent, SDValue N, SDValue &Disp, 895 SDValue &Index) { 896 LLVM_DEBUG(dbgs() << "Selecting AddrType::PCI: "); 897 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCI); 898 899 if (!matchAddress(N, AM)) 900 return false; 901 902 if (!AM.isPCRelative()) { 903 LLVM_DEBUG(dbgs() << "REJECT: Not PC relative\n"); 904 return false; 905 } 906 907 if (!AM.hasIndexReg()) { 908 LLVM_DEBUG(dbgs() << "REJECT: No Index\n"); 909 return false; 910 } 911 912 Index = AM.IndexReg; 913 914 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) { 915 assert(!AM.Disp && "Should not be any displacement"); 916 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n"); 917 return true; 918 } 919 920 Disp = getI8Imm(AM.Disp, SDLoc(N)); 921 922 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 923 return true; 924 } 925 926 bool M68kDAGToDAGISel::SelectARI(SDNode *Parent, SDValue N, SDValue &Base) { 927 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARI: "); 928 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARI); 929 930 if (!matchAddress(N, AM)) { 931 LLVM_DEBUG(dbgs() << "REJECT: Match failed\n"); 932 return false; 933 } 934 935 if (AM.isPCRelative()) { 936 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n"); 937 return false; 938 } 939 940 // AddrType::ARI does not use these 941 if (AM.hasIndexReg() || AM.Disp != 0) { 942 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index or Disp\n"); 943 return false; 944 } 945 946 // Must be matched by AddrType::AL 947 if (AM.hasSymbolicDisplacement()) { 948 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Symbolic Disp\n"); 949 return false; 950 } 951 952 if (AM.hasBaseReg()) { 953 Base = AM.BaseReg; 954 LLVM_DEBUG(dbgs() << "SUCCESS\n"); 955 return true; 956 } 957 958 return false; 959 } 960 961 bool M68kDAGToDAGISel::SelectInlineAsmMemoryOperand( 962 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, 963 std::vector<SDValue> &OutOps) { 964 // In order to tell AsmPrinter the exact addressing mode we select here, which 965 // might comprise of multiple SDValues (hence MachineOperands), a 32-bit 966 // immediate value is prepended to the list of selected SDValues to indicate 967 // the addressing mode kind. 968 using AMK = M68k::MemAddrModeKind; 969 auto addKind = [this](SDValue &Opnd, AMK Kind) -> bool { 970 Opnd = CurDAG->getTargetConstant(unsigned(Kind), SDLoc(), MVT::i32); 971 return true; 972 }; 973 974 switch (ConstraintID) { 975 // Generic memory operand. 976 case InlineAsm::ConstraintCode::m: { 977 // Try every supported (memory) addressing modes. 978 SDValue Operands[4]; 979 980 // TODO: The ordering of the following SelectXXX is relatively...arbitrary, 981 // right now we simply sort them by descending complexity. Maybe we should 982 // adjust this by code model and/or relocation mode in the future. 983 if (SelectARII(nullptr, Op, Operands[1], Operands[2], Operands[3]) && 984 addKind(Operands[0], AMK::f)) { 985 OutOps.insert(OutOps.end(), &Operands[0], Operands + 4); 986 return false; 987 } 988 989 if ((SelectPCI(nullptr, Op, Operands[1], Operands[2]) && 990 addKind(Operands[0], AMK::k)) || 991 (SelectARID(nullptr, Op, Operands[1], Operands[2]) && 992 addKind(Operands[0], AMK::p))) { 993 OutOps.insert(OutOps.end(), &Operands[0], Operands + 3); 994 return false; 995 } 996 997 if ((SelectPCD(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::q)) || 998 (SelectARI(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::j)) || 999 (SelectAL(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::b))) { 1000 OutOps.insert(OutOps.end(), {Operands[0], Operands[1]}); 1001 return false; 1002 } 1003 1004 return true; 1005 } 1006 // 'Q': Address register indirect addressing. 1007 case InlineAsm::ConstraintCode::Q: { 1008 SDValue AMKind, Base; 1009 // 'j' addressing mode. 1010 // TODO: Add support for 'o' and 'e' after their 1011 // select functions are implemented. 1012 if (SelectARI(nullptr, Op, Base) && addKind(AMKind, AMK::j)) { 1013 OutOps.insert(OutOps.end(), {AMKind, Base}); 1014 return false; 1015 } 1016 return true; 1017 } 1018 // 'U': Address register indirect w/ constant offset addressing. 1019 case InlineAsm::ConstraintCode::Um: { 1020 SDValue AMKind, Base, Offset; 1021 // 'p' addressing mode. 1022 if (SelectARID(nullptr, Op, Offset, Base) && addKind(AMKind, AMK::p)) { 1023 OutOps.insert(OutOps.end(), {AMKind, Offset, Base}); 1024 return false; 1025 } 1026 return true; 1027 } 1028 default: 1029 return true; 1030 } 1031 } 1032