1 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Print MCInst instructions to .ptx format.
12 //===----------------------------------------------------------------------===//
14 #include "InstPrinter/NVPTXInstPrinter.h"
15 #include "MCTargetDesc/NVPTXBaseInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/FormattedStream.h"
27 #define DEBUG_TYPE "asm-printer"
29 #include "NVPTXGenAsmWriter.inc"
31 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
32 const MCRegisterInfo &MRI)
33 : MCInstPrinter(MAI, MII, MRI) {}
35 void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
36 // Decode the virtual register
37 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
38 unsigned RCId = (RegNo >> 28);
40 default: report_fatal_error("Bad virtual register encoding");
42 // This is actually a physical register, so defer to the autogenerated
44 OS << getRegisterName(RegNo);
66 unsigned VReg = RegNo & 0x0FFFFFFF;
70 void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
71 StringRef Annot, const MCSubtargetInfo &STI) {
72 printInstruction(MI, 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 O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
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, "base") == 0) {
107 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
110 case NVPTX::PTXCvtMode::NONE:
112 case NVPTX::PTXCvtMode::RNI:
115 case NVPTX::PTXCvtMode::RZI:
118 case NVPTX::PTXCvtMode::RMI:
121 case NVPTX::PTXCvtMode::RPI:
124 case NVPTX::PTXCvtMode::RN:
127 case NVPTX::PTXCvtMode::RZ:
130 case NVPTX::PTXCvtMode::RM:
133 case NVPTX::PTXCvtMode::RP:
138 llvm_unreachable("Invalid conversion modifier");
142 void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
143 const char *Modifier) {
144 const MCOperand &MO = MI->getOperand(OpNum);
145 int64_t Imm = MO.getImm();
147 if (strcmp(Modifier, "ftz") == 0) {
149 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
151 } else if (strcmp(Modifier, "base") == 0) {
152 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
155 case NVPTX::PTXCmpMode::EQ:
158 case NVPTX::PTXCmpMode::NE:
161 case NVPTX::PTXCmpMode::LT:
164 case NVPTX::PTXCmpMode::LE:
167 case NVPTX::PTXCmpMode::GT:
170 case NVPTX::PTXCmpMode::GE:
173 case NVPTX::PTXCmpMode::LO:
176 case NVPTX::PTXCmpMode::LS:
179 case NVPTX::PTXCmpMode::HI:
182 case NVPTX::PTXCmpMode::HS:
185 case NVPTX::PTXCmpMode::EQU:
188 case NVPTX::PTXCmpMode::NEU:
191 case NVPTX::PTXCmpMode::LTU:
194 case NVPTX::PTXCmpMode::LEU:
197 case NVPTX::PTXCmpMode::GTU:
200 case NVPTX::PTXCmpMode::GEU:
203 case NVPTX::PTXCmpMode::NUM:
206 case NVPTX::PTXCmpMode::NotANumber:
211 llvm_unreachable("Empty Modifier");
215 void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
216 raw_ostream &O, const char *Modifier) {
218 const MCOperand &MO = MI->getOperand(OpNum);
219 int Imm = (int) MO.getImm();
220 if (!strcmp(Modifier, "volatile")) {
223 } else if (!strcmp(Modifier, "addsp")) {
225 case NVPTX::PTXLdStInstCode::GLOBAL:
228 case NVPTX::PTXLdStInstCode::SHARED:
231 case NVPTX::PTXLdStInstCode::LOCAL:
234 case NVPTX::PTXLdStInstCode::PARAM:
237 case NVPTX::PTXLdStInstCode::CONSTANT:
240 case NVPTX::PTXLdStInstCode::GENERIC:
243 llvm_unreachable("Wrong Address Space");
245 } else if (!strcmp(Modifier, "sign")) {
246 if (Imm == NVPTX::PTXLdStInstCode::Signed)
248 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
252 } else if (!strcmp(Modifier, "vec")) {
253 if (Imm == NVPTX::PTXLdStInstCode::V2)
255 else if (Imm == NVPTX::PTXLdStInstCode::V4)
258 llvm_unreachable("Unknown Modifier");
260 llvm_unreachable("Empty Modifier");
263 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
264 raw_ostream &O, const char *Modifier) {
265 printOperand(MI, OpNum, O);
267 if (Modifier && !strcmp(Modifier, "add")) {
269 printOperand(MI, OpNum + 1, O);
271 if (MI->getOperand(OpNum + 1).isImm() &&
272 MI->getOperand(OpNum + 1).getImm() == 0)
273 return; // don't print ',0' or '+0'
275 printOperand(MI, OpNum + 1, O);
279 void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
280 raw_ostream &O, const char *Modifier) {
281 const MCOperand &Op = MI->getOperand(OpNum);
282 assert(Op.isExpr() && "Call prototype is not an MCExpr?");
283 const MCExpr *Expr = Op.getExpr();
284 const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();