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