Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp
35294 views
1
//===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax ---------===//
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 class prints an CSKY MCInst to a .s file.
10
//
11
//===----------------------------------------------------------------------===//
12
#include "CSKYInstPrinter.h"
13
#include "MCTargetDesc/CSKYBaseInfo.h"
14
#include "MCTargetDesc/CSKYMCExpr.h"
15
#include "llvm/ADT/STLExtras.h"
16
#include "llvm/ADT/StringExtras.h"
17
#include "llvm/MC/MCAsmInfo.h"
18
#include "llvm/MC/MCExpr.h"
19
#include "llvm/MC/MCInst.h"
20
#include "llvm/MC/MCInstrInfo.h"
21
#include "llvm/MC/MCRegisterInfo.h"
22
#include "llvm/MC/MCSection.h"
23
#include "llvm/MC/MCSubtargetInfo.h"
24
#include "llvm/MC/MCSymbol.h"
25
#include "llvm/Support/CommandLine.h"
26
#include "llvm/Support/Debug.h"
27
#include "llvm/Support/ErrorHandling.h"
28
#include "llvm/Support/FormattedStream.h"
29
30
using namespace llvm;
31
32
#define DEBUG_TYPE "csky-asm-printer"
33
34
// Include the auto-generated portion of the assembly writer.
35
#define PRINT_ALIAS_INSTR
36
#include "CSKYGenAsmWriter.inc"
37
38
static cl::opt<bool>
39
NoAliases("csky-no-aliases",
40
cl::desc("Disable the emission of assembler pseudo instructions"),
41
cl::init(false), cl::Hidden);
42
43
static cl::opt<bool>
44
ArchRegNames("csky-arch-reg-names",
45
cl::desc("Print architectural register names rather than the "
46
"ABI names (such as r14 instead of sp)"),
47
cl::init(false), cl::Hidden);
48
49
// The command-line flags above are used by llvm-mc and llc. They can be used by
50
// `llvm-objdump`, but we override their values here to handle options passed to
51
// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to
52
// be an easier way to allow these options in all these tools, without doing it
53
// this way.
54
bool CSKYInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {
55
if (Opt == "no-aliases") {
56
NoAliases = true;
57
return true;
58
}
59
if (Opt == "numeric") {
60
ArchRegNames = true;
61
return true;
62
}
63
if (Opt == "debug") {
64
DebugFlag = true;
65
return true;
66
}
67
if (Opt == "abi-names") {
68
ABIRegNames = true;
69
return true;
70
}
71
72
return false;
73
}
74
75
void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address,
76
StringRef Annot, const MCSubtargetInfo &STI,
77
raw_ostream &O) {
78
const MCInst *NewMI = MI;
79
80
if (NoAliases || !printAliasInstr(NewMI, Address, STI, O))
81
printInstruction(NewMI, Address, STI, O);
82
printAnnotation(O, Annot);
83
}
84
85
void CSKYInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
86
if (PrintBranchImmAsAddress)
87
O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName
88
: CSKY::NoRegAltName);
89
else
90
O << getRegisterName(Reg);
91
}
92
93
void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {
94
if (PrintBranchImmAsAddress)
95
O << getRegisterName(RegNo, CSKY::NoRegAltName);
96
else
97
O << getRegisterName(RegNo);
98
}
99
100
void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
101
const MCSubtargetInfo &STI, raw_ostream &O,
102
const char *Modifier) {
103
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
104
const MCOperand &MO = MI->getOperand(OpNo);
105
106
if (MO.isReg()) {
107
unsigned Reg = MO.getReg();
108
bool useABIName = false;
109
if (PrintBranchImmAsAddress)
110
useABIName = ABIRegNames;
111
else
112
useABIName = !ArchRegNames;
113
114
if (Reg == CSKY::C)
115
O << "";
116
else if (STI.hasFeature(CSKY::FeatureJAVA)) {
117
if (Reg == CSKY::R23)
118
O << (useABIName ? "fp" : "r23");
119
else if (Reg == CSKY::R24)
120
O << (useABIName ? "top" : "r24");
121
else if (Reg == CSKY::R25)
122
O << (useABIName ? "bsp" : "r25");
123
else
124
printRegName(O, Reg);
125
} else
126
printRegName(O, Reg);
127
128
return;
129
}
130
131
if (MO.isImm()) {
132
uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;
133
134
if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&
135
PrintBranchImmAsAddress)
136
O << formatHex(MO.getImm());
137
else
138
O << MO.getImm();
139
return;
140
}
141
142
assert(MO.isExpr() && "Unknown operand kind in printOperand");
143
MO.getExpr()->print(O, &MAI);
144
}
145
146
void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo,
147
const MCSubtargetInfo &STI,
148
raw_ostream &O) {
149
const MCOperand &MO = MI->getOperand(OpNo);
150
151
O << "[";
152
if (MO.isImm())
153
O << MO.getImm();
154
else
155
MO.getExpr()->print(O, &MAI);
156
O << "]";
157
}
158
159
void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address,
160
unsigned OpNo, const MCSubtargetInfo &STI,
161
raw_ostream &O) {
162
const MCOperand &MO = MI->getOperand(OpNo);
163
164
if (MO.isImm()) {
165
if (PrintBranchImmAsAddress) {
166
uint64_t Target = Address + MO.getImm();
167
Target &= 0xfffffffc;
168
O << formatHex(Target);
169
} else {
170
O << MO.getImm();
171
}
172
return;
173
}
174
175
assert(MO.isExpr() && "Unknown operand kind in printConstpool");
176
177
O << "[";
178
MO.getExpr()->print(O, &MAI);
179
O << "]";
180
}
181
182
void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address,
183
unsigned OpNo,
184
const MCSubtargetInfo &STI,
185
raw_ostream &O) {
186
const MCOperand &MO = MI->getOperand(OpNo);
187
if (!MO.isImm()) {
188
return printOperand(MI, OpNo, STI, O);
189
}
190
191
if (PrintBranchImmAsAddress) {
192
uint64_t Target = Address + MO.getImm();
193
Target &= 0xffffffff;
194
O << formatHex(Target);
195
} else {
196
O << MO.getImm();
197
}
198
}
199
200
void CSKYInstPrinter::printPSRFlag(const MCInst *MI, unsigned OpNo,
201
const MCSubtargetInfo &STI, raw_ostream &O) {
202
auto V = MI->getOperand(OpNo).getImm();
203
204
ListSeparator LS;
205
206
if ((V >> 3) & 0x1)
207
O << LS << "ee";
208
if ((V >> 2) & 0x1)
209
O << LS << "ie";
210
if ((V >> 1) & 0x1)
211
O << LS << "fe";
212
if ((V >> 0) & 0x1)
213
O << LS << "af";
214
}
215
216
void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum,
217
const MCSubtargetInfo &STI,
218
raw_ostream &O) {
219
printRegName(O, MI->getOperand(OpNum).getReg());
220
O << "-";
221
printRegName(O, MI->getOperand(OpNum + 1).getReg());
222
}
223
224
void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
225
const MCSubtargetInfo &STI,
226
raw_ostream &O) {
227
auto V = MI->getOperand(OpNum).getImm();
228
ListSeparator LS;
229
230
if (V & 0xf) {
231
O << LS;
232
printRegName(O, CSKY::R4);
233
auto Offset = (V & 0xf) - 1;
234
if (Offset) {
235
O << "-";
236
printRegName(O, CSKY::R4 + Offset);
237
}
238
}
239
240
if ((V >> 4) & 0x1) {
241
O << LS;
242
printRegName(O, CSKY::R15);
243
}
244
245
if ((V >> 5) & 0x7) {
246
O << LS;
247
printRegName(O, CSKY::R16);
248
249
auto Offset = ((V >> 5) & 0x7) - 1;
250
251
if (Offset) {
252
O << "-";
253
printRegName(O, CSKY::R16 + Offset);
254
}
255
}
256
257
if ((V >> 8) & 0x1) {
258
O << LS;
259
printRegName(O, CSKY::R28);
260
}
261
}
262
263
const char *CSKYInstPrinter::getRegisterName(MCRegister Reg) {
264
return getRegisterName(Reg, ArchRegNames ? CSKY::NoRegAltName
265
: CSKY::ABIRegAltName);
266
}
267
268
void CSKYInstPrinter::printFPR(const MCInst *MI, unsigned OpNo,
269
const MCSubtargetInfo &STI, raw_ostream &O) {
270
const MCOperand &MO = MI->getOperand(OpNo);
271
assert(MO.isReg());
272
273
printFPRRegName(O, MO.getReg());
274
}
275
276