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
;
102 Expr
= MCSymbolRefExpr::create(Sym
, RefKind
, Ctx
);
105 if (!MO
.isJTI() && !MO
.isMBB() && MO
.getOffset()) {
106 Expr
= MCBinaryExpr::createAdd(
107 Expr
, MCConstantExpr::create(MO
.getOffset(), Ctx
), Ctx
);
110 return MCOperand::createExpr(Expr
);
114 M68kMCInstLower::LowerOperand(const MachineInstr
*MI
,
115 const MachineOperand
&MO
) const {
116 switch (MO
.getType()) {
118 llvm_unreachable("unknown operand type");
119 case MachineOperand::MO_Register
:
120 // Ignore all implicit register operands.
123 return MCOperand::createReg(MO
.getReg());
124 case MachineOperand::MO_Immediate
:
125 return MCOperand::createImm(MO
.getImm());
126 case MachineOperand::MO_MachineBasicBlock
:
127 case MachineOperand::MO_GlobalAddress
:
128 case MachineOperand::MO_ExternalSymbol
:
129 return LowerSymbolOperand(MO
, GetSymbolFromOperand(MO
));
130 case MachineOperand::MO_MCSymbol
:
131 return LowerSymbolOperand(MO
, MO
.getMCSymbol());
132 case MachineOperand::MO_JumpTableIndex
:
133 return LowerSymbolOperand(MO
, AsmPrinter
.GetJTISymbol(MO
.getIndex()));
134 case MachineOperand::MO_ConstantPoolIndex
:
135 return LowerSymbolOperand(MO
, AsmPrinter
.GetCPISymbol(MO
.getIndex()));
136 case MachineOperand::MO_BlockAddress
:
137 return LowerSymbolOperand(
138 MO
, AsmPrinter
.GetBlockAddressSymbol(MO
.getBlockAddress()));
139 case MachineOperand::MO_RegisterMask
:
140 // Ignore call clobbers.
145 void M68kMCInstLower::Lower(const MachineInstr
*MI
, MCInst
&OutMI
) const {
146 unsigned Opcode
= MI
->getOpcode();
147 OutMI
.setOpcode(Opcode
);
149 for (unsigned i
= 0, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
150 const MachineOperand
&MO
= MI
->getOperand(i
);
151 Optional
<MCOperand
> MCOp
= LowerOperand(MI
, MO
);
153 if (MCOp
.hasValue() && MCOp
.getValue().isValid())
154 OutMI
.addOperand(MCOp
.getValue());
157 // TAILJMPj, TAILJMPq - Lower to the correct jump instructions.
158 if (Opcode
== M68k::TAILJMPj
|| Opcode
== M68k::TAILJMPq
) {
159 assert(OutMI
.getNumOperands() == 1 && "Unexpected number of operands");
162 Opcode
= M68k::JMP32j
;
168 OutMI
.setOpcode(Opcode
);