Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.cpp
35295 views
1
//===-- LanaiInstPrinter.cpp - Convert Lanai 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 Lanai MCInst to a .s file.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiInstPrinter.h"
14
#include "LanaiMCExpr.h"
15
#include "LanaiAluCode.h"
16
#include "LanaiCondCode.h"
17
#include "MCTargetDesc/LanaiMCTargetDesc.h"
18
#include "llvm/MC/MCAsmInfo.h"
19
#include "llvm/MC/MCExpr.h"
20
#include "llvm/MC/MCInst.h"
21
#include "llvm/MC/MCRegisterInfo.h"
22
#include "llvm/MC/MCSymbol.h"
23
#include "llvm/Support/ErrorHandling.h"
24
#include "llvm/Support/FormattedStream.h"
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "asm-printer"
29
30
// Include the auto-generated portion of the assembly writer.
31
#define PRINT_ALIAS_INSTR
32
#include "LanaiGenAsmWriter.inc"
33
34
void LanaiInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
35
OS << StringRef(getRegisterName(Reg)).lower();
36
}
37
38
bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
39
StringRef Alias, unsigned OpNo0,
40
unsigned OpNo1) {
41
OS << "\t" << Alias << " ";
42
printOperand(MI, OpNo0, OS);
43
OS << ", ";
44
printOperand(MI, OpNo1, OS);
45
return true;
46
}
47
48
static bool usesGivenOffset(const MCInst *MI, int AddOffset) {
49
unsigned AluCode = MI->getOperand(3).getImm();
50
return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&
51
(MI->getOperand(2).getImm() == AddOffset ||
52
MI->getOperand(2).getImm() == -AddOffset);
53
}
54
55
static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {
56
unsigned AluCode = MI->getOperand(3).getImm();
57
return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);
58
}
59
60
static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {
61
unsigned AluCode = MI->getOperand(3).getImm();
62
return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);
63
}
64
65
static StringRef decIncOperator(const MCInst *MI) {
66
if (MI->getOperand(2).getImm() < 0)
67
return "--";
68
return "++";
69
}
70
71
bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,
72
raw_ostream &OS,
73
StringRef Opcode,
74
int AddOffset) {
75
if (isPreIncrementForm(MI, AddOffset)) {
76
OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"
77
<< getRegisterName(MI->getOperand(1).getReg()) << "], %"
78
<< getRegisterName(MI->getOperand(0).getReg());
79
return true;
80
}
81
if (isPostIncrementForm(MI, AddOffset)) {
82
OS << "\t" << Opcode << "\t[%"
83
<< getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)
84
<< "], %" << getRegisterName(MI->getOperand(0).getReg());
85
return true;
86
}
87
return false;
88
}
89
90
bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,
91
raw_ostream &OS,
92
StringRef Opcode,
93
int AddOffset) {
94
if (isPreIncrementForm(MI, AddOffset)) {
95
OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
96
<< ", [" << decIncOperator(MI) << "%"
97
<< getRegisterName(MI->getOperand(1).getReg()) << "]";
98
return true;
99
}
100
if (isPostIncrementForm(MI, AddOffset)) {
101
OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())
102
<< ", [%" << getRegisterName(MI->getOperand(1).getReg())
103
<< decIncOperator(MI) << "]";
104
return true;
105
}
106
return false;
107
}
108
109
bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {
110
switch (MI->getOpcode()) {
111
case Lanai::LDW_RI:
112
// ld 4[*%rN], %rX => ld [++imm], %rX
113
// ld -4[*%rN], %rX => ld [--imm], %rX
114
// ld 4[%rN*], %rX => ld [imm++], %rX
115
// ld -4[%rN*], %rX => ld [imm--], %rX
116
return printMemoryLoadIncrement(MI, OS, "ld", 4);
117
case Lanai::LDHs_RI:
118
return printMemoryLoadIncrement(MI, OS, "ld.h", 2);
119
case Lanai::LDHz_RI:
120
return printMemoryLoadIncrement(MI, OS, "uld.h", 2);
121
case Lanai::LDBs_RI:
122
return printMemoryLoadIncrement(MI, OS, "ld.b", 1);
123
case Lanai::LDBz_RI:
124
return printMemoryLoadIncrement(MI, OS, "uld.b", 1);
125
case Lanai::SW_RI:
126
// st %rX, 4[*%rN] => st %rX, [++imm]
127
// st %rX, -4[*%rN] => st %rX, [--imm]
128
// st %rX, 4[%rN*] => st %rX, [imm++]
129
// st %rX, -4[%rN*] => st %rX, [imm--]
130
return printMemoryStoreIncrement(MI, OS, "st", 4);
131
case Lanai::STH_RI:
132
return printMemoryStoreIncrement(MI, OS, "st.h", 2);
133
case Lanai::STB_RI:
134
return printMemoryStoreIncrement(MI, OS, "st.b", 1);
135
default:
136
return false;
137
}
138
}
139
140
void LanaiInstPrinter::printInst(const MCInst *MI, uint64_t Address,
141
StringRef Annotation,
142
const MCSubtargetInfo & /*STI*/,
143
raw_ostream &OS) {
144
if (!printAlias(MI, OS) && !printAliasInstr(MI, Address, OS))
145
printInstruction(MI, Address, OS);
146
printAnnotation(OS, Annotation);
147
}
148
149
void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
150
raw_ostream &OS, const char *Modifier) {
151
assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported");
152
const MCOperand &Op = MI->getOperand(OpNo);
153
if (Op.isReg())
154
OS << "%" << getRegisterName(Op.getReg());
155
else if (Op.isImm())
156
OS << formatHex(Op.getImm());
157
else {
158
assert(Op.isExpr() && "Expected an expression");
159
Op.getExpr()->print(OS, &MAI);
160
}
161
}
162
163
void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,
164
raw_ostream &OS) {
165
const MCOperand &Op = MI->getOperand(OpNo);
166
if (Op.isImm()) {
167
OS << '[' << formatHex(Op.getImm()) << ']';
168
} else {
169
// Symbolic operand will be lowered to immediate value by linker
170
assert(Op.isExpr() && "Expected an expression");
171
OS << '[';
172
Op.getExpr()->print(OS, &MAI);
173
OS << ']';
174
}
175
}
176
177
void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,
178
raw_ostream &OS) {
179
const MCOperand &Op = MI->getOperand(OpNo);
180
if (Op.isImm()) {
181
OS << formatHex(Op.getImm() << 16);
182
} else {
183
// Symbolic operand will be lowered to immediate value by linker
184
assert(Op.isExpr() && "Expected an expression");
185
Op.getExpr()->print(OS, &MAI);
186
}
187
}
188
189
void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,
190
raw_ostream &OS) {
191
const MCOperand &Op = MI->getOperand(OpNo);
192
if (Op.isImm()) {
193
OS << formatHex((Op.getImm() << 16) | 0xffff);
194
} else {
195
// Symbolic operand will be lowered to immediate value by linker
196
assert(Op.isExpr() && "Expected an expression");
197
Op.getExpr()->print(OS, &MAI);
198
}
199
}
200
201
void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,
202
raw_ostream &OS) {
203
const MCOperand &Op = MI->getOperand(OpNo);
204
if (Op.isImm()) {
205
OS << formatHex(0xffff0000 | Op.getImm());
206
} else {
207
// Symbolic operand will be lowered to immediate value by linker
208
assert(Op.isExpr() && "Expected an expression");
209
Op.getExpr()->print(OS, &MAI);
210
}
211
}
212
213
static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,
214
const MCOperand &RegOp) {
215
assert(RegOp.isReg() && "Register operand expected");
216
OS << "[";
217
if (LPAC::isPreOp(AluCode))
218
OS << "*";
219
OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());
220
if (LPAC::isPostOp(AluCode))
221
OS << "*";
222
OS << "]";
223
}
224
225
template <unsigned SizeInBits>
226
static void printMemoryImmediateOffset(const MCAsmInfo &MAI,
227
const MCOperand &OffsetOp,
228
raw_ostream &OS) {
229
assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");
230
if (OffsetOp.isImm()) {
231
assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");
232
OS << OffsetOp.getImm();
233
} else
234
OffsetOp.getExpr()->print(OS, &MAI);
235
}
236
237
void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,
238
raw_ostream &OS,
239
const char * /*Modifier*/) {
240
const MCOperand &RegOp = MI->getOperand(OpNo);
241
const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
242
const MCOperand &AluOp = MI->getOperand(OpNo + 2);
243
const unsigned AluCode = AluOp.getImm();
244
245
// Offset
246
printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);
247
248
// Register
249
printMemoryBaseRegister(OS, AluCode, RegOp);
250
}
251
252
void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,
253
raw_ostream &OS,
254
const char * /*Modifier*/) {
255
const MCOperand &RegOp = MI->getOperand(OpNo);
256
const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
257
const MCOperand &AluOp = MI->getOperand(OpNo + 2);
258
const unsigned AluCode = AluOp.getImm();
259
assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");
260
261
// [ Base OP Offset ]
262
OS << "[";
263
if (LPAC::isPreOp(AluCode))
264
OS << "*";
265
OS << "%" << getRegisterName(RegOp.getReg());
266
if (LPAC::isPostOp(AluCode))
267
OS << "*";
268
OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";
269
OS << "%" << getRegisterName(OffsetOp.getReg());
270
OS << "]";
271
}
272
273
void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,
274
raw_ostream &OS,
275
const char * /*Modifier*/) {
276
const MCOperand &RegOp = MI->getOperand(OpNo);
277
const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
278
const MCOperand &AluOp = MI->getOperand(OpNo + 2);
279
const unsigned AluCode = AluOp.getImm();
280
281
// Offset
282
printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);
283
284
// Register
285
printMemoryBaseRegister(OS, AluCode, RegOp);
286
}
287
288
void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
289
raw_ostream &OS) {
290
LPCC::CondCode CC =
291
static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
292
// Handle the undefined value here for printing so we don't abort().
293
if (CC >= LPCC::UNKNOWN)
294
OS << "<und>";
295
else
296
OS << lanaiCondCodeToString(CC);
297
}
298
299
void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
300
raw_ostream &OS) {
301
LPCC::CondCode CC =
302
static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
303
// Handle the undefined value here for printing so we don't abort().
304
if (CC >= LPCC::UNKNOWN)
305
OS << "<und>";
306
else if (CC != LPCC::ICC_T)
307
OS << "." << lanaiCondCodeToString(CC);
308
}
309
310