Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / NVPTX / MCTargetDesc / NVPTXInstPrinter.cpp
blobb7a20c351f5ff6ff8a0aee458efb8e5c6e8d8e76
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.
11 //===----------------------------------------------------------------------===//
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;
26 #define DEBUG_TYPE "asm-printer"
28 #include "NVPTXGenAsmWriter.inc"
30 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31 const MCRegisterInfo &MRI)
32 : MCInstPrinter(MAI, MII, MRI) {}
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;
65 unsigned VReg = Reg.id() & 0x0FFFFFFF;
66 OS << VReg;
69 void NVPTXInstPrinter::printInst(const MCInst *MI, uint64_t Address,
70 StringRef Annot, const MCSubtargetInfo &STI,
71 raw_ostream &OS) {
72 printInstruction(MI, Address, OS);
74 // Next always print the annotation.
75 printAnnotation(OS, Annot);
78 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
79 raw_ostream &O) {
80 const MCOperand &Op = MI->getOperand(OpNo);
81 if (Op.isReg()) {
82 unsigned Reg = Op.getReg();
83 printRegName(O, Reg);
84 } else if (Op.isImm()) {
85 markup(O, Markup::Immediate) << formatImm(Op.getImm());
86 } else {
87 assert(Op.isExpr() && "Unknown operand kind in printOperand");
88 Op.getExpr()->print(O, &MAI);
92 void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
93 const char *Modifier) {
94 const MCOperand &MO = MI->getOperand(OpNum);
95 int64_t Imm = MO.getImm();
97 if (strcmp(Modifier, "ftz") == 0) {
98 // FTZ flag
99 if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
100 O << ".ftz";
101 } else if (strcmp(Modifier, "sat") == 0) {
102 // SAT flag
103 if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
104 O << ".sat";
105 } else if (strcmp(Modifier, "relu") == 0) {
106 // RELU flag
107 if (Imm & NVPTX::PTXCvtMode::RELU_FLAG)
108 O << ".relu";
109 } else if (strcmp(Modifier, "base") == 0) {
110 // Default operand
111 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
112 default:
113 return;
114 case NVPTX::PTXCvtMode::NONE:
115 break;
116 case NVPTX::PTXCvtMode::RNI:
117 O << ".rni";
118 break;
119 case NVPTX::PTXCvtMode::RZI:
120 O << ".rzi";
121 break;
122 case NVPTX::PTXCvtMode::RMI:
123 O << ".rmi";
124 break;
125 case NVPTX::PTXCvtMode::RPI:
126 O << ".rpi";
127 break;
128 case NVPTX::PTXCvtMode::RN:
129 O << ".rn";
130 break;
131 case NVPTX::PTXCvtMode::RZ:
132 O << ".rz";
133 break;
134 case NVPTX::PTXCvtMode::RM:
135 O << ".rm";
136 break;
137 case NVPTX::PTXCvtMode::RP:
138 O << ".rp";
139 break;
140 case NVPTX::PTXCvtMode::RNA:
141 O << ".rna";
142 break;
144 } else {
145 llvm_unreachable("Invalid conversion modifier");
149 void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
150 const char *Modifier) {
151 const MCOperand &MO = MI->getOperand(OpNum);
152 int64_t Imm = MO.getImm();
154 if (strcmp(Modifier, "ftz") == 0) {
155 // FTZ flag
156 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
157 O << ".ftz";
158 } else if (strcmp(Modifier, "base") == 0) {
159 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
160 default:
161 return;
162 case NVPTX::PTXCmpMode::EQ:
163 O << ".eq";
164 break;
165 case NVPTX::PTXCmpMode::NE:
166 O << ".ne";
167 break;
168 case NVPTX::PTXCmpMode::LT:
169 O << ".lt";
170 break;
171 case NVPTX::PTXCmpMode::LE:
172 O << ".le";
173 break;
174 case NVPTX::PTXCmpMode::GT:
175 O << ".gt";
176 break;
177 case NVPTX::PTXCmpMode::GE:
178 O << ".ge";
179 break;
180 case NVPTX::PTXCmpMode::LO:
181 O << ".lo";
182 break;
183 case NVPTX::PTXCmpMode::LS:
184 O << ".ls";
185 break;
186 case NVPTX::PTXCmpMode::HI:
187 O << ".hi";
188 break;
189 case NVPTX::PTXCmpMode::HS:
190 O << ".hs";
191 break;
192 case NVPTX::PTXCmpMode::EQU:
193 O << ".equ";
194 break;
195 case NVPTX::PTXCmpMode::NEU:
196 O << ".neu";
197 break;
198 case NVPTX::PTXCmpMode::LTU:
199 O << ".ltu";
200 break;
201 case NVPTX::PTXCmpMode::LEU:
202 O << ".leu";
203 break;
204 case NVPTX::PTXCmpMode::GTU:
205 O << ".gtu";
206 break;
207 case NVPTX::PTXCmpMode::GEU:
208 O << ".geu";
209 break;
210 case NVPTX::PTXCmpMode::NUM:
211 O << ".num";
212 break;
213 case NVPTX::PTXCmpMode::NotANumber:
214 O << ".nan";
215 break;
217 } else {
218 llvm_unreachable("Empty Modifier");
222 void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
223 raw_ostream &O, const char *Modifier) {
224 if (Modifier) {
225 const MCOperand &MO = MI->getOperand(OpNum);
226 int Imm = (int) MO.getImm();
227 if (!strcmp(Modifier, "volatile")) {
228 if (Imm)
229 O << ".volatile";
230 } else if (!strcmp(Modifier, "addsp")) {
231 switch (Imm) {
232 case NVPTX::PTXLdStInstCode::GLOBAL:
233 O << ".global";
234 break;
235 case NVPTX::PTXLdStInstCode::SHARED:
236 O << ".shared";
237 break;
238 case NVPTX::PTXLdStInstCode::LOCAL:
239 O << ".local";
240 break;
241 case NVPTX::PTXLdStInstCode::PARAM:
242 O << ".param";
243 break;
244 case NVPTX::PTXLdStInstCode::CONSTANT:
245 O << ".const";
246 break;
247 case NVPTX::PTXLdStInstCode::GENERIC:
248 break;
249 default:
250 llvm_unreachable("Wrong Address Space");
252 } else if (!strcmp(Modifier, "sign")) {
253 if (Imm == NVPTX::PTXLdStInstCode::Signed)
254 O << "s";
255 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
256 O << "u";
257 else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
258 O << "b";
259 else if (Imm == NVPTX::PTXLdStInstCode::Float)
260 O << "f";
261 else
262 llvm_unreachable("Unknown register type");
263 } else if (!strcmp(Modifier, "vec")) {
264 if (Imm == NVPTX::PTXLdStInstCode::V2)
265 O << ".v2";
266 else if (Imm == NVPTX::PTXLdStInstCode::V4)
267 O << ".v4";
268 } else
269 llvm_unreachable("Unknown Modifier");
270 } else
271 llvm_unreachable("Empty Modifier");
274 void NVPTXInstPrinter::printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O,
275 const char *Modifier) {
276 const MCOperand &MO = MI->getOperand(OpNum);
277 int Imm = (int)MO.getImm();
278 if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {
279 O << Imm; // Just print out PTX version
280 } else if (strcmp(Modifier, "aligned") == 0) {
281 // PTX63 requires '.aligned' in the name of the instruction.
282 if (Imm >= 63)
283 O << ".aligned";
284 } else
285 llvm_unreachable("Unknown Modifier");
288 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
289 raw_ostream &O, const char *Modifier) {
290 printOperand(MI, OpNum, O);
292 if (Modifier && !strcmp(Modifier, "add")) {
293 O << ", ";
294 printOperand(MI, OpNum + 1, O);
295 } else {
296 if (MI->getOperand(OpNum + 1).isImm() &&
297 MI->getOperand(OpNum + 1).getImm() == 0)
298 return; // don't print ',0' or '+0'
299 O << "+";
300 printOperand(MI, OpNum + 1, O);
304 void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
305 raw_ostream &O, const char *Modifier) {
306 const MCOperand &Op = MI->getOperand(OpNum);
307 assert(Op.isExpr() && "Call prototype is not an MCExpr?");
308 const MCExpr *Expr = Op.getExpr();
309 const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
310 O << Sym.getName();
313 void NVPTXInstPrinter::printPrmtMode(const MCInst *MI, int OpNum,
314 raw_ostream &O, const char *Modifier) {
315 const MCOperand &MO = MI->getOperand(OpNum);
316 int64_t Imm = MO.getImm();
318 switch (Imm) {
319 default:
320 return;
321 case NVPTX::PTXPrmtMode::NONE:
322 break;
323 case NVPTX::PTXPrmtMode::F4E:
324 O << ".f4e";
325 break;
326 case NVPTX::PTXPrmtMode::B4E:
327 O << ".b4e";
328 break;
329 case NVPTX::PTXPrmtMode::RC8:
330 O << ".rc8";
331 break;
332 case NVPTX::PTXPrmtMode::ECL:
333 O << ".ecl";
334 break;
335 case NVPTX::PTXPrmtMode::ECR:
336 O << ".ecr";
337 break;
338 case NVPTX::PTXPrmtMode::RC16:
339 O << ".rc16";
340 break;