1 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // Print MCInst instructions to .ptx format.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/NVPTXInstPrinter.h"
14 #include "MCTargetDesc/NVPTXBaseInfo.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"
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);
39 default: report_fatal_error("Bad virtual register encoding");
41 // This is actually a physical register, so defer to the autogenerated
43 OS
<< getRegisterName(Reg
);
65 unsigned VReg
= Reg
.id() & 0x0FFFFFFF;
69 void NVPTXInstPrinter::printInst(const MCInst
*MI
, uint64_t Address
,
70 StringRef Annot
, const MCSubtargetInfo
&STI
,
72 printInstruction(MI
, Address
, OS
);
74 // Next always print the annotation.
75 printAnnotation(OS
, Annot
);
78 void NVPTXInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
80 const MCOperand
&Op
= MI
->getOperand(OpNo
);
82 unsigned Reg
= Op
.getReg();
84 } else if (Op
.isImm()) {
85 markup(O
, Markup::Immediate
) << formatImm(Op
.getImm());
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) {
99 if (Imm
& NVPTX::PTXCvtMode::FTZ_FLAG
)
101 } else if (strcmp(Modifier
, "sat") == 0) {
103 if (Imm
& NVPTX::PTXCvtMode::SAT_FLAG
)
105 } else if (strcmp(Modifier
, "relu") == 0) {
107 if (Imm
& NVPTX::PTXCvtMode::RELU_FLAG
)
109 } else if (strcmp(Modifier
, "base") == 0) {
111 switch (Imm
& NVPTX::PTXCvtMode::BASE_MASK
) {
114 case NVPTX::PTXCvtMode::NONE
:
116 case NVPTX::PTXCvtMode::RNI
:
119 case NVPTX::PTXCvtMode::RZI
:
122 case NVPTX::PTXCvtMode::RMI
:
125 case NVPTX::PTXCvtMode::RPI
:
128 case NVPTX::PTXCvtMode::RN
:
131 case NVPTX::PTXCvtMode::RZ
:
134 case NVPTX::PTXCvtMode::RM
:
137 case NVPTX::PTXCvtMode::RP
:
140 case NVPTX::PTXCvtMode::RNA
:
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) {
156 if (Imm
& NVPTX::PTXCmpMode::FTZ_FLAG
)
158 } else if (strcmp(Modifier
, "base") == 0) {
159 switch (Imm
& NVPTX::PTXCmpMode::BASE_MASK
) {
162 case NVPTX::PTXCmpMode::EQ
:
165 case NVPTX::PTXCmpMode::NE
:
168 case NVPTX::PTXCmpMode::LT
:
171 case NVPTX::PTXCmpMode::LE
:
174 case NVPTX::PTXCmpMode::GT
:
177 case NVPTX::PTXCmpMode::GE
:
180 case NVPTX::PTXCmpMode::LO
:
183 case NVPTX::PTXCmpMode::LS
:
186 case NVPTX::PTXCmpMode::HI
:
189 case NVPTX::PTXCmpMode::HS
:
192 case NVPTX::PTXCmpMode::EQU
:
195 case NVPTX::PTXCmpMode::NEU
:
198 case NVPTX::PTXCmpMode::LTU
:
201 case NVPTX::PTXCmpMode::LEU
:
204 case NVPTX::PTXCmpMode::GTU
:
207 case NVPTX::PTXCmpMode::GEU
:
210 case NVPTX::PTXCmpMode::NUM
:
213 case NVPTX::PTXCmpMode::NotANumber
:
218 llvm_unreachable("Empty Modifier");
222 void NVPTXInstPrinter::printLdStCode(const MCInst
*MI
, int OpNum
,
223 raw_ostream
&O
, const char *Modifier
) {
225 const MCOperand
&MO
= MI
->getOperand(OpNum
);
226 int Imm
= (int) MO
.getImm();
227 if (!strcmp(Modifier
, "volatile")) {
230 } else if (!strcmp(Modifier
, "addsp")) {
232 case NVPTX::PTXLdStInstCode::GLOBAL
:
235 case NVPTX::PTXLdStInstCode::SHARED
:
238 case NVPTX::PTXLdStInstCode::LOCAL
:
241 case NVPTX::PTXLdStInstCode::PARAM
:
244 case NVPTX::PTXLdStInstCode::CONSTANT
:
247 case NVPTX::PTXLdStInstCode::GENERIC
:
250 llvm_unreachable("Wrong Address Space");
252 } else if (!strcmp(Modifier
, "sign")) {
253 if (Imm
== NVPTX::PTXLdStInstCode::Signed
)
255 else if (Imm
== NVPTX::PTXLdStInstCode::Unsigned
)
257 else if (Imm
== NVPTX::PTXLdStInstCode::Untyped
)
259 else if (Imm
== NVPTX::PTXLdStInstCode::Float
)
262 llvm_unreachable("Unknown register type");
263 } else if (!strcmp(Modifier
, "vec")) {
264 if (Imm
== NVPTX::PTXLdStInstCode::V2
)
266 else if (Imm
== NVPTX::PTXLdStInstCode::V4
)
269 llvm_unreachable("Unknown Modifier");
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.
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")) {
294 printOperand(MI
, OpNum
+ 1, O
);
296 if (MI
->getOperand(OpNum
+ 1).isImm() &&
297 MI
->getOperand(OpNum
+ 1).getImm() == 0)
298 return; // don't print ',0' or '+0'
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();
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();
321 case NVPTX::PTXPrmtMode::NONE
:
323 case NVPTX::PTXPrmtMode::F4E
:
326 case NVPTX::PTXPrmtMode::B4E
:
329 case NVPTX::PTXPrmtMode::RC8
:
332 case NVPTX::PTXPrmtMode::ECL
:
335 case NVPTX::PTXPrmtMode::ECR
:
338 case NVPTX::PTXPrmtMode::RC16
: