LLVM: lib/Target/M68k/M68kISelDAGToDAG.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

38

39using namespace llvm;

40

41#define DEBUG_TYPE "m68k-isel"

42#define PASS_NAME "M68k DAG->DAG Pattern Instruction Selection"

43

44namespace {

45

46

47

48struct M68kISelAddressMode {

49 enum class AddrType {

50 ARI,

51 ARIPI,

52 ARIPD,

53 ARID,

54 ARII,

55 PCD,

56 PCI,

57 AL,

58 };

59 AddrType AM;

60

61 enum class Base { RegBase, FrameIndexBase };

63

64 int64_t Disp;

65

66

68 int BaseFrameIndex;

69

71 unsigned Scale;

72

76 const char *ES;

78 int JT;

79 Align Alignment;

80

81 unsigned char SymbolFlags;

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

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

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

135 bool isPCRelative() const {

136 if (BaseType != Base::RegBase)

137 return false;

139 return RegNode->getReg() == M68k::PC;

140 return false;

141 }

142

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()) {

163 } else {

164 dbgs() << "null";

165 dbgs() << ", Scale: " << Scale;

166 }

167 dbgs() << '\n';

168 }

169#endif

170};

171}

172

173namespace {

174

176public:

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

185private:

186

187

188 const M68kSubtarget *Subtarget;

189

190

191#include "M68kGenDAGISel.inc"

192

193

194

195 const M68kTargetMachine &getTargetMachine() {

196 return static_cast<const M68kTargetMachine &>(TM);

197 }

198

199 void Select(SDNode *N) override;

200

201

202

203

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,

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

227

228 bool SelectInlineAsmMemoryOperand(const SDValue &Op,

230 std::vector &OutOps) override;

231

232

233

234

235 inline bool getFrameIndexAddress(M68kISelAddressMode &AM, const SDLoc &DL,

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

248 inline bool getSymbolicDisplacement(M68kISelAddressMode &AM, const SDLoc &DL,

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

291 inline SDValue getI8Imm(int64_t Imm, const SDLoc &DL) {

292 return CurDAG->getSignedTargetConstant(Imm, DL, MVT::i8);

293 }

294

295

296 inline SDValue getI16Imm(int64_t Imm, const SDLoc &DL) {

297 return CurDAG->getSignedTargetConstant(Imm, DL, MVT::i16);

298 }

299

300

301 inline SDValue getI32Imm(int64_t Imm, const SDLoc &DL) {

302 return CurDAG->getSignedTargetConstant(Imm, DL, MVT::i32);

303 }

304

305

306

307 const M68kInstrInfo *getInstrInfo() const {

308 return Subtarget->getInstrInfo();

309 }

310

311

312

313

314 SDNode *getGlobalBaseReg();

315};

316

318public:

319 static char ID;

320 explicit M68kDAGToDAGISelLegacy(M68kTargetMachine &TM)

321 : SelectionDAGISelLegacy(ID, std::make_unique(TM)) {}

322};

323

324char M68kDAGToDAGISelLegacy::ID;

325

326}

327

329

331 SDNode *Root) const {

333 return false;

334

335 if (U == Root) {

336 switch (U->getOpcode()) {

337 default:

338 return true;

339 case M68kISD::SUB:

341

342

343

344

345

346

347

349 return false;

350 break;

351 }

352 }

353

354 return true;

355}

356

357bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {

358 Subtarget = &MF.getSubtarget();

360}

361

362

363

365 return new M68kDAGToDAGISelLegacy(TM);

366}

367

369 if (!AM.isDispAddrType())

370 return false;

371

372 return isIntN(AM.getDispSize() - 1, AM.Disp);

373}

374

375static bool doesDispFit(M68kISelAddressMode &AM, int64_t Val) {

376 if (!AM.isDispAddrType())

377 return false;

378 return isIntN(AM.getDispSize(), Val);

379}

380

381

382

383

384SDNode *M68kDAGToDAGISel::getGlobalBaseReg() {

385 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);

386 auto &DL = MF->getDataLayout();

387 return CurDAG->getRegister(GlobalBaseReg, TLI->getPointerTy(DL)).getNode();

388}

389

390bool M68kDAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset,

391 M68kISelAddressMode &AM) {

392

393 if (Offset != 0 && (AM.ES || AM.MCSym))

394 return false;

395

396 int64_t Val = AM.Disp + Offset;

397

399 AM.Disp = Val;

400 return true;

401 }

402

403 return false;

404}

405

406

407

408

409

410

411

412bool M68kDAGToDAGISel::matchAddressBase(SDValue N, M68kISelAddressMode &AM) {

413

414 if (AM.hasBase()) {

415

416 if (!AM.hasIndexReg()) {

417 AM.IndexReg = N;

418 AM.Scale = 1;

419 return true;

420 }

421

422

423 return false;

424 }

425

426

427 AM.BaseType = M68kISelAddressMode::Base::RegBase;

428 AM.BaseReg = N;

429 return true;

430}

431

432

433bool M68kDAGToDAGISel::matchLoadInAddress(LoadSDNode *N,

434 M68kISelAddressMode &AM) {

435 return false;

436}

437

438bool M68kDAGToDAGISel::matchAddressRecursively(SDValue N,

439 M68kISelAddressMode &AM,

440 unsigned Depth) {

441 SDLoc DL(N);

442

443

445 return matchAddressBase(N, AM);

446

447

448

449

450 if (AM.isPCRelative()) {

451

452

453

454

456 if (foldOffsetIntoAddress(Cst->getSExtValue(), AM))

457 return true;

458 return false;

459 }

460

461 switch (N.getOpcode()) {

462 default:

463 break;

464

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:

480 return true;

481 break;

482

484

485

486

487

488

489

490 if (CurDAG->haveNoCommonBitsSet(N.getOperand(0), N.getOperand(1)) &&

491 matchADD(N, AM, Depth))

492 return true;

493 break;

494

496 if (matchADD(N, AM, Depth))

497 return true;

498 break;

499

501 if (AM.isDispAddrType() &&

502 AM.BaseType == M68kISelAddressMode::Base::RegBase &&

504 AM.BaseType = M68kISelAddressMode::Base::FrameIndexBase;

506 return true;

507 }

508 break;

509

514 return true;

515 }

516 }

517

518 return matchAddressBase(N, AM);

519}

520

521

522

523bool M68kDAGToDAGISel::matchAddress(SDValue N, M68kISelAddressMode &AM) {

524

525

526

527

528

529

530

531 return matchAddressRecursively(N, AM, 0);

532}

533

534bool M68kDAGToDAGISel::matchADD(SDValue &N, M68kISelAddressMode &AM,

535 unsigned Depth) {

536

537

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

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

555

556

557 if (!AM.hasBase() && !AM.hasIndexReg()) {

558 N = Handle.getValue();

561 AM.Scale = 1;

562 return true;

563 }

564

565 N = Handle.getValue();

566 return false;

567}

568

569

570

571

572

573bool M68kDAGToDAGISel::matchWrapper(SDValue N, M68kISelAddressMode &AM) {

574

575

576 if (AM.hasSymbolicDisplacement())

577 return false;

578

579 SDValue N0 = N.getOperand(0);

580

581 if (N.getOpcode() == M68kISD::WrapperPC) {

582

583

584 M68kISelAddressMode Backup = AM;

585

586 if (AM.hasBase()) {

587 return false;

588 }

589

591 AM.GV = G->getGlobal();

592 AM.SymbolFlags = G->getTargetFlags();

593 if (!foldOffsetIntoAddress(G->getOffset(), AM)) {

594 AM = Backup;

595 return false;

596 }

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 }

606 AM.ES = S->getSymbol();

607 AM.SymbolFlags = S->getTargetFlags();

609 AM.MCSym = S->getMCSymbol();

611 AM.JT = J->getIndex();

612 AM.SymbolFlags = J->getTargetFlags();

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

622

623 AM.setBaseReg(CurDAG->getRegister(M68k::PC, MVT::i32));

624 return true;

625 }

626

627

628 if (!AM.isDisp32()) {

629 return false;

630 }

631

632 if (N.getOpcode() == M68kISD::Wrapper) {

634 AM.GV = G->getGlobal();

635 AM.Disp += G->getOffset();

636 AM.SymbolFlags = G->getTargetFlags();

638 AM.CP = CP->getConstVal();

639 AM.Alignment = CP->getAlign();

640 AM.Disp += CP->getOffset();

641 AM.SymbolFlags = CP->getTargetFlags();

643 AM.ES = S->getSymbol();

644 AM.SymbolFlags = S->getTargetFlags();

646 AM.MCSym = S->getMCSymbol();

648 AM.JT = J->getIndex();

649 AM.SymbolFlags = J->getTargetFlags();

651 AM.BlockAddr = BA->getBlockAddress();

652 AM.Disp += BA->getOffset();

653 AM.SymbolFlags = BA->getTargetFlags();

654 } else

656 return true;

657 }

658

659 return false;

660}

661

662

663

664

665

666void M68kDAGToDAGISel::Select(SDNode *Node) {

667 unsigned Opcode = Node->getOpcode();

668 SDLoc DL(Node);

669

671

672 if (Node->isMachineOpcode()) {

674 Node->setNodeId(-1);

675 return;

676 }

677

678 switch (Opcode) {

679 default:

680 break;

681

683 SDValue GOT = CurDAG->getTargetExternalSymbol(

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

699bool M68kDAGToDAGISel::SelectARIPI(SDNode *Parent, SDValue N, SDValue &Base) {

702 return false;

703}

704

705bool M68kDAGToDAGISel::SelectARIPD(SDNode *Parent, SDValue N, SDValue &Base) {

708 return false;

709}

710

712 if (!Parent)

713 return false;

715 case ISD::LOAD:

716 case ISD::STORE:

717 case ISD::ATOMIC_LOAD:

718 case ISD::ATOMIC_STORE:

719 return true;

720 default:

721 return false;

722 }

723}

724

725bool M68kDAGToDAGISel::SelectARID(SDNode *Parent, SDValue N, SDValue &Disp,

728 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARID);

729

730 if (!matchAddress(N, AM))

731 return false;

732

733 if (AM.isPCRelative()) {

734 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");

735 return false;

736 }

737

738

739 if (getFrameIndexAddress(AM, SDLoc(N), Disp, Base)) {

741 return true;

742 }

743

744 if (AM.hasIndexReg()) {

745 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");

746 return false;

747 }

748

749 if (!AM.hasBaseReg()) {

751 return false;

752 }

753

754 Base = AM.BaseReg;

755

756 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) {

758 "Should not be any displacement");

760 return true;

761 }

762

763

764 if (AM.Disp == 0) {

766 return false;

767 }

768

769 Disp = getI16Imm(AM.Disp, SDLoc(N));

770

772 return true;

773}

774

776 switch (N.getOpcode()) {

780 [](const SDUse &U) { return isAddressBase(U.get()); });

781 case M68kISD::Wrapper:

782 case M68kISD::WrapperPC:

783 case M68kISD::GLOBAL_BASE_REG:

784 return true;

785 default:

786 return false;

787 }

788}

789

791 if (!Parent)

792 return false;

794 case ISD::LOAD:

795 case ISD::STORE:

796 case ISD::ATOMIC_LOAD:

797 case ISD::ATOMIC_STORE:

798 case ISD::ATOMIC_CMP_SWAP:

799 return true;

800 default:

801 return false;

802 }

803}

804

805bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp,

807 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARII);

809

810 if (!matchAddress(N, AM))

811 return false;

812

813 if (AM.isPCRelative()) {

815 return false;

816 }

817

818 if (!AM.hasIndexReg()) {

820 return false;

821 }

822

823 if (!AM.hasBaseReg()) {

825 return false;

826 }

827

829 Base = AM.IndexReg;

830 Index = AM.BaseReg;

831 } else {

832 Base = AM.BaseReg;

833 Index = AM.IndexReg;

834 }

835

836 if (AM.hasSymbolicDisplacement()) {

837 LLVM_DEBUG(dbgs() << "REJECT, Cannot match symbolic displacement\n");

838 return false;

839 }

840

841

842

843

845 LLVM_DEBUG(dbgs() << "REJECT: Displacement is Zero\n");

846 return false;

847 }

848

849 Disp = getI8Imm(AM.Disp, SDLoc(N));

850

852 return true;

853}

854

855bool M68kDAGToDAGISel::SelectAL(SDNode *Parent, SDValue N, SDValue &Sym) {

857 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::AL);

858

859 if (!matchAddress(N, AM)) {

861 return false;

862 }

863

864 if (AM.isPCRelative()) {

865 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");

866 return false;

867 }

868

869 if (AM.hasBase()) {

871 return false;

872 }

873

874 if (AM.hasIndexReg()) {

875 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");

876 return false;

877 }

878

879 if (getSymbolicDisplacement(AM, SDLoc(N), Sym)) {

881 return true;

882 }

883

884 if (AM.Disp) {

885 Sym = getI32Imm(AM.Disp, SDLoc(N));

887 return true;

888 }

889

890 LLVM_DEBUG(dbgs() << "REJECT: Not Symbol or Disp\n");

891 return false;

892 ;

893}

894

895bool M68kDAGToDAGISel::SelectPCD(SDNode *Parent, SDValue N, SDValue &Disp) {

897 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCD);

898

899 if (!matchAddress(N, AM))

900 return false;

901

902 if (!AM.isPCRelative()) {

904 return false;

905 }

906

907 if (AM.hasIndexReg()) {

908 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");

909 return false;

910 }

911

912 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) {

914 return true;

915 }

916

917 Disp = getI16Imm(AM.Disp, SDLoc(N));

918

920 return true;

921}

922

923bool M68kDAGToDAGISel::SelectPCI(SDNode *Parent, SDValue N, SDValue &Disp,

926 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCI);

927

928 if (!matchAddress(N, AM))

929 return false;

930

931 if (!AM.isPCRelative()) {

933 return false;

934 }

935

936 if (!AM.hasIndexReg()) {

938 return false;

939 }

940

941 Index = AM.IndexReg;

942

943 if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) {

944 assert(!AM.Disp && "Should not be any displacement");

946 return true;

947 }

948

949 Disp = getI8Imm(AM.Disp, SDLoc(N));

950

952 return true;

953}

954

955bool M68kDAGToDAGISel::SelectARI(SDNode *Parent, SDValue N, SDValue &Base) {

957 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARI);

958

959 if (!matchAddress(N, AM)) {

961 return false;

962 }

963

964 if (AM.isPCRelative()) {

965 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");

966 return false;

967 }

968

969

970 if (AM.hasIndexReg() || AM.Disp != 0) {

971 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index or Disp\n");

972 return false;

973 }

974

975

976 if (AM.hasSymbolicDisplacement()) {

977 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Symbolic Disp\n");

978 return false;

979 }

980

981 if (AM.hasBaseReg()) {

982 Base = AM.BaseReg;

984 return true;

985 }

986

987 return false;

988}

989

990bool M68kDAGToDAGISel::SelectInlineAsmMemoryOperand(

992 std::vector &OutOps) {

993

994

995

996

998 auto addKind = [this](SDValue &Opnd, AMK Kind) -> bool {

999 Opnd = CurDAG->getTargetConstant(unsigned(Kind), SDLoc(), MVT::i32);

1000 return true;

1001 };

1002

1003 switch (ConstraintID) {

1004

1005 case InlineAsm::ConstraintCode::m: {

1006

1008

1009

1010

1011

1012 if (SelectARII(nullptr, Op, Operands[1], Operands[2], Operands[3]) &&

1013 addKind(Operands[0], AMK::f)) {

1014 OutOps.insert(OutOps.end(), &Operands[0], Operands + 4);

1015 return false;

1016 }

1017

1018 if ((SelectPCI(nullptr, Op, Operands[1], Operands[2]) &&

1019 addKind(Operands[0], AMK::k)) ||

1020 (SelectARID(nullptr, Op, Operands[1], Operands[2]) &&

1021 addKind(Operands[0], AMK::p))) {

1022 OutOps.insert(OutOps.end(), &Operands[0], Operands + 3);

1023 return false;

1024 }

1025

1026 if ((SelectPCD(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::q)) ||

1027 (SelectARI(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::j)) ||

1028 (SelectAL(nullptr, Op, Operands[1]) && addKind(Operands[0], AMK::b))) {

1029 OutOps.insert(OutOps.end(), {Operands[0], Operands[1]});

1030 return false;

1031 }

1032

1033 return true;

1034 }

1035

1036 case InlineAsm::ConstraintCode::Q: {

1038

1039

1040

1041 if (SelectARI(nullptr, Op, Base) && addKind(AMKind, AMK::j)) {

1042 OutOps.insert(OutOps.end(), {AMKind, Base});

1043 return false;

1044 }

1045 return true;

1046 }

1047

1048 case InlineAsm::ConstraintCode::Um: {

1050

1051 if (SelectARID(nullptr, Op, Offset, Base) && addKind(AMKind, AMK::p)) {

1052 OutOps.insert(OutOps.end(), {AMKind, Offset, Base});

1053 return false;

1054 }

1055 return true;

1056 }

1057 default:

1058 return true;

1059 }

1060}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU Register Bank Select

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file provides various utilities for inspecting and working with the control flow graph in LLVM I...

static bool doesDispFit(M68kISelAddressMode &AM, int64_t Val)

Definition M68kISelDAGToDAG.cpp:375

static bool allowARIDWithDisp(SDNode *Parent)

Definition M68kISelDAGToDAG.cpp:711

static bool doesDispFitFI(M68kISelAddressMode &AM)

Definition M68kISelDAGToDAG.cpp:368

static bool isAddressBase(const SDValue &N)

Definition M68kISelDAGToDAG.cpp:775

static bool AllowARIIWithZeroDisp(SDNode *Parent)

Definition M68kISelDAGToDAG.cpp:790

This file declares the M68k specific subclass of MachineFunctionInfo.

This file contains the M68k implementation of the TargetRegisterInfo class.

This file declares the M68k specific subclass of TargetMachine.

This file contains the entry points for global functions defined in the M68k target library,...

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

BaseType

A given derived pointer can have multiple base pointers through phi/selects.

The address of a basic block.

This is an important base class in LLVM.

FunctionPass class - This class is used to implement most global optimizations.

unsigned getTargetFlags() const

const GlobalValue * getGlobal() const

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

Represents one node in the SelectionDAG.

LLVM_ABI void dump() const

Dump this node, for debugging.

unsigned getOpcode() const

Return the SelectionDAG opcode value for this node.

Represents a use of a SDNode.

Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.

SDNode * getNode() const

get the SDNode which holds the desired result

const SDValue & getOperand(unsigned i) const

SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...

virtual bool runOnMachineFunction(MachineFunction &mf)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ ADDC

Carry-setting nodes for multiple precision addition and subtraction.

@ ADD

Simple integer binary arithmetic operators.

@ GLOBAL_OFFSET_TABLE

The address of the GOT.

@ MO_GOTPCREL

On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...

@ GlobalBaseReg

The result of the mflr at function entry, used for PIC code.

NodeAddr< NodeBase * > Node

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

LLVM_ABI bool isNullConstant(SDValue V)

Returns true if V is a constant integer zero.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto dyn_cast_or_null(const Y &Val)

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

FunctionPass * createM68kISelDag(M68kTargetMachine &TM)

This pass converts a legalized DAG into a M68k-specific DAG, ready for instruction scheduling.

Definition M68kISelDAGToDAG.cpp:364

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

This struct is a compact representation of a valid (non-zero power of two) alignment.