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