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
, unsigned RegNo
) const {
35 // Decode the virtual register
36 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
37 unsigned RCId
= (RegNo
>> 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(RegNo
);
71 unsigned VReg
= RegNo
& 0x0FFFFFFF;
75 void NVPTXInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&OS
,
76 StringRef Annot
, const MCSubtargetInfo
&STI
) {
77 printInstruction(MI
, OS
);
79 // Next always print the annotation.
80 printAnnotation(OS
, Annot
);
83 void NVPTXInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
85 const MCOperand
&Op
= MI
->getOperand(OpNo
);
87 unsigned Reg
= Op
.getReg();
89 } else if (Op
.isImm()) {
90 O
<< markup("<imm:") << formatImm(Op
.getImm()) << markup(">");
92 assert(Op
.isExpr() && "Unknown operand kind in printOperand");
93 Op
.getExpr()->print(O
, &MAI
);
97 void NVPTXInstPrinter::printCvtMode(const MCInst
*MI
, int OpNum
, raw_ostream
&O
,
98 const char *Modifier
) {
99 const MCOperand
&MO
= MI
->getOperand(OpNum
);
100 int64_t Imm
= MO
.getImm();
102 if (strcmp(Modifier
, "ftz") == 0) {
104 if (Imm
& NVPTX::PTXCvtMode::FTZ_FLAG
)
106 } else if (strcmp(Modifier
, "sat") == 0) {
108 if (Imm
& NVPTX::PTXCvtMode::SAT_FLAG
)
110 } else if (strcmp(Modifier
, "base") == 0) {
112 switch (Imm
& NVPTX::PTXCvtMode::BASE_MASK
) {
115 case NVPTX::PTXCvtMode::NONE
:
117 case NVPTX::PTXCvtMode::RNI
:
120 case NVPTX::PTXCvtMode::RZI
:
123 case NVPTX::PTXCvtMode::RMI
:
126 case NVPTX::PTXCvtMode::RPI
:
129 case NVPTX::PTXCvtMode::RN
:
132 case NVPTX::PTXCvtMode::RZ
:
135 case NVPTX::PTXCvtMode::RM
:
138 case NVPTX::PTXCvtMode::RP
:
143 llvm_unreachable("Invalid conversion modifier");
147 void NVPTXInstPrinter::printCmpMode(const MCInst
*MI
, int OpNum
, raw_ostream
&O
,
148 const char *Modifier
) {
149 const MCOperand
&MO
= MI
->getOperand(OpNum
);
150 int64_t Imm
= MO
.getImm();
152 if (strcmp(Modifier
, "ftz") == 0) {
154 if (Imm
& NVPTX::PTXCmpMode::FTZ_FLAG
)
156 } else if (strcmp(Modifier
, "base") == 0) {
157 switch (Imm
& NVPTX::PTXCmpMode::BASE_MASK
) {
160 case NVPTX::PTXCmpMode::EQ
:
163 case NVPTX::PTXCmpMode::NE
:
166 case NVPTX::PTXCmpMode::LT
:
169 case NVPTX::PTXCmpMode::LE
:
172 case NVPTX::PTXCmpMode::GT
:
175 case NVPTX::PTXCmpMode::GE
:
178 case NVPTX::PTXCmpMode::LO
:
181 case NVPTX::PTXCmpMode::LS
:
184 case NVPTX::PTXCmpMode::HI
:
187 case NVPTX::PTXCmpMode::HS
:
190 case NVPTX::PTXCmpMode::EQU
:
193 case NVPTX::PTXCmpMode::NEU
:
196 case NVPTX::PTXCmpMode::LTU
:
199 case NVPTX::PTXCmpMode::LEU
:
202 case NVPTX::PTXCmpMode::GTU
:
205 case NVPTX::PTXCmpMode::GEU
:
208 case NVPTX::PTXCmpMode::NUM
:
211 case NVPTX::PTXCmpMode::NotANumber
:
216 llvm_unreachable("Empty Modifier");
220 void NVPTXInstPrinter::printLdStCode(const MCInst
*MI
, int OpNum
,
221 raw_ostream
&O
, const char *Modifier
) {
223 const MCOperand
&MO
= MI
->getOperand(OpNum
);
224 int Imm
= (int) MO
.getImm();
225 if (!strcmp(Modifier
, "volatile")) {
228 } else if (!strcmp(Modifier
, "addsp")) {
230 case NVPTX::PTXLdStInstCode::GLOBAL
:
233 case NVPTX::PTXLdStInstCode::SHARED
:
236 case NVPTX::PTXLdStInstCode::LOCAL
:
239 case NVPTX::PTXLdStInstCode::PARAM
:
242 case NVPTX::PTXLdStInstCode::CONSTANT
:
245 case NVPTX::PTXLdStInstCode::GENERIC
:
248 llvm_unreachable("Wrong Address Space");
250 } else if (!strcmp(Modifier
, "sign")) {
251 if (Imm
== NVPTX::PTXLdStInstCode::Signed
)
253 else if (Imm
== NVPTX::PTXLdStInstCode::Unsigned
)
255 else if (Imm
== NVPTX::PTXLdStInstCode::Untyped
)
257 else if (Imm
== NVPTX::PTXLdStInstCode::Float
)
260 llvm_unreachable("Unknown register type");
261 } else if (!strcmp(Modifier
, "vec")) {
262 if (Imm
== NVPTX::PTXLdStInstCode::V2
)
264 else if (Imm
== NVPTX::PTXLdStInstCode::V4
)
267 llvm_unreachable("Unknown Modifier");
269 llvm_unreachable("Empty Modifier");
272 void NVPTXInstPrinter::printMmaCode(const MCInst
*MI
, int OpNum
, raw_ostream
&O
,
273 const char *Modifier
) {
274 const MCOperand
&MO
= MI
->getOperand(OpNum
);
275 int Imm
= (int)MO
.getImm();
276 if (Modifier
== nullptr || strcmp(Modifier
, "version") == 0) {
277 O
<< Imm
; // Just print out PTX version
278 } else if (strcmp(Modifier
, "aligned") == 0) {
279 // PTX63 requires '.aligned' in the name of the instruction.
283 llvm_unreachable("Unknown Modifier");
286 void NVPTXInstPrinter::printMemOperand(const MCInst
*MI
, int OpNum
,
287 raw_ostream
&O
, const char *Modifier
) {
288 printOperand(MI
, OpNum
, O
);
290 if (Modifier
&& !strcmp(Modifier
, "add")) {
292 printOperand(MI
, OpNum
+ 1, O
);
294 if (MI
->getOperand(OpNum
+ 1).isImm() &&
295 MI
->getOperand(OpNum
+ 1).getImm() == 0)
296 return; // don't print ',0' or '+0'
298 printOperand(MI
, OpNum
+ 1, O
);
302 void NVPTXInstPrinter::printProtoIdent(const MCInst
*MI
, int OpNum
,
303 raw_ostream
&O
, const char *Modifier
) {
304 const MCOperand
&Op
= MI
->getOperand(OpNum
);
305 assert(Op
.isExpr() && "Call prototype is not an MCExpr?");
306 const MCExpr
*Expr
= Op
.getExpr();
307 const MCSymbol
&Sym
= cast
<MCSymbolRefExpr
>(Expr
)->getSymbol();