Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.cpp
35295 views
1
//===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
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
// Print MCInst instructions to .ptx format.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MCTargetDesc/NVPTXInstPrinter.h"
14
#include "MCTargetDesc/NVPTXBaseInfo.h"
15
#include "NVPTX.h"
16
#include "llvm/MC/MCExpr.h"
17
#include "llvm/MC/MCInst.h"
18
#include "llvm/MC/MCInstrInfo.h"
19
#include "llvm/MC/MCSubtargetInfo.h"
20
#include "llvm/MC/MCSymbol.h"
21
#include "llvm/Support/ErrorHandling.h"
22
#include "llvm/Support/FormattedStream.h"
23
#include <cctype>
24
using namespace llvm;
25
26
#define DEBUG_TYPE "asm-printer"
27
28
#include "NVPTXGenAsmWriter.inc"
29
30
NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31
const MCRegisterInfo &MRI)
32
: MCInstPrinter(MAI, MII, MRI) {}
33
34
void NVPTXInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
35
// Decode the virtual register
36
// Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
37
unsigned RCId = (Reg.id() >> 28);
38
switch (RCId) {
39
default: report_fatal_error("Bad virtual register encoding");
40
case 0:
41
// This is actually a physical register, so defer to the autogenerated
42
// register printer
43
OS << getRegisterName(Reg);
44
return;
45
case 1:
46
OS << "%p";
47
break;
48
case 2:
49
OS << "%rs";
50
break;
51
case 3:
52
OS << "%r";
53
break;
54
case 4:
55
OS << "%rd";
56
break;
57
case 5:
58
OS << "%f";
59
break;
60
case 6:
61
OS << "%fd";
62
break;
63
case 7:
64
OS << "%rq";
65
break;
66
}
67
68
unsigned VReg = Reg.id() & 0x0FFFFFFF;
69
OS << VReg;
70
}
71
72
void NVPTXInstPrinter::printInst(const MCInst *MI, uint64_t Address,
73
StringRef Annot, const MCSubtargetInfo &STI,
74
raw_ostream &OS) {
75
printInstruction(MI, Address, OS);
76
77
// Next always print the annotation.
78
printAnnotation(OS, Annot);
79
}
80
81
void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
82
raw_ostream &O) {
83
const MCOperand &Op = MI->getOperand(OpNo);
84
if (Op.isReg()) {
85
unsigned Reg = Op.getReg();
86
printRegName(O, Reg);
87
} else if (Op.isImm()) {
88
markup(O, Markup::Immediate) << formatImm(Op.getImm());
89
} else {
90
assert(Op.isExpr() && "Unknown operand kind in printOperand");
91
Op.getExpr()->print(O, &MAI);
92
}
93
}
94
95
void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
96
const char *Modifier) {
97
const MCOperand &MO = MI->getOperand(OpNum);
98
int64_t Imm = MO.getImm();
99
100
if (strcmp(Modifier, "ftz") == 0) {
101
// FTZ flag
102
if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
103
O << ".ftz";
104
} else if (strcmp(Modifier, "sat") == 0) {
105
// SAT flag
106
if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
107
O << ".sat";
108
} else if (strcmp(Modifier, "relu") == 0) {
109
// RELU flag
110
if (Imm & NVPTX::PTXCvtMode::RELU_FLAG)
111
O << ".relu";
112
} else if (strcmp(Modifier, "base") == 0) {
113
// Default operand
114
switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
115
default:
116
return;
117
case NVPTX::PTXCvtMode::NONE:
118
break;
119
case NVPTX::PTXCvtMode::RNI:
120
O << ".rni";
121
break;
122
case NVPTX::PTXCvtMode::RZI:
123
O << ".rzi";
124
break;
125
case NVPTX::PTXCvtMode::RMI:
126
O << ".rmi";
127
break;
128
case NVPTX::PTXCvtMode::RPI:
129
O << ".rpi";
130
break;
131
case NVPTX::PTXCvtMode::RN:
132
O << ".rn";
133
break;
134
case NVPTX::PTXCvtMode::RZ:
135
O << ".rz";
136
break;
137
case NVPTX::PTXCvtMode::RM:
138
O << ".rm";
139
break;
140
case NVPTX::PTXCvtMode::RP:
141
O << ".rp";
142
break;
143
case NVPTX::PTXCvtMode::RNA:
144
O << ".rna";
145
break;
146
}
147
} else {
148
llvm_unreachable("Invalid conversion modifier");
149
}
150
}
151
152
void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
153
const char *Modifier) {
154
const MCOperand &MO = MI->getOperand(OpNum);
155
int64_t Imm = MO.getImm();
156
157
if (strcmp(Modifier, "ftz") == 0) {
158
// FTZ flag
159
if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
160
O << ".ftz";
161
} else if (strcmp(Modifier, "base") == 0) {
162
switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
163
default:
164
return;
165
case NVPTX::PTXCmpMode::EQ:
166
O << ".eq";
167
break;
168
case NVPTX::PTXCmpMode::NE:
169
O << ".ne";
170
break;
171
case NVPTX::PTXCmpMode::LT:
172
O << ".lt";
173
break;
174
case NVPTX::PTXCmpMode::LE:
175
O << ".le";
176
break;
177
case NVPTX::PTXCmpMode::GT:
178
O << ".gt";
179
break;
180
case NVPTX::PTXCmpMode::GE:
181
O << ".ge";
182
break;
183
case NVPTX::PTXCmpMode::LO:
184
O << ".lo";
185
break;
186
case NVPTX::PTXCmpMode::LS:
187
O << ".ls";
188
break;
189
case NVPTX::PTXCmpMode::HI:
190
O << ".hi";
191
break;
192
case NVPTX::PTXCmpMode::HS:
193
O << ".hs";
194
break;
195
case NVPTX::PTXCmpMode::EQU:
196
O << ".equ";
197
break;
198
case NVPTX::PTXCmpMode::NEU:
199
O << ".neu";
200
break;
201
case NVPTX::PTXCmpMode::LTU:
202
O << ".ltu";
203
break;
204
case NVPTX::PTXCmpMode::LEU:
205
O << ".leu";
206
break;
207
case NVPTX::PTXCmpMode::GTU:
208
O << ".gtu";
209
break;
210
case NVPTX::PTXCmpMode::GEU:
211
O << ".geu";
212
break;
213
case NVPTX::PTXCmpMode::NUM:
214
O << ".num";
215
break;
216
case NVPTX::PTXCmpMode::NotANumber:
217
O << ".nan";
218
break;
219
}
220
} else {
221
llvm_unreachable("Empty Modifier");
222
}
223
}
224
225
void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
226
raw_ostream &O, const char *Modifier) {
227
if (Modifier) {
228
const MCOperand &MO = MI->getOperand(OpNum);
229
int Imm = (int) MO.getImm();
230
if (!strcmp(Modifier, "volatile")) {
231
if (Imm)
232
O << ".volatile";
233
} else if (!strcmp(Modifier, "addsp")) {
234
switch (Imm) {
235
case NVPTX::PTXLdStInstCode::GLOBAL:
236
O << ".global";
237
break;
238
case NVPTX::PTXLdStInstCode::SHARED:
239
O << ".shared";
240
break;
241
case NVPTX::PTXLdStInstCode::LOCAL:
242
O << ".local";
243
break;
244
case NVPTX::PTXLdStInstCode::PARAM:
245
O << ".param";
246
break;
247
case NVPTX::PTXLdStInstCode::CONSTANT:
248
O << ".const";
249
break;
250
case NVPTX::PTXLdStInstCode::GENERIC:
251
break;
252
default:
253
llvm_unreachable("Wrong Address Space");
254
}
255
} else if (!strcmp(Modifier, "sign")) {
256
if (Imm == NVPTX::PTXLdStInstCode::Signed)
257
O << "s";
258
else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
259
O << "u";
260
else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
261
O << "b";
262
else if (Imm == NVPTX::PTXLdStInstCode::Float)
263
O << "f";
264
else
265
llvm_unreachable("Unknown register type");
266
} else if (!strcmp(Modifier, "vec")) {
267
if (Imm == NVPTX::PTXLdStInstCode::V2)
268
O << ".v2";
269
else if (Imm == NVPTX::PTXLdStInstCode::V4)
270
O << ".v4";
271
} else
272
llvm_unreachable("Unknown Modifier");
273
} else
274
llvm_unreachable("Empty Modifier");
275
}
276
277
void NVPTXInstPrinter::printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O,
278
const char *Modifier) {
279
const MCOperand &MO = MI->getOperand(OpNum);
280
int Imm = (int)MO.getImm();
281
if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {
282
O << Imm; // Just print out PTX version
283
} else if (strcmp(Modifier, "aligned") == 0) {
284
// PTX63 requires '.aligned' in the name of the instruction.
285
if (Imm >= 63)
286
O << ".aligned";
287
} else
288
llvm_unreachable("Unknown Modifier");
289
}
290
291
void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
292
raw_ostream &O, const char *Modifier) {
293
printOperand(MI, OpNum, O);
294
295
if (Modifier && !strcmp(Modifier, "add")) {
296
O << ", ";
297
printOperand(MI, OpNum + 1, O);
298
} else {
299
if (MI->getOperand(OpNum + 1).isImm() &&
300
MI->getOperand(OpNum + 1).getImm() == 0)
301
return; // don't print ',0' or '+0'
302
O << "+";
303
printOperand(MI, OpNum + 1, O);
304
}
305
}
306
307
void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
308
raw_ostream &O, const char *Modifier) {
309
const MCOperand &Op = MI->getOperand(OpNum);
310
assert(Op.isExpr() && "Call prototype is not an MCExpr?");
311
const MCExpr *Expr = Op.getExpr();
312
const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
313
O << Sym.getName();
314
}
315
316
void NVPTXInstPrinter::printPrmtMode(const MCInst *MI, int OpNum,
317
raw_ostream &O, const char *Modifier) {
318
const MCOperand &MO = MI->getOperand(OpNum);
319
int64_t Imm = MO.getImm();
320
321
switch (Imm) {
322
default:
323
return;
324
case NVPTX::PTXPrmtMode::NONE:
325
break;
326
case NVPTX::PTXPrmtMode::F4E:
327
O << ".f4e";
328
break;
329
case NVPTX::PTXPrmtMode::B4E:
330
O << ".b4e";
331
break;
332
case NVPTX::PTXPrmtMode::RC8:
333
O << ".rc8";
334
break;
335
case NVPTX::PTXPrmtMode::ECL:
336
O << ".ecl";
337
break;
338
case NVPTX::PTXPrmtMode::ECR:
339
O << ".ecr";
340
break;
341
case NVPTX::PTXPrmtMode::RC16:
342
O << ".rc16";
343
break;
344
}
345
}
346
347