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) {
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)) &&
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.