LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NVPTXInstPrinter.cpp
Go to the documentation of this file.
1 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Print MCInst instructions to .ptx format.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #define DEBUG_TYPE "asm-printer"
16 #include "NVPTX.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCSymbol.h"
25 #include <cctype>
26 using namespace llvm;
27 
28 #include "NVPTXGenAsmWriter.inc"
29 
30 
32  const MCRegisterInfo &MRI,
33  const MCSubtargetInfo &STI)
34  : MCInstPrinter(MAI, MII, MRI) {
36 }
37 
38 void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
39  // Decode the virtual register
40  // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
41  unsigned RCId = (RegNo >> 28);
42  switch (RCId) {
43  default: report_fatal_error("Bad virtual register encoding");
44  case 0:
45  // This is actually a physical register, so defer to the autogenerated
46  // register printer
47  OS << getRegisterName(RegNo);
48  return;
49  case 1:
50  OS << "%p";
51  break;
52  case 2:
53  OS << "%rs";
54  break;
55  case 3:
56  OS << "%r";
57  break;
58  case 4:
59  OS << "%rl";
60  break;
61  case 5:
62  OS << "%f";
63  break;
64  case 6:
65  OS << "%fl";
66  break;
67  }
68 
69  unsigned VReg = RegNo & 0x0FFFFFFF;
70  OS << VReg;
71 }
72 
74  StringRef Annot) {
75  printInstruction(MI, OS);
76 
77  // Next always print the annotation.
78  printAnnotation(OS, Annot);
79 }
80 
81 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
82  raw_ostream &O) {
83  const MCOperand &Op = MI->getOperand(OpNo);
84  if (Op.isReg()) {
85  unsigned Reg = Op.getReg();
86  printRegName(O, Reg);
87  } else if (Op.isImm()) {
88  O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
89  } else {
90  assert(Op.isExpr() && "Unknown operand kind in printOperand");
91  O << *Op.getExpr();
92  }
93 }
94 
96  const char *Modifier) {
97  const MCOperand &MO = MI->getOperand(OpNum);
98  int64_t Imm = MO.getImm();
99 
100  if (strcmp(Modifier, "ftz") == 0) {
101  // FTZ flag
102  if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
103  O << ".ftz";
104  } else if (strcmp(Modifier, "sat") == 0) {
105  // SAT flag
106  if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
107  O << ".sat";
108  } else if (strcmp(Modifier, "base") == 0) {
109  // Default operand
110  switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
111  default:
112  return;
114  break;
116  O << ".rni";
117  break;
119  O << ".rzi";
120  break;
122  O << ".rmi";
123  break;
125  O << ".rpi";
126  break;
128  O << ".rn";
129  break;
131  O << ".rz";
132  break;
134  O << ".rm";
135  break;
137  O << ".rp";
138  break;
139  }
140  } else {
141  llvm_unreachable("Invalid conversion modifier");
142  }
143 }
144 
146  const char *Modifier) {
147  const MCOperand &MO = MI->getOperand(OpNum);
148  int64_t Imm = MO.getImm();
149 
150  if (strcmp(Modifier, "ftz") == 0) {
151  // FTZ flag
152  if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
153  O << ".ftz";
154  } else if (strcmp(Modifier, "base") == 0) {
155  switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
156  default:
157  return;
159  O << ".eq";
160  break;
162  O << ".ne";
163  break;
165  O << ".lt";
166  break;
168  O << ".le";
169  break;
171  O << ".gt";
172  break;
174  O << ".ge";
175  break;
177  O << ".lo";
178  break;
180  O << ".ls";
181  break;
183  O << ".hi";
184  break;
186  O << ".hs";
187  break;
189  O << ".equ";
190  break;
192  O << ".neu";
193  break;
195  O << ".ltu";
196  break;
198  O << ".leu";
199  break;
201  O << ".gtu";
202  break;
204  O << ".geu";
205  break;
207  O << ".num";
208  break;
210  O << ".nan";
211  break;
212  }
213  } else {
214  llvm_unreachable("Empty Modifier");
215  }
216 }
217 
219  raw_ostream &O, const char *Modifier) {
220  if (Modifier) {
221  const MCOperand &MO = MI->getOperand(OpNum);
222  int Imm = (int) MO.getImm();
223  if (!strcmp(Modifier, "volatile")) {
224  if (Imm)
225  O << ".volatile";
226  } else if (!strcmp(Modifier, "addsp")) {
227  switch (Imm) {
229  O << ".global";
230  break;
232  O << ".shared";
233  break;
235  O << ".local";
236  break;
238  O << ".param";
239  break;
241  O << ".const";
242  break;
244  break;
245  default:
246  llvm_unreachable("Wrong Address Space");
247  }
248  } else if (!strcmp(Modifier, "sign")) {
250  O << "s";
251  else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
252  O << "u";
253  else
254  O << "f";
255  } else if (!strcmp(Modifier, "vec")) {
256  if (Imm == NVPTX::PTXLdStInstCode::V2)
257  O << ".v2";
258  else if (Imm == NVPTX::PTXLdStInstCode::V4)
259  O << ".v4";
260  } else
261  llvm_unreachable("Unknown Modifier");
262  } else
263  llvm_unreachable("Empty Modifier");
264 }
265 
267  raw_ostream &O, const char *Modifier) {
268  printOperand(MI, OpNum, O);
269 
270  if (Modifier && !strcmp(Modifier, "add")) {
271  O << ", ";
272  printOperand(MI, OpNum + 1, O);
273  } else {
274  if (MI->getOperand(OpNum + 1).isImm() &&
275  MI->getOperand(OpNum + 1).getImm() == 0)
276  return; // don't print ',0' or '+0'
277  O << "+";
278  printOperand(MI, OpNum + 1, O);
279  }
280 }
281 
283  raw_ostream &O, const char *Modifier) {
284  const MCOperand &Op = MI->getOperand(OpNum);
285  assert(Op.isExpr() && "Call prototype is not an MCExpr?");
286  const MCExpr *Expr = Op.getExpr();
287  const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
288  O << Sym.getName();
289 }
int strcmp(const char *s1, const char *s2);
bool isReg() const
Definition: MCInst.h:56
void printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
void printInstruction(const MCInst *MI, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
format_object1< int64_t > formatImm(const int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:97
#define llvm_unreachable(msg)
unsigned getReg() const
getReg - Returns the register number.
Definition: MCInst.h:63
void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
void printMemOperand(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
const MCInstrInfo & MII
bool isExpr() const
Definition: MCInst.h:59
static const char * getRegisterName(unsigned RegNo)
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const
printRegName - Print the assembler register name.
virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot)
void printLdStCode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
uint64_t getFeatureBits() const
int64_t getImm() const
Definition: MCInst.h:74
void printProtoIdent(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=0)
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:70
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
void setAvailableFeatures(uint64_t Value)
Definition: MCInstPrinter.h:81
const MCRegisterInfo & MRI
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:163
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI)