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/MCTargetDesc/XtensaInstPrinter.cpp
35295 views
1
//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//
2
//
3
// The LLVM Compiler Infrastructure
4
//
5
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6
// See https://llvm.org/LICENSE.txt for license information.
7
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8
//
9
//===----------------------------------------------------------------------===//
10
//
11
// This class prints an Xtensa MCInst to a .s file.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "XtensaInstPrinter.h"
16
#include "llvm/CodeGen/MachineOperand.h"
17
#include "llvm/MC/MCExpr.h"
18
#include "llvm/MC/MCInstrInfo.h"
19
#include "llvm/MC/MCRegister.h"
20
#include "llvm/MC/MCSymbol.h"
21
#include "llvm/Support/Casting.h"
22
#include "llvm/Support/raw_ostream.h"
23
24
using namespace llvm;
25
26
#define DEBUG_TYPE "asm-printer"
27
28
#include "XtensaGenAsmWriter.inc"
29
30
static void printExpr(const MCExpr *Expr, raw_ostream &OS) {
31
int Offset = 0;
32
const MCSymbolRefExpr *SRE;
33
34
if (!(SRE = cast<MCSymbolRefExpr>(Expr)))
35
assert(false && "Unexpected MCExpr type.");
36
37
MCSymbolRefExpr::VariantKind Kind = SRE->getKind();
38
39
switch (Kind) {
40
case MCSymbolRefExpr::VK_None:
41
break;
42
// TODO
43
default:
44
report_fatal_error("Invalid kind!");
45
}
46
47
OS << SRE->getSymbol();
48
49
if (Offset) {
50
if (Offset > 0)
51
OS << '+';
52
OS << Offset;
53
}
54
55
if (Kind != MCSymbolRefExpr::VK_None)
56
OS << ')';
57
}
58
59
void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) {
60
if (MC.isReg())
61
O << getRegisterName(MC.getReg());
62
else if (MC.isImm())
63
O << MC.getImm();
64
else if (MC.isExpr())
65
printExpr(MC.getExpr(), O);
66
else
67
report_fatal_error("Invalid operand");
68
}
69
70
void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,
71
StringRef Annot, const MCSubtargetInfo &STI,
72
raw_ostream &O) {
73
printInstruction(MI, Address, O);
74
printAnnotation(O, Annot);
75
}
76
77
void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {
78
O << getRegisterName(Reg);
79
}
80
81
void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum,
82
raw_ostream &O) {
83
printOperand(MI->getOperand(OpNum), O);
84
}
85
86
void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
87
raw_ostream &OS) {
88
OS << getRegisterName(MI->getOperand(OpNum).getReg());
89
OS << ", ";
90
printOperand(MI, OpNum + 1, OS);
91
}
92
93
void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
94
raw_ostream &OS) {
95
const MCOperand &MC = MI->getOperand(OpNum);
96
if (MI->getOperand(OpNum).isImm()) {
97
int64_t Val = MC.getImm() + 4;
98
OS << ". ";
99
if (Val > 0)
100
OS << '+';
101
OS << Val;
102
} else if (MC.isExpr())
103
MC.getExpr()->print(OS, &MAI, true);
104
else
105
llvm_unreachable("Invalid operand");
106
}
107
108
void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
109
raw_ostream &OS) {
110
const MCOperand &MC = MI->getOperand(OpNum);
111
if (MC.isImm()) {
112
int64_t Val = MC.getImm() + 4;
113
OS << ". ";
114
if (Val > 0)
115
OS << '+';
116
OS << Val;
117
} else if (MC.isExpr())
118
MC.getExpr()->print(OS, &MAI, true);
119
else
120
llvm_unreachable("Invalid operand");
121
;
122
}
123
124
void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
125
raw_ostream &OS) {
126
const MCOperand &MC = MI->getOperand(OpNum);
127
if (MC.isImm()) {
128
int64_t Val = MC.getImm() + 4;
129
OS << ". ";
130
if (Val > 0)
131
OS << '+';
132
OS << Val;
133
} else if (MC.isExpr())
134
MC.getExpr()->print(OS, &MAI, true);
135
else
136
llvm_unreachable("Invalid operand");
137
}
138
139
void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
140
raw_ostream &O) {
141
const MCOperand &MC = MI->getOperand(OpNum);
142
if (MC.isImm()) {
143
int64_t Value = MI->getOperand(OpNum).getImm();
144
int64_t InstrOff = Value & 0x3;
145
Value -= InstrOff;
146
assert((Value >= -262144 && Value <= -4) &&
147
"Invalid argument, value must be in ranges [-262144,-4]");
148
Value += ((InstrOff + 0x3) & 0x4) - InstrOff;
149
O << ". ";
150
O << Value;
151
} else if (MC.isExpr())
152
MC.getExpr()->print(O, &MAI, true);
153
else
154
llvm_unreachable("Invalid operand");
155
}
156
157
void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
158
raw_ostream &O) {
159
if (MI->getOperand(OpNum).isImm()) {
160
int64_t Value = MI->getOperand(OpNum).getImm();
161
assert(isInt<8>(Value) &&
162
"Invalid argument, value must be in ranges [-128,127]");
163
O << Value;
164
} else {
165
printOperand(MI, OpNum, O);
166
}
167
}
168
169
void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum,
170
raw_ostream &O) {
171
if (MI->getOperand(OpNum).isImm()) {
172
int64_t Value = MI->getOperand(OpNum).getImm();
173
assert((isInt<16>(Value) && ((Value & 0xFF) == 0)) &&
174
"Invalid argument, value must be multiples of 256 in range "
175
"[-32768,32512]");
176
O << Value;
177
} else
178
printOperand(MI, OpNum, O);
179
}
180
181
void XtensaInstPrinter::printImm12_AsmOperand(const MCInst *MI, int OpNum,
182
raw_ostream &O) {
183
if (MI->getOperand(OpNum).isImm()) {
184
int64_t Value = MI->getOperand(OpNum).getImm();
185
assert((Value >= -2048 && Value <= 2047) &&
186
"Invalid argument, value must be in ranges [-2048,2047]");
187
O << Value;
188
} else
189
printOperand(MI, OpNum, O);
190
}
191
192
void XtensaInstPrinter::printImm12m_AsmOperand(const MCInst *MI, int OpNum,
193
raw_ostream &O) {
194
if (MI->getOperand(OpNum).isImm()) {
195
int64_t Value = MI->getOperand(OpNum).getImm();
196
assert((Value >= -2048 && Value <= 2047) &&
197
"Invalid argument, value must be in ranges [-2048,2047]");
198
O << Value;
199
} else
200
printOperand(MI, OpNum, O);
201
}
202
203
void XtensaInstPrinter::printUimm4_AsmOperand(const MCInst *MI, int OpNum,
204
raw_ostream &O) {
205
if (MI->getOperand(OpNum).isImm()) {
206
int64_t Value = MI->getOperand(OpNum).getImm();
207
assert((Value >= 0 && Value <= 15) && "Invalid argument");
208
O << Value;
209
} else
210
printOperand(MI, OpNum, O);
211
}
212
213
void XtensaInstPrinter::printUimm5_AsmOperand(const MCInst *MI, int OpNum,
214
raw_ostream &O) {
215
if (MI->getOperand(OpNum).isImm()) {
216
int64_t Value = MI->getOperand(OpNum).getImm();
217
assert((Value >= 0 && Value <= 31) && "Invalid argument");
218
O << Value;
219
} else
220
printOperand(MI, OpNum, O);
221
}
222
223
void XtensaInstPrinter::printShimm1_31_AsmOperand(const MCInst *MI, int OpNum,
224
raw_ostream &O) {
225
if (MI->getOperand(OpNum).isImm()) {
226
int64_t Value = MI->getOperand(OpNum).getImm();
227
assert((Value >= 1 && Value <= 31) &&
228
"Invalid argument, value must be in range [1,31]");
229
O << Value;
230
} else
231
printOperand(MI, OpNum, O);
232
}
233
234
void XtensaInstPrinter::printImm1_16_AsmOperand(const MCInst *MI, int OpNum,
235
raw_ostream &O) {
236
if (MI->getOperand(OpNum).isImm()) {
237
int64_t Value = MI->getOperand(OpNum).getImm();
238
assert((Value >= 1 && Value <= 16) &&
239
"Invalid argument, value must be in range [1,16]");
240
O << Value;
241
} else
242
printOperand(MI, OpNum, O);
243
}
244
245
void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,
246
raw_ostream &O) {
247
if (MI->getOperand(OpNum).isImm()) {
248
int64_t Value = MI->getOperand(OpNum).getImm();
249
assert((Value >= 0 && Value <= 255) &&
250
"Invalid argument, value must be in range [0,255]");
251
O << Value;
252
} else
253
printOperand(MI, OpNum, O);
254
}
255
256
void XtensaInstPrinter::printOffset8m16_AsmOperand(const MCInst *MI, int OpNum,
257
raw_ostream &O) {
258
if (MI->getOperand(OpNum).isImm()) {
259
int64_t Value = MI->getOperand(OpNum).getImm();
260
assert((Value >= 0 && Value <= 510 && ((Value & 0x1) == 0)) &&
261
"Invalid argument, value must be multiples of two in range [0,510]");
262
O << Value;
263
} else
264
printOperand(MI, OpNum, O);
265
}
266
267
void XtensaInstPrinter::printOffset8m32_AsmOperand(const MCInst *MI, int OpNum,
268
raw_ostream &O) {
269
if (MI->getOperand(OpNum).isImm()) {
270
int64_t Value = MI->getOperand(OpNum).getImm();
271
assert(
272
(Value >= 0 && Value <= 1020 && ((Value & 0x3) == 0)) &&
273
"Invalid argument, value must be multiples of four in range [0,1020]");
274
O << Value;
275
} else
276
printOperand(MI, OpNum, O);
277
}
278
279
void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,
280
raw_ostream &O) {
281
if (MI->getOperand(OpNum).isImm()) {
282
int64_t Value = MI->getOperand(OpNum).getImm();
283
assert((Value >= 0 && Value <= 60 && ((Value & 0x3) == 0)) &&
284
"Invalid argument, value must be multiples of four in range [0,60]");
285
O << Value;
286
} else
287
printOperand(MI, OpNum, O);
288
}
289
290
void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,
291
raw_ostream &O) {
292
if (MI->getOperand(OpNum).isImm()) {
293
int64_t Value = MI->getOperand(OpNum).getImm();
294
295
switch (Value) {
296
case -1:
297
case 1:
298
case 2:
299
case 3:
300
case 4:
301
case 5:
302
case 6:
303
case 7:
304
case 8:
305
case 10:
306
case 12:
307
case 16:
308
case 32:
309
case 64:
310
case 128:
311
case 256:
312
break;
313
default:
314
assert((0) && "Invalid B4const argument");
315
}
316
O << Value;
317
} else
318
printOperand(MI, OpNum, O);
319
}
320
321
void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
322
raw_ostream &O) {
323
if (MI->getOperand(OpNum).isImm()) {
324
int64_t Value = MI->getOperand(OpNum).getImm();
325
326
switch (Value) {
327
case 32768:
328
case 65536:
329
case 2:
330
case 3:
331
case 4:
332
case 5:
333
case 6:
334
case 7:
335
case 8:
336
case 10:
337
case 12:
338
case 16:
339
case 32:
340
case 64:
341
case 128:
342
case 256:
343
break;
344
default:
345
assert((0) && "Invalid B4constu argument");
346
}
347
O << Value;
348
} else
349
printOperand(MI, OpNum, O);
350
}
351
352