Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp
35271 views
1
//===- XtensaAsmPrinter.cpp Xtensa LLVM Assembly Printer ------------------===//
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
// This file contains a printer that converts from our internal representation
10
// of machine-dependent LLVM code to GAS-format Xtensa assembly language.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "XtensaAsmPrinter.h"
15
#include "MCTargetDesc/XtensaMCExpr.h"
16
#include "MCTargetDesc/XtensaTargetStreamer.h"
17
#include "TargetInfo/XtensaTargetInfo.h"
18
#include "XtensaConstantPoolValue.h"
19
#include "llvm/ADT/StringExtras.h"
20
#include "llvm/BinaryFormat/ELF.h"
21
#include "llvm/CodeGen/MachineConstantPool.h"
22
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
23
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
24
#include "llvm/MC/MCExpr.h"
25
#include "llvm/MC/MCInstBuilder.h"
26
#include "llvm/MC/MCSectionELF.h"
27
#include "llvm/MC/MCStreamer.h"
28
#include "llvm/MC/MCSymbol.h"
29
#include "llvm/MC/MCSymbolELF.h"
30
#include "llvm/MC/TargetRegistry.h"
31
32
using namespace llvm;
33
34
static MCSymbolRefExpr::VariantKind
35
getModifierVariantKind(XtensaCP::XtensaCPModifier Modifier) {
36
switch (Modifier) {
37
case XtensaCP::no_modifier:
38
return MCSymbolRefExpr::VK_None;
39
case XtensaCP::TPOFF:
40
return MCSymbolRefExpr::VK_TPOFF;
41
}
42
report_fatal_error("Invalid XtensaCPModifier!");
43
}
44
45
void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
46
unsigned Opc = MI->getOpcode();
47
48
switch (Opc) {
49
case Xtensa::BR_JT:
50
EmitToStreamer(
51
*OutStreamer,
52
MCInstBuilder(Xtensa::JX).addReg(MI->getOperand(0).getReg()));
53
return;
54
default:
55
MCInst LoweredMI;
56
lowerToMCInst(MI, LoweredMI);
57
EmitToStreamer(*OutStreamer, LoweredMI);
58
return;
59
}
60
}
61
62
void XtensaAsmPrinter::emitMachineConstantPoolValue(
63
MachineConstantPoolValue *MCPV) {
64
XtensaConstantPoolValue *ACPV = static_cast<XtensaConstantPoolValue *>(MCPV);
65
MCSymbol *MCSym;
66
67
if (ACPV->isBlockAddress()) {
68
const BlockAddress *BA =
69
cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();
70
MCSym = GetBlockAddressSymbol(BA);
71
} else if (ACPV->isJumpTable()) {
72
unsigned Idx = cast<XtensaConstantPoolJumpTable>(ACPV)->getIndex();
73
MCSym = this->GetJTISymbol(Idx, false);
74
} else {
75
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
76
XtensaConstantPoolSymbol *XtensaSym = cast<XtensaConstantPoolSymbol>(ACPV);
77
const char *SymName = XtensaSym->getSymbol();
78
79
if (XtensaSym->isPrivateLinkage()) {
80
const DataLayout &DL = getDataLayout();
81
MCSym = OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
82
SymName);
83
} else {
84
MCSym = OutContext.getOrCreateSymbol(SymName);
85
}
86
}
87
88
MCSymbol *LblSym = GetCPISymbol(ACPV->getLabelId());
89
auto *TS =
90
static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());
91
MCSymbolRefExpr::VariantKind VK = getModifierVariantKind(ACPV->getModifier());
92
93
if (ACPV->getModifier() != XtensaCP::no_modifier) {
94
std::string SymName(MCSym->getName());
95
StringRef Modifier = ACPV->getModifierText();
96
SymName += Modifier;
97
MCSym = OutContext.getOrCreateSymbol(SymName);
98
}
99
100
const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, VK, OutContext);
101
TS->emitLiteral(LblSym, Expr, false);
102
}
103
104
void XtensaAsmPrinter::emitMachineConstantPoolEntry(
105
const MachineConstantPoolEntry &CPE, int i) {
106
if (CPE.isMachineConstantPoolEntry()) {
107
XtensaConstantPoolValue *ACPV =
108
static_cast<XtensaConstantPoolValue *>(CPE.Val.MachineCPVal);
109
ACPV->setLabelId(i);
110
emitMachineConstantPoolValue(CPE.Val.MachineCPVal);
111
} else {
112
MCSymbol *LblSym = GetCPISymbol(i);
113
auto *TS =
114
static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());
115
const Constant *C = CPE.Val.ConstVal;
116
const MCExpr *Value = nullptr;
117
118
Type *Ty = C->getType();
119
if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
120
Value = MCConstantExpr::create(
121
CFP->getValueAPF().bitcastToAPInt().getSExtValue(), OutContext);
122
} else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
123
Value = MCConstantExpr::create(CI->getValue().getSExtValue(), OutContext);
124
} else if (isa<PointerType>(Ty)) {
125
Value = lowerConstant(C);
126
} else {
127
llvm_unreachable("unexpected constant pool entry type");
128
}
129
130
TS->emitLiteral(LblSym, Value, false);
131
}
132
}
133
134
// EmitConstantPool - Print to the current output stream assembly
135
// representations of the constants in the constant pool MCP. This is
136
// used to print out constants which have been "spilled to memory" by
137
// the code generator.
138
void XtensaAsmPrinter::emitConstantPool() {
139
const Function &F = MF->getFunction();
140
const MachineConstantPool *MCP = MF->getConstantPool();
141
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
142
if (CP.empty())
143
return;
144
145
OutStreamer->pushSection();
146
147
auto *TS =
148
static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());
149
MCSection *CS = getObjFileLowering().SectionForGlobal(&F, TM);
150
TS->startLiteralSection(CS);
151
152
int CPIdx = 0;
153
for (const MachineConstantPoolEntry &CPE : CP) {
154
emitMachineConstantPoolEntry(CPE, CPIdx++);
155
}
156
157
OutStreamer->popSection();
158
}
159
160
MCSymbol *
161
XtensaAsmPrinter::GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
162
// Create a symbol for the name.
163
return GetCPISymbol(MO.getIndex());
164
}
165
166
MCSymbol *XtensaAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) const {
167
return GetJTISymbol(MO.getIndex());
168
}
169
170
MCOperand
171
XtensaAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
172
MachineOperand::MachineOperandType MOTy,
173
unsigned Offset) const {
174
const MCSymbol *Symbol;
175
XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
176
177
switch (MOTy) {
178
case MachineOperand::MO_GlobalAddress:
179
Symbol = getSymbol(MO.getGlobal());
180
Offset += MO.getOffset();
181
break;
182
case MachineOperand::MO_MachineBasicBlock:
183
Symbol = MO.getMBB()->getSymbol();
184
break;
185
case MachineOperand::MO_BlockAddress:
186
Symbol = GetBlockAddressSymbol(MO.getBlockAddress());
187
Offset += MO.getOffset();
188
break;
189
case MachineOperand::MO_ExternalSymbol:
190
Symbol = GetExternalSymbolSymbol(MO.getSymbolName());
191
Offset += MO.getOffset();
192
break;
193
case MachineOperand::MO_JumpTableIndex:
194
Symbol = GetJumpTableSymbol(MO);
195
break;
196
case MachineOperand::MO_ConstantPoolIndex:
197
Symbol = GetConstantPoolIndexSymbol(MO);
198
Offset += MO.getOffset();
199
break;
200
default:
201
report_fatal_error("<unknown operand type>");
202
}
203
204
const MCExpr *ME =
205
MCSymbolRefExpr::create(Symbol, MCSymbolRefExpr::VK_None, OutContext);
206
ME = XtensaMCExpr::create(ME, Kind, OutContext);
207
208
if (Offset) {
209
// Assume offset is never negative.
210
assert(Offset > 0);
211
212
const MCConstantExpr *OffsetExpr =
213
MCConstantExpr::create(Offset, OutContext);
214
ME = MCBinaryExpr::createAdd(ME, OffsetExpr, OutContext);
215
}
216
217
return MCOperand::createExpr(ME);
218
}
219
220
MCOperand XtensaAsmPrinter::lowerOperand(const MachineOperand &MO,
221
unsigned Offset) const {
222
MachineOperand::MachineOperandType MOTy = MO.getType();
223
224
switch (MOTy) {
225
case MachineOperand::MO_Register:
226
// Ignore all implicit register operands.
227
if (MO.isImplicit())
228
break;
229
return MCOperand::createReg(MO.getReg());
230
case MachineOperand::MO_Immediate:
231
return MCOperand::createImm(MO.getImm() + Offset);
232
case MachineOperand::MO_RegisterMask:
233
break;
234
case MachineOperand::MO_GlobalAddress:
235
case MachineOperand::MO_MachineBasicBlock:
236
case MachineOperand::MO_BlockAddress:
237
case MachineOperand::MO_ExternalSymbol:
238
case MachineOperand::MO_JumpTableIndex:
239
case MachineOperand::MO_ConstantPoolIndex:
240
return LowerSymbolOperand(MO, MOTy, Offset);
241
default:
242
report_fatal_error("unknown operand type");
243
}
244
245
return MCOperand();
246
}
247
248
void XtensaAsmPrinter::lowerToMCInst(const MachineInstr *MI,
249
MCInst &OutMI) const {
250
OutMI.setOpcode(MI->getOpcode());
251
252
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
253
const MachineOperand &MO = MI->getOperand(i);
254
MCOperand MCOp = lowerOperand(MO);
255
256
if (MCOp.isValid())
257
OutMI.addOperand(MCOp);
258
}
259
}
260
261
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() {
262
RegisterAsmPrinter<XtensaAsmPrinter> A(getTheXtensaTarget());
263
}
264
265