Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kMCInstLower.cpp
35294 views
1
//===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst -------*- 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 contains code to lower M68k MachineInstrs to their
11
/// corresponding MCInst records.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "M68kMCInstLower.h"
16
17
#include "M68kAsmPrinter.h"
18
#include "M68kInstrInfo.h"
19
20
#include "MCTargetDesc/M68kBaseInfo.h"
21
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"
29
30
using namespace llvm;
31
32
#define DEBUG_TYPE "m68k-mc-inst-lower"
33
34
M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)
35
: Ctx(MF.getContext()), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),
36
AsmPrinter(AP) {}
37
38
MCSymbol *
39
M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
40
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
41
"Isn't a symbol reference");
42
43
const auto &TT = TM.getTargetTriple();
44
if (MO.isGlobal() && TT.isOSBinFormatELF())
45
return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());
46
47
const DataLayout &DL = MF.getDataLayout();
48
49
MCSymbol *Sym = nullptr;
50
SmallString<128> Name;
51
StringRef Suffix;
52
53
if (!Suffix.empty())
54
Name += DL.getPrivateGlobalPrefix();
55
56
if (MO.isGlobal()) {
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();
64
}
65
66
Name += Suffix;
67
if (!Sym)
68
Sym = Ctx.getOrCreateSymbol(Name);
69
70
return Sym;
71
}
72
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;
79
80
switch (MO.getTargetFlags()) {
81
default:
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:
86
break;
87
case M68kII::MO_GOTPCREL:
88
RefKind = MCSymbolRefExpr::VK_GOTPCREL;
89
break;
90
case M68kII::MO_GOT:
91
RefKind = MCSymbolRefExpr::VK_GOT;
92
break;
93
case M68kII::MO_GOTOFF:
94
RefKind = MCSymbolRefExpr::VK_GOTOFF;
95
break;
96
case M68kII::MO_PLT:
97
RefKind = MCSymbolRefExpr::VK_PLT;
98
break;
99
case M68kII::MO_TLSGD:
100
RefKind = MCSymbolRefExpr::VK_TLSGD;
101
break;
102
case M68kII::MO_TLSLD:
103
RefKind = MCSymbolRefExpr::VK_TLSLD;
104
break;
105
case M68kII::MO_TLSLDM:
106
RefKind = MCSymbolRefExpr::VK_TLSLDM;
107
break;
108
case M68kII::MO_TLSIE:
109
RefKind = MCSymbolRefExpr::VK_GOTTPOFF;
110
break;
111
case M68kII::MO_TLSLE:
112
RefKind = MCSymbolRefExpr::VK_TPOFF;
113
break;
114
}
115
116
if (!Expr) {
117
Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
118
}
119
120
if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {
121
Expr = MCBinaryExpr::createAdd(
122
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
123
}
124
125
return MCOperand::createExpr(Expr);
126
}
127
128
std::optional<MCOperand>
129
M68kMCInstLower::LowerOperand(const MachineInstr *MI,
130
const MachineOperand &MO) const {
131
switch (MO.getType()) {
132
default:
133
llvm_unreachable("unknown operand type");
134
case MachineOperand::MO_Register:
135
// Ignore all implicit register operands.
136
if (MO.isImplicit())
137
return std::nullopt;
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.
156
return std::nullopt;
157
}
158
}
159
160
void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
161
unsigned Opcode = MI->getOpcode();
162
OutMI.setOpcode(Opcode);
163
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);
167
168
if (MCOp.has_value() && MCOp.value().isValid())
169
OutMI.addOperand(MCOp.value());
170
}
171
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");
175
switch (Opcode) {
176
case M68k::TAILJMPj:
177
Opcode = M68k::JMP32j;
178
break;
179
case M68k::TAILJMPq:
180
Opcode = M68k::BRA8;
181
break;
182
}
183
OutMI.setOpcode(Opcode);
184
}
185
}
186
187