1 //===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst -------*- 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 contains code to lower M68k MachineInstrs to their
11 /// corresponding MCInst records.
13 //===----------------------------------------------------------------------===//
15 #include "M68kMCInstLower.h"
17 #include "M68kAsmPrinter.h"
18 #include "M68kInstrInfo.h"
20 #include "MCTargetDesc/M68kBaseInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstr.h"
24 #include "llvm/CodeGen/MachineOperand.h"
25 #include "llvm/IR/Mangler.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInst.h"
32 #define DEBUG_TYPE "m68k-mc-inst-lower"
34 M68kMCInstLower::M68kMCInstLower(MachineFunction
&MF
, M68kAsmPrinter
&AP
)
35 : Ctx(MF
.getContext()), MF(MF
), TM(MF
.getTarget()), MAI(*TM
.getMCAsmInfo()),
39 M68kMCInstLower::GetSymbolFromOperand(const MachineOperand
&MO
) const {
40 assert((MO
.isGlobal() || MO
.isSymbol() || MO
.isMBB()) &&
41 "Isn't a symbol reference");
43 const auto &TT
= TM
.getTargetTriple();
44 if (MO
.isGlobal() && TT
.isOSBinFormatELF())
45 return AsmPrinter
.getSymbolPreferLocal(*MO
.getGlobal());
47 const DataLayout
&DL
= MF
.getDataLayout();
49 MCSymbol
*Sym
= nullptr;
50 SmallString
<128> Name
;
54 Name
+= DL
.getPrivateGlobalPrefix();
57 const GlobalValue
*GV
= MO
.getGlobal();
58 AsmPrinter
.getNameWithPrefix(Name
, GV
);
59 } else if (MO
.isSymbol()) {
60 Mangler::getNameWithPrefix(Name
, MO
.getSymbolName(), DL
);
61 } else if (MO
.isMBB()) {
62 assert(Suffix
.empty());
63 Sym
= MO
.getMBB()->getSymbol();
68 Sym
= Ctx
.getOrCreateSymbol(Name
);
73 MCOperand
M68kMCInstLower::LowerSymbolOperand(const MachineOperand
&MO
,
74 MCSymbol
*Sym
) const {
75 // FIXME We would like an efficient form for this, so we don't have to do a
76 // lot of extra uniquing. This fixme is originally from X86
77 const MCExpr
*Expr
= nullptr;
78 MCSymbolRefExpr::VariantKind RefKind
= MCSymbolRefExpr::VK_None
;
80 switch (MO
.getTargetFlags()) {
82 llvm_unreachable("Unknown target flag on GV operand");
83 case M68kII::MO_NO_FLAG
:
84 case M68kII::MO_ABSOLUTE_ADDRESS
:
85 case M68kII::MO_PC_RELATIVE_ADDRESS
:
87 case M68kII::MO_GOTPCREL
:
88 RefKind
= MCSymbolRefExpr::VK_GOTPCREL
;
91 RefKind
= MCSymbolRefExpr::VK_GOT
;
93 case M68kII::MO_GOTOFF
:
94 RefKind
= MCSymbolRefExpr::VK_GOTOFF
;
97 RefKind
= MCSymbolRefExpr::VK_PLT
;
99 case M68kII::MO_TLSGD
:
100 RefKind
= MCSymbolRefExpr::VK_TLSGD
;
102 case M68kII::MO_TLSLD
:
103 RefKind
= MCSymbolRefExpr::VK_TLSLD
;
105 case M68kII::MO_TLSLDM
:
106 RefKind
= MCSymbolRefExpr::VK_TLSLDM
;
108 case M68kII::MO_TLSIE
:
109 RefKind
= MCSymbolRefExpr::VK_GOTTPOFF
;
111 case M68kII::MO_TLSLE
:
112 RefKind
= MCSymbolRefExpr::VK_TPOFF
;
117 Expr
= MCSymbolRefExpr::create(Sym
, RefKind
, Ctx
);
120 if (!MO
.isJTI() && !MO
.isMBB() && MO
.getOffset()) {
121 Expr
= MCBinaryExpr::createAdd(
122 Expr
, MCConstantExpr::create(MO
.getOffset(), Ctx
), Ctx
);
125 return MCOperand::createExpr(Expr
);
128 std::optional
<MCOperand
>
129 M68kMCInstLower::LowerOperand(const MachineInstr
*MI
,
130 const MachineOperand
&MO
) const {
131 switch (MO
.getType()) {
133 llvm_unreachable("unknown operand type");
134 case MachineOperand::MO_Register
:
135 // Ignore all implicit register operands.
138 return MCOperand::createReg(MO
.getReg());
139 case MachineOperand::MO_Immediate
:
140 return MCOperand::createImm(MO
.getImm());
141 case MachineOperand::MO_MachineBasicBlock
:
142 case MachineOperand::MO_GlobalAddress
:
143 case MachineOperand::MO_ExternalSymbol
:
144 return LowerSymbolOperand(MO
, GetSymbolFromOperand(MO
));
145 case MachineOperand::MO_MCSymbol
:
146 return LowerSymbolOperand(MO
, MO
.getMCSymbol());
147 case MachineOperand::MO_JumpTableIndex
:
148 return LowerSymbolOperand(MO
, AsmPrinter
.GetJTISymbol(MO
.getIndex()));
149 case MachineOperand::MO_ConstantPoolIndex
:
150 return LowerSymbolOperand(MO
, AsmPrinter
.GetCPISymbol(MO
.getIndex()));
151 case MachineOperand::MO_BlockAddress
:
152 return LowerSymbolOperand(
153 MO
, AsmPrinter
.GetBlockAddressSymbol(MO
.getBlockAddress()));
154 case MachineOperand::MO_RegisterMask
:
155 // Ignore call clobbers.
160 void M68kMCInstLower::Lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
161 unsigned Opcode
= MI
->getOpcode();
162 OutMI
.setOpcode(Opcode
);
164 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
165 const MachineOperand
&MO
= MI
->getOperand(i
);
166 std::optional
<MCOperand
> MCOp
= LowerOperand(MI
, MO
);
168 if (MCOp
.has_value() && MCOp
.value().isValid())
169 OutMI
.addOperand(MCOp
.value());
172 // TAILJMPj, TAILJMPq - Lower to the correct jump instructions.
173 if (Opcode
== M68k::TAILJMPj
|| Opcode
== M68k::TAILJMPq
) {
174 assert(OutMI
.getNumOperands() == 1 && "Unexpected number of operands");
177 Opcode
= M68k::JMP32j
;
183 OutMI
.setOpcode(Opcode
);