1 //===- M68kISelDAGToDAG.cpp - M68k Dag to Dag Inst Selector -*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file defines an instruction selector for the M68K target.
12 //===----------------------------------------------------------------------===//
16 #include "M68kMachineFunction.h"
17 #include "M68kRegisterInfo.h"
18 #include "M68kTargetMachine.h"
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"
41 #define DEBUG_TYPE "m68k-isel"
45 // For reference, the full order of operands for memory references is:
46 // (Operand), Displacement, Base, Index, Scale
47 struct M68kISelAddressMode
{
49 ARI
, // Address Register Indirect
50 ARIPI
, // Address Register Indirect with Postincrement
51 ARIPD
, // Address Register Indirect with Postdecrement
52 ARID
, // Address Register Indirect with Displacement
53 ARII
, // Address Register Indirect with Index
54 PCD
, // Program Counter Indirect with Displacement
55 PCI
, // Program Counter Indirect with Index
60 enum class Base
{ RegBase
, FrameIndexBase
};
65 // This is really a union, discriminated by BaseType!
72 const GlobalValue
*GV
;
74 const BlockAddress
*BlockAddr
;
78 Align Alignment
; // CP alignment.
80 unsigned char SymbolFlags
; // M68kII::MO_*
82 M68kISelAddressMode(AddrType AT
)
83 : AM(AT
), BaseType(Base::RegBase
), Disp(0), BaseFrameIndex(0), IndexReg(),
84 Scale(1), GV(nullptr), CP(nullptr), BlockAddr(nullptr), ES(nullptr),
85 MCSym(nullptr), JT(-1), Alignment(), SymbolFlags(M68kII::MO_NO_FLAG
) {}
87 bool hasSymbolicDisplacement() const {
88 return GV
!= nullptr || CP
!= nullptr || ES
!= nullptr ||
89 MCSym
!= nullptr || JT
!= -1 || BlockAddr
!= nullptr;
92 bool hasBase() const {
93 return BaseType
== Base::FrameIndexBase
|| BaseReg
.getNode() != nullptr;
96 bool hasFrameIndex() const { return BaseType
== Base::FrameIndexBase
; }
98 bool hasBaseReg() const {
99 return BaseType
== Base::RegBase
&& BaseReg
.getNode() != nullptr;
102 bool hasIndexReg() const {
103 return BaseType
== Base::RegBase
&& IndexReg
.getNode() != nullptr;
106 /// True if address mode type supports displacement
107 bool isDispAddrType() const {
108 return AM
== AddrType::ARII
|| AM
== AddrType::PCI
||
109 AM
== AddrType::ARID
|| AM
== AddrType::PCD
|| AM
== AddrType::AL
;
112 unsigned getDispSize() const {
119 // These two in the next chip generations can hold upto 32 bit
128 bool hasDisp() const { return getDispSize() != 0; }
129 bool isDisp8() const { return getDispSize() == 8; }
130 bool isDisp16() const { return getDispSize() == 16; }
131 bool isDisp32() const { return getDispSize() == 32; }
133 /// Return true if this addressing mode is already PC-relative.
134 bool isPCRelative() const {
135 if (BaseType
!= Base::RegBase
)
137 if (auto *RegNode
= dyn_cast_or_null
<RegisterSDNode
>(BaseReg
.getNode()))
138 return RegNode
->getReg() == M68k::PC
;
142 void setBaseReg(SDValue Reg
) {
143 BaseType
= Base::RegBase
;
147 void setIndexReg(SDValue Reg
) { IndexReg
= Reg
; }
149 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
151 dbgs() << "M68kISelAddressMode " << this;
152 dbgs() << "\nDisp: " << Disp
;
153 dbgs() << ", BaseReg: ";
154 if (BaseReg
.getNode())
155 BaseReg
.getNode()->dump();
158 dbgs() << ", BaseFI: " << BaseFrameIndex
;
159 dbgs() << ", IndexReg: ";
160 if (IndexReg
.getNode()) {
161 IndexReg
.getNode()->dump();
164 dbgs() << ", Scale: " << Scale
;
170 } // end anonymous namespace
174 class M68kDAGToDAGISel
: public SelectionDAGISel
{
176 explicit M68kDAGToDAGISel(M68kTargetMachine
&TM
)
177 : SelectionDAGISel(TM
), Subtarget(nullptr) {}
179 StringRef
getPassName() const override
{
180 return "M68k DAG->DAG Pattern Instruction Selection";
183 bool runOnMachineFunction(MachineFunction
&MF
) override
;
186 /// Keep a pointer to the M68kSubtarget around so that we can
187 /// make the right decision when generating code for different targets.
188 const M68kSubtarget
*Subtarget
;
190 // Include the pieces autogenerated from the target description.
191 #include "M68kGenDAGISel.inc"
193 /// getTargetMachine - Return a reference to the TargetMachine, casted
194 /// to the target-specific type.
195 const M68kTargetMachine
&getTargetMachine() {
196 return static_cast<const M68kTargetMachine
&>(TM
);
199 void Select(SDNode
*N
) override
;
201 // Insert instructions to initialize the global base register in the
202 // first MBB of the function.
203 // HMM... do i need this?
204 void initGlobalBaseReg(MachineFunction
&MF
);
206 bool foldOffsetIntoAddress(uint64_t Offset
, M68kISelAddressMode
&AM
);
208 bool matchLoadInAddress(LoadSDNode
*N
, M68kISelAddressMode
&AM
);
209 bool matchAddress(SDValue N
, M68kISelAddressMode
&AM
);
210 bool matchAddressBase(SDValue N
, M68kISelAddressMode
&AM
);
211 bool matchAddressRecursively(SDValue N
, M68kISelAddressMode
&AM
,
213 bool matchADD(SDValue
&N
, M68kISelAddressMode
&AM
, unsigned Depth
);
214 bool matchWrapper(SDValue N
, M68kISelAddressMode
&AM
);
216 std::pair
<bool, SDNode
*> selectNode(SDNode
*Node
);
218 bool SelectARI(SDNode
*Parent
, SDValue N
, SDValue
&Base
);
219 bool SelectARIPI(SDNode
*Parent
, SDValue N
, SDValue
&Base
);
220 bool SelectARIPD(SDNode
*Parent
, SDValue N
, SDValue
&Base
);
221 bool SelectARID(SDNode
*Parent
, SDValue N
, SDValue
&Imm
, SDValue
&Base
);
222 bool SelectARII(SDNode
*Parent
, SDValue N
, SDValue
&Imm
, SDValue
&Base
,
224 bool SelectAL(SDNode
*Parent
, SDValue N
, SDValue
&Sym
);
225 bool SelectPCD(SDNode
*Parent
, SDValue N
, SDValue
&Imm
);
226 bool SelectPCI(SDNode
*Parent
, SDValue N
, SDValue
&Imm
, SDValue
&Index
);
228 // If Address Mode represents Frame Index store FI in Disp and
229 // Displacement bit size in Base. These values are read symmetrically by
230 // M68kRegisterInfo::eliminateFrameIndex method
231 inline bool getFrameIndexAddress(M68kISelAddressMode
&AM
, const SDLoc
&DL
,
232 SDValue
&Disp
, SDValue
&Base
) {
233 if (AM
.BaseType
== M68kISelAddressMode::Base::FrameIndexBase
) {
234 Disp
= getI32Imm(AM
.Disp
, DL
);
235 Base
= CurDAG
->getTargetFrameIndex(
236 AM
.BaseFrameIndex
, TLI
->getPointerTy(CurDAG
->getDataLayout()));
243 // Gets a symbol plus optional displacement
244 inline bool getSymbolicDisplacement(M68kISelAddressMode
&AM
, const SDLoc
&DL
,
247 Sym
= CurDAG
->getTargetGlobalAddress(AM
.GV
, SDLoc(), MVT::i32
, AM
.Disp
,
253 Sym
= CurDAG
->getTargetConstantPool(AM
.CP
, MVT::i32
, AM
.Alignment
,
254 AM
.Disp
, AM
.SymbolFlags
);
259 assert(!AM
.Disp
&& "Non-zero displacement is ignored with ES.");
260 Sym
= CurDAG
->getTargetExternalSymbol(AM
.ES
, MVT::i32
, AM
.SymbolFlags
);
265 assert(!AM
.Disp
&& "Non-zero displacement is ignored with MCSym.");
266 assert(AM
.SymbolFlags
== 0 && "oo");
267 Sym
= CurDAG
->getMCSymbol(AM
.MCSym
, MVT::i32
);
272 assert(!AM
.Disp
&& "Non-zero displacement is ignored with JT.");
273 Sym
= CurDAG
->getTargetJumpTable(AM
.JT
, MVT::i32
, AM
.SymbolFlags
);
278 Sym
= CurDAG
->getTargetBlockAddress(AM
.BlockAddr
, MVT::i32
, AM
.Disp
,
286 /// Return a target constant with the specified value of type i8.
287 inline SDValue
getI8Imm(int64_t Imm
, const SDLoc
&DL
) {
288 return CurDAG
->getTargetConstant(Imm
, DL
, MVT::i8
);
291 /// Return a target constant with the specified value of type i8.
292 inline SDValue
getI16Imm(int64_t Imm
, const SDLoc
&DL
) {
293 return CurDAG
->getTargetConstant(Imm
, DL
, MVT::i16
);
296 /// Return a target constant with the specified value, of type i32.
297 inline SDValue
getI32Imm(int64_t Imm
, const SDLoc
&DL
) {
298 return CurDAG
->getTargetConstant(Imm
, DL
, MVT::i32
);
301 /// Return a reference to the TargetInstrInfo, casted to the target-specific
303 const M68kInstrInfo
*getInstrInfo() const {
304 return Subtarget
->getInstrInfo();
307 /// Return an SDNode that returns the value of the global base register.
308 /// Output instructions required to initialize the global base register,
310 SDNode
*getGlobalBaseReg();
314 bool M68kDAGToDAGISel::runOnMachineFunction(MachineFunction
&MF
) {
315 Subtarget
= &static_cast<const M68kSubtarget
&>(MF
.getSubtarget());
316 return SelectionDAGISel::runOnMachineFunction(MF
);
319 /// This pass converts a legalized DAG into a M68k-specific DAG,
320 /// ready for instruction scheduling.
321 FunctionPass
*llvm::createM68kISelDag(M68kTargetMachine
&TM
) {
322 return new M68kDAGToDAGISel(TM
);
325 static bool doesDispFitFI(M68kISelAddressMode
&AM
) {
326 if (!AM
.isDispAddrType())
328 // -1 to make sure that resolved FI will fit into Disp field
329 return isIntN(AM
.getDispSize() - 1, AM
.Disp
);
332 static bool doesDispFit(M68kISelAddressMode
&AM
, int64_t Val
) {
333 if (!AM
.isDispAddrType())
335 return isIntN(AM
.getDispSize(), Val
);
338 /// Return an SDNode that returns the value of the global base register.
339 /// Output instructions required to initialize the global base register,
341 SDNode
*M68kDAGToDAGISel::getGlobalBaseReg() {
342 unsigned GlobalBaseReg
= getInstrInfo()->getGlobalBaseReg(MF
);
343 auto &DL
= MF
->getDataLayout();
344 return CurDAG
->getRegister(GlobalBaseReg
, TLI
->getPointerTy(DL
)).getNode();
347 bool M68kDAGToDAGISel::foldOffsetIntoAddress(uint64_t Offset
,
348 M68kISelAddressMode
&AM
) {
349 // Cannot combine ExternalSymbol displacements with integer offsets.
350 if (Offset
!= 0 && (AM
.ES
|| AM
.MCSym
))
353 int64_t Val
= AM
.Disp
+ Offset
;
355 if (doesDispFit(AM
, Val
)) {
363 //===----------------------------------------------------------------------===//
365 //===----------------------------------------------------------------------===//
367 /// Helper for MatchAddress. Add the specified node to the
368 /// specified addressing mode without any further recursion.
369 bool M68kDAGToDAGISel::matchAddressBase(SDValue N
, M68kISelAddressMode
&AM
) {
370 // Is the base register already occupied?
372 // If so, check to see if the scale index register is set.
373 if (!AM
.hasIndexReg()) {
379 // Otherwise, we cannot select it.
383 // Default, generate it as a register.
384 AM
.BaseType
= M68kISelAddressMode::Base::RegBase
;
389 /// TODO Add TLS support
390 bool M68kDAGToDAGISel::matchLoadInAddress(LoadSDNode
*N
,
391 M68kISelAddressMode
&AM
) {
395 bool M68kDAGToDAGISel::matchAddressRecursively(SDValue N
,
396 M68kISelAddressMode
&AM
,
402 return matchAddressBase(N
, AM
);
404 // If this is already a %PC relative address, we can only merge immediates
405 // into it. Instead of handling this in every case, we handle it here.
406 // PC relative addressing: %PC + 16-bit displacement!
407 if (AM
.isPCRelative()) {
408 // FIXME JumpTable and ExternalSymbol address currently don't like
409 // displacements. It isn't very important, but should be fixed for
412 if (ConstantSDNode
*Cst
= dyn_cast
<ConstantSDNode
>(N
))
413 if (foldOffsetIntoAddress(Cst
->getSExtValue(), AM
))
418 switch (N
.getOpcode()) {
422 case ISD::Constant
: {
423 uint64_t Val
= cast
<ConstantSDNode
>(N
)->getSExtValue();
424 if (foldOffsetIntoAddress(Val
, AM
))
429 case M68kISD::Wrapper
:
430 case M68kISD::WrapperPC
:
431 if (matchWrapper(N
, AM
))
436 if (matchLoadInAddress(cast
<LoadSDNode
>(N
), AM
))
441 // We want to look through a transform in InstCombine and DAGCombiner that
442 // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
443 // Example: (or (and x, 1), (shl y, 3)) --> (add (and x, 1), (shl y, 3))
444 // An 'lea' can then be used to match the shift (multiply) and add:
446 // lea (%rsi, %rdi, 8), %rax
447 if (CurDAG
->haveNoCommonBitsSet(N
.getOperand(0), N
.getOperand(1)) &&
448 matchADD(N
, AM
, Depth
))
453 if (matchADD(N
, AM
, Depth
))
457 case ISD::FrameIndex
:
458 if (AM
.isDispAddrType() &&
459 AM
.BaseType
== M68kISelAddressMode::Base::RegBase
&&
460 AM
.BaseReg
.getNode() == nullptr && doesDispFitFI(AM
)) {
461 AM
.BaseType
= M68kISelAddressMode::Base::FrameIndexBase
;
462 AM
.BaseFrameIndex
= cast
<FrameIndexSDNode
>(N
)->getIndex();
468 return matchAddressBase(N
, AM
);
471 /// Add the specified node to the specified addressing mode, returning true if
472 /// it cannot be done. This just pattern matches for the addressing mode.
473 bool M68kDAGToDAGISel::matchAddress(SDValue N
, M68kISelAddressMode
&AM
) {
474 // TODO: Post-processing: Convert lea(,%reg,2) to lea(%reg,%reg), which has
475 // a smaller encoding and avoids a scaled-index.
476 // And make sure it is an indexed mode
478 // TODO: Post-processing: Convert foo to foo(%pc), even in non-PIC mode,
479 // because it has a smaller encoding.
480 // Make sure this must be done only if PC* modes are currently being matched
481 return matchAddressRecursively(N
, AM
, 0);
484 bool M68kDAGToDAGISel::matchADD(SDValue
&N
, M68kISelAddressMode
&AM
,
486 // Add an artificial use to this node so that we can keep track of
487 // it if it gets CSE'd with a different node.
488 HandleSDNode
Handle(N
);
490 M68kISelAddressMode Backup
= AM
;
491 if (matchAddressRecursively(N
.getOperand(0), AM
, Depth
+ 1) &&
492 matchAddressRecursively(Handle
.getValue().getOperand(1), AM
, Depth
+ 1)) {
497 // Try again after commuting the operands.
498 if (matchAddressRecursively(Handle
.getValue().getOperand(1), AM
, Depth
+ 1) &&
499 matchAddressRecursively(Handle
.getValue().getOperand(0), AM
, Depth
+ 1)) {
504 // If we couldn't fold both operands into the address at the same time,
505 // see if we can just put each operand into a register and fold at least
507 if (!AM
.hasBase() && !AM
.hasIndexReg()) {
508 N
= Handle
.getValue();
509 AM
.BaseReg
= N
.getOperand(0);
510 AM
.IndexReg
= N
.getOperand(1);
515 N
= Handle
.getValue();
519 /// Try to match M68kISD::Wrapper and M68kISD::WrapperPC nodes into an
520 /// addressing mode. These wrap things that will resolve down into a symbol
521 /// reference. If no match is possible, this returns true, otherwise it returns
523 bool M68kDAGToDAGISel::matchWrapper(SDValue N
, M68kISelAddressMode
&AM
) {
524 // If the addressing mode already has a symbol as the displacement, we can
525 // never match another symbol.
526 if (AM
.hasSymbolicDisplacement())
529 SDValue N0
= N
.getOperand(0);
531 if (N
.getOpcode() == M68kISD::WrapperPC
) {
533 // If cannot match here just restore the old version
534 M68kISelAddressMode Backup
= AM
;
540 if (auto *G
= dyn_cast
<GlobalAddressSDNode
>(N0
)) {
541 AM
.GV
= G
->getGlobal();
542 AM
.SymbolFlags
= G
->getTargetFlags();
543 if (!foldOffsetIntoAddress(G
->getOffset(), AM
)) {
547 } else if (auto *CP
= dyn_cast
<ConstantPoolSDNode
>(N0
)) {
548 AM
.CP
= CP
->getConstVal();
549 AM
.Alignment
= CP
->getAlign();
550 AM
.SymbolFlags
= CP
->getTargetFlags();
551 if (!foldOffsetIntoAddress(CP
->getOffset(), AM
)) {
555 } else if (auto *S
= dyn_cast
<ExternalSymbolSDNode
>(N0
)) {
556 AM
.ES
= S
->getSymbol();
557 AM
.SymbolFlags
= S
->getTargetFlags();
558 } else if (auto *S
= dyn_cast
<MCSymbolSDNode
>(N0
)) {
559 AM
.MCSym
= S
->getMCSymbol();
560 } else if (auto *J
= dyn_cast
<JumpTableSDNode
>(N0
)) {
561 AM
.JT
= J
->getIndex();
562 AM
.SymbolFlags
= J
->getTargetFlags();
563 } else if (auto *BA
= dyn_cast
<BlockAddressSDNode
>(N0
)) {
564 AM
.BlockAddr
= BA
->getBlockAddress();
565 AM
.SymbolFlags
= BA
->getTargetFlags();
566 if (!foldOffsetIntoAddress(BA
->getOffset(), AM
)) {
571 llvm_unreachable("Unhandled symbol reference node.");
573 AM
.setBaseReg(CurDAG
->getRegister(M68k::PC
, MVT::i32
));
577 // This wrapper requires 32bit disp/imm field for Medium CM
578 if (!AM
.isDisp32()) {
582 if (N
.getOpcode() == M68kISD::Wrapper
) {
583 if (auto *G
= dyn_cast
<GlobalAddressSDNode
>(N0
)) {
584 AM
.GV
= G
->getGlobal();
585 AM
.Disp
+= G
->getOffset();
586 AM
.SymbolFlags
= G
->getTargetFlags();
587 } else if (auto *CP
= dyn_cast
<ConstantPoolSDNode
>(N0
)) {
588 AM
.CP
= CP
->getConstVal();
589 AM
.Alignment
= CP
->getAlign();
590 AM
.Disp
+= CP
->getOffset();
591 AM
.SymbolFlags
= CP
->getTargetFlags();
592 } else if (auto *S
= dyn_cast
<ExternalSymbolSDNode
>(N0
)) {
593 AM
.ES
= S
->getSymbol();
594 AM
.SymbolFlags
= S
->getTargetFlags();
595 } else if (auto *S
= dyn_cast
<MCSymbolSDNode
>(N0
)) {
596 AM
.MCSym
= S
->getMCSymbol();
597 } else if (auto *J
= dyn_cast
<JumpTableSDNode
>(N0
)) {
598 AM
.JT
= J
->getIndex();
599 AM
.SymbolFlags
= J
->getTargetFlags();
600 } else if (auto *BA
= dyn_cast
<BlockAddressSDNode
>(N0
)) {
601 AM
.BlockAddr
= BA
->getBlockAddress();
602 AM
.Disp
+= BA
->getOffset();
603 AM
.SymbolFlags
= BA
->getTargetFlags();
605 llvm_unreachable("Unhandled symbol reference node.");
612 //===----------------------------------------------------------------------===//
614 //===----------------------------------------------------------------------===//
616 void M68kDAGToDAGISel::Select(SDNode
*Node
) {
617 unsigned Opcode
= Node
->getOpcode();
620 LLVM_DEBUG(dbgs() << "Selecting: "; Node
->dump(CurDAG
); dbgs() << '\n');
622 if (Node
->isMachineOpcode()) {
623 LLVM_DEBUG(dbgs() << "== "; Node
->dump(CurDAG
); dbgs() << '\n');
625 return; // Already selected.
632 case M68kISD::GLOBAL_BASE_REG
:
633 ReplaceNode(Node
, getGlobalBaseReg());
640 bool M68kDAGToDAGISel::SelectARIPI(SDNode
*Parent
, SDValue N
, SDValue
&Base
) {
641 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARIPI: ");
642 LLVM_DEBUG(dbgs() << "NOT IMPLEMENTED\n");
646 bool M68kDAGToDAGISel::SelectARIPD(SDNode
*Parent
, SDValue N
, SDValue
&Base
) {
647 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARIPD: ");
648 LLVM_DEBUG(dbgs() << "NOT IMPLEMENTED\n");
652 bool M68kDAGToDAGISel::SelectARID(SDNode
*Parent
, SDValue N
, SDValue
&Disp
,
654 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARID: ");
655 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::ARID
);
657 if (!matchAddress(N
, AM
))
660 if (AM
.isPCRelative()) {
661 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");
665 // If this is a frame index, grab it
666 if (getFrameIndexAddress(AM
, SDLoc(N
), Disp
, Base
)) {
667 LLVM_DEBUG(dbgs() << "SUCCESS matched FI\n");
671 if (AM
.hasIndexReg()) {
672 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");
676 if (!AM
.hasBaseReg()) {
677 LLVM_DEBUG(dbgs() << "REJECT: No Base reg\n");
681 if (getSymbolicDisplacement(AM
, SDLoc(N
), Disp
)) {
682 assert(!AM
.Disp
&& "Should not be any displacement");
683 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n");
687 // Give a chance to AddrType::ARI
689 LLVM_DEBUG(dbgs() << "REJECT: No displacement\n");
694 Disp
= getI16Imm(AM
.Disp
, SDLoc(N
));
696 LLVM_DEBUG(dbgs() << "SUCCESS\n");
700 static bool isAddressBase(const SDValue
&N
) {
701 switch (N
.getOpcode()) {
704 return llvm::any_of(N
.getNode()->ops(),
705 [](const SDUse
&U
) { return isAddressBase(U
.get()); });
706 case M68kISD::Wrapper
:
707 case M68kISD::WrapperPC
:
708 case M68kISD::GLOBAL_BASE_REG
:
715 bool M68kDAGToDAGISel::SelectARII(SDNode
*Parent
, SDValue N
, SDValue
&Disp
,
716 SDValue
&Base
, SDValue
&Index
) {
717 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::ARII
);
718 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARII: ");
720 if (!matchAddress(N
, AM
))
723 if (AM
.isPCRelative()) {
724 LLVM_DEBUG(dbgs() << "REJECT: PC relative\n");
728 if (!AM
.hasIndexReg()) {
729 LLVM_DEBUG(dbgs() << "REJECT: No Index\n");
733 if (!AM
.hasBaseReg()) {
734 LLVM_DEBUG(dbgs() << "REJECT: No Base\n");
738 if (!isAddressBase(AM
.BaseReg
) && isAddressBase(AM
.IndexReg
)) {
746 if (AM
.hasSymbolicDisplacement()) {
747 LLVM_DEBUG(dbgs() << "REJECT, Cannot match symbolic displacement\n");
751 // The idea here is that we want to use AddrType::ARII without displacement
752 // only if necessary like memory operations, otherwise this must be lowered
754 if (AM
.Disp
== 0 && (!Parent
|| (Parent
->getOpcode() != ISD::LOAD
&&
755 Parent
->getOpcode() != ISD::STORE
))) {
756 LLVM_DEBUG(dbgs() << "REJECT: Displacement is Zero\n");
760 Disp
= getI8Imm(AM
.Disp
, SDLoc(N
));
762 LLVM_DEBUG(dbgs() << "SUCCESS\n");
766 bool M68kDAGToDAGISel::SelectAL(SDNode
*Parent
, SDValue N
, SDValue
&Sym
) {
767 LLVM_DEBUG(dbgs() << "Selecting AddrType::AL: ");
768 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::AL
);
770 if (!matchAddress(N
, AM
)) {
771 LLVM_DEBUG(dbgs() << "REJECT: Match failed\n");
775 if (AM
.isPCRelative()) {
776 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");
781 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Base\n");
785 if (AM
.hasIndexReg()) {
786 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");
790 if (getSymbolicDisplacement(AM
, SDLoc(N
), Sym
)) {
791 LLVM_DEBUG(dbgs() << "SUCCESS: Matched symbol\n");
796 Sym
= getI32Imm(AM
.Disp
, SDLoc(N
));
797 LLVM_DEBUG(dbgs() << "SUCCESS\n");
801 LLVM_DEBUG(dbgs() << "REJECT: Not Symbol or Disp\n");
806 bool M68kDAGToDAGISel::SelectPCD(SDNode
*Parent
, SDValue N
, SDValue
&Disp
) {
807 LLVM_DEBUG(dbgs() << "Selecting AddrType::PCD: ");
808 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::PCD
);
810 if (!matchAddress(N
, AM
))
813 if (!AM
.isPCRelative()) {
814 LLVM_DEBUG(dbgs() << "REJECT: Not PC relative\n");
818 if (AM
.hasIndexReg()) {
819 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index\n");
823 if (getSymbolicDisplacement(AM
, SDLoc(N
), Disp
)) {
824 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n");
828 Disp
= getI16Imm(AM
.Disp
, SDLoc(N
));
830 LLVM_DEBUG(dbgs() << "SUCCESS\n");
834 bool M68kDAGToDAGISel::SelectPCI(SDNode
*Parent
, SDValue N
, SDValue
&Disp
,
836 LLVM_DEBUG(dbgs() << "Selecting AddrType::PCI: ");
837 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::PCI
);
839 if (!matchAddress(N
, AM
))
842 if (!AM
.isPCRelative()) {
843 LLVM_DEBUG(dbgs() << "REJECT: Not PC relative\n");
847 if (!AM
.hasIndexReg()) {
848 LLVM_DEBUG(dbgs() << "REJECT: No Index\n");
854 if (getSymbolicDisplacement(AM
, SDLoc(N
), Disp
)) {
855 assert(!AM
.Disp
&& "Should not be any displacement");
856 LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n");
860 Disp
= getI8Imm(AM
.Disp
, SDLoc(N
));
862 LLVM_DEBUG(dbgs() << "SUCCESS\n");
866 bool M68kDAGToDAGISel::SelectARI(SDNode
*Parent
, SDValue N
, SDValue
&Base
) {
867 LLVM_DEBUG(dbgs() << "Selecting AddrType::ARI: ");
868 M68kISelAddressMode
AM(M68kISelAddressMode::AddrType::ARI
);
870 if (!matchAddress(N
, AM
)) {
871 LLVM_DEBUG(dbgs() << "REJECT: Match failed\n");
875 if (AM
.isPCRelative()) {
876 LLVM_DEBUG(dbgs() << "REJECT: Cannot match PC relative address\n");
880 // AddrType::ARI does not use these
881 if (AM
.hasIndexReg() || AM
.Disp
!= 0) {
882 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Index or Disp\n");
886 // Must be matched by AddrType::AL
887 if (AM
.hasSymbolicDisplacement()) {
888 LLVM_DEBUG(dbgs() << "REJECT: Cannot match Symbolic Disp\n");
892 if (AM
.hasBaseReg()) {
894 LLVM_DEBUG(dbgs() << "SUCCESS\n");