LLVM 20.0.0git
NVPTXInstPrinter.cpp
Go to the documentation of this file.
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
15#include "NVPTX.h"
16#include "NVPTXUtilities.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCInstrInfo.h"
21#include "llvm/MC/MCSymbol.h"
25#include <cctype>
26using namespace llvm;
27
28#define DEBUG_TYPE "asm-printer"
29
30#include "NVPTXGenAsmWriter.inc"
31
33 const MCRegisterInfo &MRI)
34 : MCInstPrinter(MAI, MII, MRI) {}
35
37 // Decode the virtual register
38 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
39 unsigned RCId = (Reg.id() >> 28);
40 switch (RCId) {
41 default: report_fatal_error("Bad virtual register encoding");
42 case 0:
43 // This is actually a physical register, so defer to the autogenerated
44 // register printer
45 OS << getRegisterName(Reg);
46 return;
47 case 1:
48 OS << "%p";
49 break;
50 case 2:
51 OS << "%rs";
52 break;
53 case 3:
54 OS << "%r";
55 break;
56 case 4:
57 OS << "%rd";
58 break;
59 case 5:
60 OS << "%f";
61 break;
62 case 6:
63 OS << "%fd";
64 break;
65 case 7:
66 OS << "%rq";
67 break;
68 }
69
70 unsigned VReg = Reg.id() & 0x0FFFFFFF;
71 OS << VReg;
72}
73
75 StringRef Annot, const MCSubtargetInfo &STI,
76 raw_ostream &OS) {
78
79 // Next always print the annotation.
80 printAnnotation(OS, Annot);
81}
82
83void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
84 raw_ostream &O) {
85 const MCOperand &Op = MI->getOperand(OpNo);
86 if (Op.isReg()) {
87 unsigned Reg = Op.getReg();
88 printRegName(O, Reg);
89 } else if (Op.isImm()) {
90 markup(O, Markup::Immediate) << formatImm(Op.getImm());
91 } else {
92 assert(Op.isExpr() && "Unknown operand kind in printOperand");
93 Op.getExpr()->print(O, &MAI);
94 }
95}
96
98 const char *Modifier) {
99 const MCOperand &MO = MI->getOperand(OpNum);
100 int64_t Imm = MO.getImm();
101
102 if (strcmp(Modifier, "ftz") == 0) {
103 // FTZ flag
105 O << ".ftz";
106 } else if (strcmp(Modifier, "sat") == 0) {
107 // SAT flag
109 O << ".sat";
110 } else if (strcmp(Modifier, "relu") == 0) {
111 // RELU flag
113 O << ".relu";
114 } else if (strcmp(Modifier, "base") == 0) {
115 // Default operand
116 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
117 default:
118 return;
120 break;
122 O << ".rni";
123 break;
125 O << ".rzi";
126 break;
128 O << ".rmi";
129 break;
131 O << ".rpi";
132 break;
134 O << ".rn";
135 break;
137 O << ".rz";
138 break;
140 O << ".rm";
141 break;
143 O << ".rp";
144 break;
146 O << ".rna";
147 break;
148 }
149 } else {
150 llvm_unreachable("Invalid conversion modifier");
151 }
152}
153
155 const char *Modifier) {
156 const MCOperand &MO = MI->getOperand(OpNum);
157 int64_t Imm = MO.getImm();
158
159 if (strcmp(Modifier, "ftz") == 0) {
160 // FTZ flag
162 O << ".ftz";
163 } else if (strcmp(Modifier, "base") == 0) {
164 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
165 default:
166 return;
168 O << ".eq";
169 break;
171 O << ".ne";
172 break;
174 O << ".lt";
175 break;
177 O << ".le";
178 break;
180 O << ".gt";
181 break;
183 O << ".ge";
184 break;
186 O << ".lo";
187 break;
189 O << ".ls";
190 break;
192 O << ".hi";
193 break;
195 O << ".hs";
196 break;
198 O << ".equ";
199 break;
201 O << ".neu";
202 break;
204 O << ".ltu";
205 break;
207 O << ".leu";
208 break;
210 O << ".gtu";
211 break;
213 O << ".geu";
214 break;
216 O << ".num";
217 break;
219 O << ".nan";
220 break;
221 }
222 } else {
223 llvm_unreachable("Empty Modifier");
224 }
225}
226
228 raw_ostream &O, const char *Modifier) {
229 if (Modifier) {
230 const MCOperand &MO = MI->getOperand(OpNum);
231 int Imm = (int) MO.getImm();
232 if (!strcmp(Modifier, "sem")) {
233 auto Ordering = NVPTX::Ordering(Imm);
234 switch (Ordering) {
236 break;
238 O << ".volatile";
239 break;
241 O << ".relaxed.sys";
242 break;
244 O << ".acquire.sys";
245 break;
247 O << ".release.sys";
248 break;
250 O << ".mmio.relaxed.sys";
251 break;
252 default:
254 "NVPTX LdStCode Printer does not support \"{}\" sem modifier.",
255 OrderingToCString(Ordering)));
256 }
257 } else if (!strcmp(Modifier, "addsp")) {
258 switch (Imm) {
260 O << ".global";
261 break;
263 O << ".shared";
264 break;
266 O << ".local";
267 break;
269 O << ".param";
270 break;
272 O << ".const";
273 break;
275 break;
276 default:
277 llvm_unreachable("Wrong Address Space");
278 }
279 } else if (!strcmp(Modifier, "sign")) {
281 O << "s";
282 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
283 O << "u";
284 else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
285 O << "b";
286 else if (Imm == NVPTX::PTXLdStInstCode::Float)
287 O << "f";
288 else
289 llvm_unreachable("Unknown register type");
290 } else if (!strcmp(Modifier, "vec")) {
292 O << ".v2";
293 else if (Imm == NVPTX::PTXLdStInstCode::V4)
294 O << ".v4";
295 } else
296 llvm_unreachable("Unknown Modifier");
297 } else
298 llvm_unreachable("Empty Modifier");
299}
300
302 const char *Modifier) {
303 const MCOperand &MO = MI->getOperand(OpNum);
304 int Imm = (int)MO.getImm();
305 if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {
306 O << Imm; // Just print out PTX version
307 } else if (strcmp(Modifier, "aligned") == 0) {
308 // PTX63 requires '.aligned' in the name of the instruction.
309 if (Imm >= 63)
310 O << ".aligned";
311 } else
312 llvm_unreachable("Unknown Modifier");
313}
314
316 raw_ostream &O, const char *Modifier) {
317 printOperand(MI, OpNum, O);
318
319 if (Modifier && !strcmp(Modifier, "add")) {
320 O << ", ";
321 printOperand(MI, OpNum + 1, O);
322 } else {
323 if (MI->getOperand(OpNum + 1).isImm() &&
324 MI->getOperand(OpNum + 1).getImm() == 0)
325 return; // don't print ',0' or '+0'
326 O << "+";
327 printOperand(MI, OpNum + 1, O);
328 }
329}
330
332 raw_ostream &O, const char *Modifier) {
333 const MCOperand &Op = MI->getOperand(OpNum);
334 assert(Op.isExpr() && "Call prototype is not an MCExpr?");
335 const MCExpr *Expr = Op.getExpr();
336 const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
337 O << Sym.getName();
338}
339
341 raw_ostream &O, const char *Modifier) {
342 const MCOperand &MO = MI->getOperand(OpNum);
343 int64_t Imm = MO.getImm();
344
345 switch (Imm) {
346 default:
347 return;
349 break;
351 O << ".f4e";
352 break;
354 O << ".b4e";
355 break;
357 O << ".rc8";
358 break;
360 O << ".ecl";
361 break;
363 O << ".ecr";
364 break;
366 O << ".rc16";
367 break;
368 }
369}
unsigned const MachineRegisterInfo * MRI
Symbol * Sym
Definition: ELF_riscv.cpp:479
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This class represents an Operation in the Expression.
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:45
WithMarkup markup(raw_ostream &OS, Markup M) const
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printMemOperand(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
void printLdStCode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printProtoIdent(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printRegName(raw_ostream &OS, MCRegister Reg) const override
Print the assembler register name.
static const char * getRegisterName(MCRegister Reg)
void printPrmtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS) override
Print the specified MCInst to the specified raw_ostream.
void printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ RelaxedMMIO
Definition: NVPTX.h:124
@ Acquire
Definition: NVPTX.h:118
@ Relaxed
Definition: NVPTX.h:116
@ NotAtomic
Definition: NVPTX.h:113
@ Volatile
Definition: NVPTX.h:123
@ Release
Definition: NVPTX.h:119
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167