41 #define DEBUG_TYPE "m68k-isel"
47 struct M68kISelAddressMode {
60 enum class Base { RegBase, FrameIndexBase };
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),
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 {
102 bool hasIndexReg()
const {
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 {
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; }
134 bool isPCRelative()
const {
137 if (
auto *RegNode = dyn_cast_or_null<RegisterSDNode>(BaseReg.
getNode()))
138 return RegNode->getReg() == M68k::PC;
149 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
151 dbgs() <<
"M68kISelAddressMode " <<
this;
152 dbgs() <<
"\nDisp: " << Disp;
153 dbgs() <<
", BaseReg: ";
158 dbgs() <<
", BaseFI: " << BaseFrameIndex;
159 dbgs() <<
", IndexReg: ";
164 dbgs() <<
", Scale: " << Scale;
180 return "M68k DAG->DAG Pattern Instruction Selection";
191 #include "M68kGenDAGISel.inc"
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);
231 inline bool getFrameIndexAddress(M68kISelAddressMode &AM,
const SDLoc &
DL,
233 if (AM.BaseType == M68kISelAddressMode::Base::FrameIndexBase) {
234 Disp = getI32Imm(AM.Disp,
DL);
235 Base = CurDAG->getTargetFrameIndex(
236 AM.BaseFrameIndex, TLI->getPointerTy(CurDAG->getDataLayout()));
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,
310 SDNode *getGlobalBaseReg();
322 return new M68kDAGToDAGISel(
TM);
326 if (!AM.isDispAddrType())
329 return isIntN(AM.getDispSize() - 1, AM.Disp);
333 if (!AM.isDispAddrType())
335 return isIntN(AM.getDispSize(), Val);
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) {
350 if (Offset != 0 && (AM.ES || AM.MCSym))
353 int64_t Val = AM.Disp +
Offset;
369 bool M68kDAGToDAGISel::matchAddressBase(
SDValue N, M68kISelAddressMode &AM) {
373 if (!AM.hasIndexReg()) {
384 AM.BaseType = M68kISelAddressMode::Base::RegBase;
390 bool M68kDAGToDAGISel::matchLoadInAddress(
LoadSDNode *
N,
391 M68kISelAddressMode &AM) {
395 bool M68kDAGToDAGISel::matchAddressRecursively(
SDValue N,
396 M68kISelAddressMode &AM,
402 return matchAddressBase(
N, AM);
407 if (AM.isPCRelative()) {
413 if (foldOffsetIntoAddress(Cst->getSExtValue(), AM))
418 switch (
N.getOpcode()) {
423 uint64_t Val = cast<ConstantSDNode>(
N)->getSExtValue();
424 if (foldOffsetIntoAddress(Val, AM))
431 if (matchWrapper(
N, AM))
436 if (matchLoadInAddress(cast<LoadSDNode>(
N), AM))
447 if (CurDAG->haveNoCommonBitsSet(
N.getOperand(0),
N.getOperand(1)) &&
453 if (matchADD(
N, AM,
Depth))
458 if (AM.isDispAddrType() &&
459 AM.BaseType == M68kISelAddressMode::Base::RegBase &&
461 AM.BaseType = M68kISelAddressMode::Base::FrameIndexBase;
462 AM.BaseFrameIndex = cast<FrameIndexSDNode>(
N)->getIndex();
468 return matchAddressBase(
N, AM);
473 bool M68kDAGToDAGISel::matchAddress(
SDValue N, M68kISelAddressMode &AM) {
481 return matchAddressRecursively(
N, AM, 0);
484 bool M68kDAGToDAGISel::matchADD(
SDValue &
N, M68kISelAddressMode &AM,
490 M68kISelAddressMode Backup = AM;
491 if (matchAddressRecursively(
N.getOperand(0), AM,
Depth + 1) &&
492 matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth + 1)) {
498 if (matchAddressRecursively(Handle.getValue().getOperand(1), AM,
Depth + 1) &&
499 matchAddressRecursively(Handle.getValue().getOperand(0), AM,
Depth + 1)) {
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();
523 bool M68kDAGToDAGISel::matchWrapper(
SDValue N, M68kISelAddressMode &AM) {
526 if (AM.hasSymbolicDisplacement())
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)) {
573 AM.setBaseReg(CurDAG->getRegister(M68k::PC,
MVT::i32));
578 if (!AM.isDisp32()) {
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();
617 unsigned Opcode = Node->getOpcode();
622 if (Node->isMachineOpcode()) {
633 ReplaceNode(Node, getGlobalBaseReg());
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");
666 if (getFrameIndexAddress(AM,
SDLoc(
N), Disp,
Base)) {
671 if (AM.hasIndexReg()) {
676 if (!AM.hasBaseReg()) {
681 if (getSymbolicDisplacement(AM,
SDLoc(
N), Disp)) {
682 assert(!AM.Disp &&
"Should not be any displacement");
694 Disp = getI16Imm(AM.Disp,
SDLoc(
N));
701 switch (
N.getOpcode()) {
705 [](
const SDUse &U) { return isAddressBase(U.get()); });
717 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARII);
720 if (!matchAddress(
N, AM))
723 if (AM.isPCRelative()) {
728 if (!AM.hasIndexReg()) {
733 if (!AM.hasBaseReg()) {
746 if (AM.hasSymbolicDisplacement()) {
747 LLVM_DEBUG(
dbgs() <<
"REJECT, Cannot match symbolic displacement\n");
760 Disp = getI8Imm(AM.Disp,
SDLoc(
N));
770 if (!matchAddress(
N, AM)) {
775 if (AM.isPCRelative()) {
776 LLVM_DEBUG(
dbgs() <<
"REJECT: Cannot match PC relative address\n");
785 if (AM.hasIndexReg()) {
790 if (getSymbolicDisplacement(AM,
SDLoc(
N), Sym)) {
796 Sym = getI32Imm(AM.Disp,
SDLoc(
N));
808 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCD);
810 if (!matchAddress(
N, AM))
813 if (!AM.isPCRelative()) {
818 if (AM.hasIndexReg()) {
823 if (getSymbolicDisplacement(AM,
SDLoc(
N), Disp)) {
828 Disp = getI16Imm(AM.Disp,
SDLoc(
N));
837 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::PCI);
839 if (!matchAddress(
N, AM))
842 if (!AM.isPCRelative()) {
847 if (!AM.hasIndexReg()) {
854 if (getSymbolicDisplacement(AM,
SDLoc(
N), Disp)) {
855 assert(!AM.Disp &&
"Should not be any displacement");
860 Disp = getI8Imm(AM.Disp,
SDLoc(
N));
868 M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARI);
870 if (!matchAddress(
N, AM)) {
875 if (AM.isPCRelative()) {
876 LLVM_DEBUG(
dbgs() <<
"REJECT: Cannot match PC relative address\n");
881 if (AM.hasIndexReg() || AM.Disp != 0) {
887 if (AM.hasSymbolicDisplacement()) {
892 if (AM.hasBaseReg()) {