LLVM 23.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
14#include "NVPTX.h"
15#include "NVPTXUtilities.h"
16#include "llvm/ADT/StringRef.h"
18#include "llvm/MC/MCAsmInfo.h"
19#include "llvm/MC/MCExpr.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
23#include "llvm/MC/MCSymbol.h"
26#include <cctype>
27using namespace llvm;
28
29#define DEBUG_TYPE "asm-printer"
30
31#define GET_SUBTARGETINFO_ENUM
32#include "NVPTXGenSubtargetInfo.inc"
33
34#include "NVPTXGenAsmWriter.inc"
35
36static bool hasParamSubqualifiers(const MCSubtargetInfo &STI) {
37 return STI.hasFeature(NVPTX::PTX83);
38}
39
43
45 // Decode the virtual register
46 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
47 unsigned RCId = (Reg.id() >> 28);
48 switch (RCId) {
49 default: report_fatal_error("Bad virtual register encoding");
50 case 0:
51 // This is actually a physical register, so defer to the autogenerated
52 // register printer
53 OS << getRegisterName(Reg);
54 return;
55 case 1:
56 OS << "%p";
57 break;
58 case 2:
59 OS << "%rs";
60 break;
61 case 3:
62 OS << "%r";
63 break;
64 case 4:
65 OS << "%rd";
66 break;
67 case 5:
68 OS << "%f";
69 break;
70 case 6:
71 OS << "%fd";
72 break;
73 case 7:
74 OS << "%rq";
75 break;
76 }
77
78 unsigned VReg = Reg.id() & 0x0FFFFFFF;
79 OS << VReg;
80}
81
83 StringRef Annot, const MCSubtargetInfo &STI,
84 raw_ostream &OS) {
85 printInstruction(MI, Address, STI, OS);
86
87 // Next always print the annotation.
88 printAnnotation(OS, Annot);
89}
90
91void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
92 const MCSubtargetInfo &, raw_ostream &O) {
93 const MCOperand &Op = MI->getOperand(OpNo);
94 if (Op.isReg()) {
95 MCRegister Reg = Op.getReg();
96 printRegName(O, Reg);
97 } else if (Op.isImm()) {
98 markup(O, Markup::Immediate) << formatImm(Op.getImm());
99 } else {
100 assert(Op.isExpr() && "Unknown operand kind in printOperand");
101 MAI.printExpr(O, *Op.getExpr());
102 }
103}
104
106 const MCSubtargetInfo &, raw_ostream &O,
107 StringRef Modifier) {
108 const MCOperand &MO = MI->getOperand(OpNum);
109 int64_t Imm = MO.getImm();
110
111 if (Modifier == "ftz") {
112 // FTZ flag
114 O << ".ftz";
115 return;
116 } else if (Modifier == "sat") {
117 // SAT flag
119 O << ".sat";
120 return;
121 } else if (Modifier == "satfinite") {
122 // SATFINITE flag
124 O << ".satfinite";
125 return;
126 } else if (Modifier == "relu") {
127 // RELU flag
129 O << ".relu";
130 return;
131 } else if (Modifier == "base") {
132 // Default operand
133 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
134 default:
135 return;
137 return;
139 O << ".rni";
140 return;
142 O << ".rzi";
143 return;
145 O << ".rmi";
146 return;
148 O << ".rpi";
149 return;
151 O << ".rn";
152 return;
154 O << ".rz";
155 return;
157 O << ".rm";
158 return;
160 O << ".rp";
161 return;
163 O << ".rna";
164 return;
166 O << ".rs";
167 return;
168 }
169 }
170 llvm_unreachable("Invalid conversion modifier");
171}
172
174 const MCSubtargetInfo &, raw_ostream &O) {
175 const MCOperand &MO = MI->getOperand(OpNum);
176 const int Imm = MO.getImm();
177 if (Imm)
178 O << ".ftz";
179}
180
182 const MCSubtargetInfo &, raw_ostream &O,
183 StringRef Modifier) {
184 const MCOperand &MO = MI->getOperand(OpNum);
185 int64_t Imm = MO.getImm();
186
187 if (Modifier == "FCmp") {
188 switch (Imm) {
189 default:
190 return;
192 O << "eq";
193 return;
195 O << "ne";
196 return;
198 O << "lt";
199 return;
201 O << "le";
202 return;
204 O << "gt";
205 return;
207 O << "ge";
208 return;
210 O << "equ";
211 return;
213 O << "neu";
214 return;
216 O << "ltu";
217 return;
219 O << "leu";
220 return;
222 O << "gtu";
223 return;
225 O << "geu";
226 return;
228 O << "num";
229 return;
231 O << "nan";
232 return;
233 }
234 }
235 if (Modifier == "ICmp") {
236 switch (Imm) {
237 default:
238 llvm_unreachable("Invalid ICmp mode");
240 O << "eq";
241 return;
243 O << "ne";
244 return;
247 O << "lt";
248 return;
251 O << "le";
252 return;
255 O << "gt";
256 return;
259 O << "ge";
260 return;
261 }
262 }
263 if (Modifier == "IType") {
264 switch (Imm) {
265 default:
266 llvm_unreachable("Invalid IType");
269 O << "b";
270 return;
275 O << "s";
276 return;
281 O << "u";
282 return;
283 }
284 }
285 llvm_unreachable("Empty Modifier");
286}
287
289 const MCSubtargetInfo &STI,
290 raw_ostream &O, StringRef Modifier) {
291 const MCOperand &MO = MI->getOperand(OpNum);
292 int Imm = (int)MO.getImm();
293 if (Modifier == "sem") {
294 auto Ordering = NVPTX::Ordering(Imm);
295 switch (Ordering) {
297 return;
299 O << ".relaxed";
300 return;
302 O << ".acquire";
303 return;
305 O << ".release";
306 return;
308 O << ".acq_rel";
309 return;
312 "NVPTX AtomicCode Printer does not support \"seq_cst\" ordering.");
313 return;
315 O << ".volatile";
316 return;
318 O << ".mmio.relaxed";
319 return;
320 }
321 } else if (Modifier == "scope") {
322 auto S = NVPTX::Scope(Imm);
323 switch (S) {
326 return;
328 O << ".sys";
329 return;
331 O << ".cta";
332 return;
334 O << ".cluster";
335 return;
337 O << ".gpu";
338 return;
339 }
341 "NVPTX AtomicCode Printer does not support \"{}\" scope modifier.",
342 ScopeToString(S)));
343 } else if (Modifier == "addsp") {
344 auto A = NVPTX::AddressSpace(Imm);
345 switch (A) {
347 return;
355 O << "." << addressSpaceToString(A, hasParamSubqualifiers(STI));
356 return;
357 }
359 "NVPTX AtomicCode Printer does not support \"{}\" addsp modifier.",
360 addressSpaceToString(A)));
361 } else if (Modifier == "sign") {
362 switch (Imm) {
364 O << "s";
365 return;
367 O << "u";
368 return;
370 O << "b";
371 return;
373 O << "f";
374 return;
375 default:
376 llvm_unreachable("Unknown register type");
377 }
378 }
379 llvm_unreachable(formatv("Unknown Modifier: {}", Modifier).str().c_str());
380}
381
383 const MCSubtargetInfo &, raw_ostream &O,
384 StringRef Modifier) {
385 const MCOperand &MO = MI->getOperand(OpNum);
386 int Imm = (int)MO.getImm();
387 if (Modifier.empty() || Modifier == "version") {
388 O << Imm; // Just print out PTX version
389 return;
390 } else if (Modifier == "aligned") {
391 // PTX63 requires '.aligned' in the name of the instruction.
392 if (Imm >= 63)
393 O << ".aligned";
394 return;
395 }
396 llvm_unreachable("Unknown Modifier");
397}
398
400 const MCSubtargetInfo &STI,
401 raw_ostream &O, StringRef Modifier) {
402 printOperand(MI, OpNum, STI, O);
403
404 if (Modifier == "add") {
405 O << ", ";
406 printOperand(MI, OpNum + 1, STI, O);
407 } else {
408 if (MI->getOperand(OpNum + 1).isImm() &&
409 MI->getOperand(OpNum + 1).getImm() == 0)
410 return; // don't print ',0' or '+0'
411 O << "+";
412 printOperand(MI, OpNum + 1, STI, O);
413 }
414}
415
417 const MCSubtargetInfo &,
418 raw_ostream &O) {
419 auto &Op = MI->getOperand(OpNum);
420 assert(Op.isImm() && "Invalid operand");
421 uint32_t Imm = (uint32_t)Op.getImm();
422 if (Imm != UINT32_MAX) {
423 O << ".pragma \"used_bytes_mask " << format_hex(Imm, 1) << "\";\n\t";
424 }
425}
426
428 const MCSubtargetInfo &STI,
429 raw_ostream &O) {
430 const MCOperand &Op = MI->getOperand(OpNum);
431 if (Op.isReg() && Op.getReg() == MCRegister::NoRegister)
432 O << "_";
433 else
434 printOperand(MI, OpNum, STI, O);
435}
436
438 const MCSubtargetInfo &, raw_ostream &O) {
439 int64_t Imm = MI->getOperand(OpNum).getImm();
440 O << formatHex(Imm) << "U";
441}
442
444 const MCSubtargetInfo &,
445 raw_ostream &O) {
446 const MCOperand &Op = MI->getOperand(OpNum);
447 assert(Op.isExpr() && "Call prototype is not an MCExpr?");
448 const MCExpr *Expr = Op.getExpr();
449 const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
450 O << Sym.getName();
451}
452
454 const MCSubtargetInfo &, raw_ostream &O) {
455 const MCOperand &MO = MI->getOperand(OpNum);
456 int64_t Imm = MO.getImm();
457
458 switch (Imm) {
459 default:
460 return;
462 return;
464 O << ".f4e";
465 return;
467 O << ".b4e";
468 return;
470 O << ".rc8";
471 return;
473 O << ".ecl";
474 return;
476 O << ".ecr";
477 return;
479 O << ".rc16";
480 return;
481 }
482}
483
485 const MCSubtargetInfo &,
486 raw_ostream &O) {
487 const MCOperand &MO = MI->getOperand(OpNum);
488 using RedTy = nvvm::TMAReductionOp;
489
490 switch (static_cast<RedTy>(MO.getImm())) {
491 case RedTy::ADD:
492 O << ".add";
493 return;
494 case RedTy::MIN:
495 O << ".min";
496 return;
497 case RedTy::MAX:
498 O << ".max";
499 return;
500 case RedTy::INC:
501 O << ".inc";
502 return;
503 case RedTy::DEC:
504 O << ".dec";
505 return;
506 case RedTy::AND:
507 O << ".and";
508 return;
509 case RedTy::OR:
510 O << ".or";
511 return;
512 case RedTy::XOR:
513 O << ".xor";
514 return;
515 }
517 "Invalid Reduction Op in printCpAsyncBulkTensorReductionMode");
518}
519
521 const MCSubtargetInfo &, raw_ostream &O) {
522 const MCOperand &MO = MI->getOperand(OpNum);
523 using CGTy = nvvm::CTAGroupKind;
524
525 switch (static_cast<CGTy>(MO.getImm())) {
526 case CGTy::CG_NONE:
527 O << "";
528 return;
529 case CGTy::CG_1:
530 O << ".cta_group::1";
531 return;
532 case CGTy::CG_2:
533 O << ".cta_group::2";
534 return;
535 }
536 llvm_unreachable("Invalid cta_group in printCTAGroup");
537}
538
540 const MCSubtargetInfo &, raw_ostream &O,
541 StringRef Modifier) {
542 const MCOperand &MO = MI->getOperand(OpNum);
543 assert(MO.isImm() && "Invalid operand");
544 const auto Imm = MO.getImm();
545
546 if (Modifier == "RetList") {
547 assert((Imm == 1 || Imm == 0) && "Invalid return list");
548 if (Imm)
549 O << " (retval0),";
550 return;
551 }
552
553 if (Modifier == "ParamList") {
554 assert(Imm >= 0 && "Invalid parameter list");
556 [&](const auto &I) { O << "param" << I; });
557 return;
558 }
559 llvm_unreachable("Invalid modifier");
560}
561
562template <unsigned Bits>
564 const MCSubtargetInfo &, raw_ostream &O) {
565 const MCOperand &MO = MI->getOperand(OpNum);
566 assert(MO.isImm() && "Expected immediate operand");
567 assert(isInt<Bits>(MO.getImm()) &&
568 "Immediate value does not fit in specified bits");
569 uint64_t Imm = MO.getImm();
570 Imm &= maskTrailingOnes<uint64_t>(Bits);
571 O << formatHex(Imm) << "U";
572}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
static bool hasParamSubqualifiers(const MCSubtargetInfo &STI)
This file contains the definitions of the enumerations and flags associated with NVVM Intrinsics,...
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition MCAsmInfo.h:64
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
WithMarkup markup(raw_ostream &OS, Markup M)
format_object< int64_t > formatHex(int64_t Value) const
const MCInstrInfo & MII
const MCRegisterInfo & MRI
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri)
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
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:41
static constexpr unsigned NoRegister
Definition MCRegister.h:60
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
void printRegName(raw_ostream &OS, MCRegister Reg) override
Print the assembler register name.
void printMemOperand(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
void printAtomicCode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O)
void printMmaCode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
void printTmaReductionMode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCallOperand(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
void printProtoIdent(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCmpMode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
static const char * getRegisterName(MCRegister Reg)
void printPrmtMode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printUsedBytesMaskPragma(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printRegisterOrSinkSymbol(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printHexu32imm(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printCvtMode(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O, StringRef Modifier={})
void printFTZFlag(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
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 printCTAGroup(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
void printHexUImm(const MCInst *MI, int OpNum, const MCSubtargetInfo &STI, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O)
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ DeviceParam
Definition NVPTX.h:214
@ SharedCluster
Definition NVPTX.h:207
@ EntryParam
Definition NVPTX.h:208
@ DefaultDevice
Definition NVPTX.h:196
@ RelaxedMMIO
Definition NVPTX.h:186
@ AcquireRelease
Definition NVPTX.h:182
@ NotAtomic
Definition NVPTX.h:175
@ SequentiallyConsistent
Definition NVPTX.h:183
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
void interleaveComma(const Container &c, StreamT &os, UnaryFunctor each_fn)
Definition STLExtras.h:2313
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition Format.h:191
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:77