LLVM  8.0.1
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 
16 #include "NVPTX.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCSymbol.h"
24 #include <cctype>
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "asm-printer"
28 
29 #include "NVPTXGenAsmWriter.inc"
30 
32  const MCRegisterInfo &MRI)
33  : MCInstPrinter(MAI, MII, MRI) {}
34 
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);
39  switch (RCId) {
40  default: report_fatal_error("Bad virtual register encoding");
41  case 0:
42  // This is actually a physical register, so defer to the autogenerated
43  // register printer
44  OS << getRegisterName(RegNo);
45  return;
46  case 1:
47  OS << "%p";
48  break;
49  case 2:
50  OS << "%rs";
51  break;
52  case 3:
53  OS << "%r";
54  break;
55  case 4:
56  OS << "%rd";
57  break;
58  case 5:
59  OS << "%f";
60  break;
61  case 6:
62  OS << "%fd";
63  break;
64  case 7:
65  OS << "%h";
66  break;
67  case 8:
68  OS << "%hh";
69  break;
70  }
71 
72  unsigned VReg = RegNo & 0x0FFFFFFF;
73  OS << VReg;
74 }
75 
77  StringRef Annot, const MCSubtargetInfo &STI) {
78  printInstruction(MI, OS);
79 
80  // Next always print the annotation.
81  printAnnotation(OS, Annot);
82 }
83 
84 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
85  raw_ostream &O) {
86  const MCOperand &Op = MI->getOperand(OpNo);
87  if (Op.isReg()) {
88  unsigned Reg = Op.getReg();
89  printRegName(O, Reg);
90  } else if (Op.isImm()) {
91  O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
92  } else {
93  assert(Op.isExpr() && "Unknown operand kind in printOperand");
94  Op.getExpr()->print(O, &MAI);
95  }
96 }
97 
99  const char *Modifier) {
100  const MCOperand &MO = MI->getOperand(OpNum);
101  int64_t Imm = MO.getImm();
102 
103  if (strcmp(Modifier, "ftz") == 0) {
104  // FTZ flag
105  if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
106  O << ".ftz";
107  } else if (strcmp(Modifier, "sat") == 0) {
108  // SAT flag
109  if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
110  O << ".sat";
111  } else if (strcmp(Modifier, "base") == 0) {
112  // Default operand
113  switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
114  default:
115  return;
117  break;
119  O << ".rni";
120  break;
122  O << ".rzi";
123  break;
125  O << ".rmi";
126  break;
128  O << ".rpi";
129  break;
131  O << ".rn";
132  break;
134  O << ".rz";
135  break;
137  O << ".rm";
138  break;
140  O << ".rp";
141  break;
142  }
143  } else {
144  llvm_unreachable("Invalid conversion modifier");
145  }
146 }
147 
149  const char *Modifier) {
150  const MCOperand &MO = MI->getOperand(OpNum);
151  int64_t Imm = MO.getImm();
152 
153  if (strcmp(Modifier, "ftz") == 0) {
154  // FTZ flag
155  if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
156  O << ".ftz";
157  } else if (strcmp(Modifier, "base") == 0) {
158  switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
159  default:
160  return;
162  O << ".eq";
163  break;
165  O << ".ne";
166  break;
168  O << ".lt";
169  break;
171  O << ".le";
172  break;
174  O << ".gt";
175  break;
177  O << ".ge";
178  break;
180  O << ".lo";
181  break;
183  O << ".ls";
184  break;
186  O << ".hi";
187  break;
189  O << ".hs";
190  break;
192  O << ".equ";
193  break;
195  O << ".neu";
196  break;
198  O << ".ltu";
199  break;
201  O << ".leu";
202  break;
204  O << ".gtu";
205  break;
207  O << ".geu";
208  break;
210  O << ".num";
211  break;
213  O << ".nan";
214  break;
215  }
216  } else {
217  llvm_unreachable("Empty Modifier");
218  }
219 }
220 
222  raw_ostream &O, const char *Modifier) {
223  if (Modifier) {
224  const MCOperand &MO = MI->getOperand(OpNum);
225  int Imm = (int) MO.getImm();
226  if (!strcmp(Modifier, "volatile")) {
227  if (Imm)
228  O << ".volatile";
229  } else if (!strcmp(Modifier, "addsp")) {
230  switch (Imm) {
232  O << ".global";
233  break;
235  O << ".shared";
236  break;
238  O << ".local";
239  break;
241  O << ".param";
242  break;
244  O << ".const";
245  break;
247  break;
248  default:
249  llvm_unreachable("Wrong Address Space");
250  }
251  } else if (!strcmp(Modifier, "sign")) {
253  O << "s";
254  else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
255  O << "u";
256  else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
257  O << "b";
258  else if (Imm == NVPTX::PTXLdStInstCode::Float)
259  O << "f";
260  else
261  llvm_unreachable("Unknown register type");
262  } else if (!strcmp(Modifier, "vec")) {
263  if (Imm == NVPTX::PTXLdStInstCode::V2)
264  O << ".v2";
265  else if (Imm == NVPTX::PTXLdStInstCode::V4)
266  O << ".v4";
267  } else
268  llvm_unreachable("Unknown Modifier");
269  } else
270  llvm_unreachable("Empty Modifier");
271 }
272 
274  raw_ostream &O, const char *Modifier) {
275  printOperand(MI, OpNum, O);
276 
277  if (Modifier && !strcmp(Modifier, "add")) {
278  O << ", ";
279  printOperand(MI, OpNum + 1, O);
280  } else {
281  if (MI->getOperand(OpNum + 1).isImm() &&
282  MI->getOperand(OpNum + 1).getImm() == 0)
283  return; // don't print ',0' or '+0'
284  O << "+";
285  printOperand(MI, OpNum + 1, O);
286  }
287 }
288 
290  raw_ostream &O, const char *Modifier) {
291  const MCOperand &Op = MI->getOperand(OpNum);
292  assert(Op.isExpr() && "Call prototype is not an MCExpr?");
293  const MCExpr *Expr = Op.getExpr();
294  const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
295  O << Sym.getName();
296 }
void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
bool isImm() const
Definition: MCInst.h:59
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
void printInstruction(const MCInst *MI, raw_ostream &O)
void printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
unsigned Reg
bool isReg() const
Definition: MCInst.h:58
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
void printMemOperand(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:96
const MCExpr * getExpr() const
Definition: MCInst.h:96
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Definition: ELF.h:337
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
void printLdStCode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
int64_t getImm() const
Definition: MCInst.h:76
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:42
unsigned const MachineRegisterInfo * MRI
StringRef markup(StringRef s) const
Utility functions to make adding mark ups simpler.
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
static const char * getRegisterName(unsigned RegNo)
bool isExpr() const
Definition: MCInst.h:61
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:46
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:40
Generic base class for all target subtargets.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:203
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
void printProtoIdent(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)