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