LLVM  4.0.0
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  }
65 
66  unsigned VReg = RegNo & 0x0FFFFFFF;
67  OS << VReg;
68 }
69 
71  StringRef Annot, const MCSubtargetInfo &STI) {
72  printInstruction(MI, OS);
73 
74  // Next always print the annotation.
75  printAnnotation(OS, Annot);
76 }
77 
78 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
79  raw_ostream &O) {
80  const MCOperand &Op = MI->getOperand(OpNo);
81  if (Op.isReg()) {
82  unsigned Reg = Op.getReg();
83  printRegName(O, Reg);
84  } else if (Op.isImm()) {
85  O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
86  } else {
87  assert(Op.isExpr() && "Unknown operand kind in printOperand");
88  Op.getExpr()->print(O, &MAI);
89  }
90 }
91 
93  const char *Modifier) {
94  const MCOperand &MO = MI->getOperand(OpNum);
95  int64_t Imm = MO.getImm();
96 
97  if (strcmp(Modifier, "ftz") == 0) {
98  // FTZ flag
100  O << ".ftz";
101  } else if (strcmp(Modifier, "sat") == 0) {
102  // SAT flag
103  if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
104  O << ".sat";
105  } else if (strcmp(Modifier, "base") == 0) {
106  // Default operand
107  switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
108  default:
109  return;
111  break;
113  O << ".rni";
114  break;
116  O << ".rzi";
117  break;
119  O << ".rmi";
120  break;
122  O << ".rpi";
123  break;
125  O << ".rn";
126  break;
128  O << ".rz";
129  break;
131  O << ".rm";
132  break;
134  O << ".rp";
135  break;
136  }
137  } else {
138  llvm_unreachable("Invalid conversion modifier");
139  }
140 }
141 
143  const char *Modifier) {
144  const MCOperand &MO = MI->getOperand(OpNum);
145  int64_t Imm = MO.getImm();
146 
147  if (strcmp(Modifier, "ftz") == 0) {
148  // FTZ flag
149  if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
150  O << ".ftz";
151  } else if (strcmp(Modifier, "base") == 0) {
152  switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
153  default:
154  return;
156  O << ".eq";
157  break;
159  O << ".ne";
160  break;
162  O << ".lt";
163  break;
165  O << ".le";
166  break;
168  O << ".gt";
169  break;
171  O << ".ge";
172  break;
174  O << ".lo";
175  break;
177  O << ".ls";
178  break;
180  O << ".hi";
181  break;
183  O << ".hs";
184  break;
186  O << ".equ";
187  break;
189  O << ".neu";
190  break;
192  O << ".ltu";
193  break;
195  O << ".leu";
196  break;
198  O << ".gtu";
199  break;
201  O << ".geu";
202  break;
204  O << ".num";
205  break;
207  O << ".nan";
208  break;
209  }
210  } else {
211  llvm_unreachable("Empty Modifier");
212  }
213 }
214 
216  raw_ostream &O, const char *Modifier) {
217  if (Modifier) {
218  const MCOperand &MO = MI->getOperand(OpNum);
219  int Imm = (int) MO.getImm();
220  if (!strcmp(Modifier, "volatile")) {
221  if (Imm)
222  O << ".volatile";
223  } else if (!strcmp(Modifier, "addsp")) {
224  switch (Imm) {
226  O << ".global";
227  break;
229  O << ".shared";
230  break;
232  O << ".local";
233  break;
235  O << ".param";
236  break;
238  O << ".const";
239  break;
241  break;
242  default:
243  llvm_unreachable("Wrong Address Space");
244  }
245  } else if (!strcmp(Modifier, "sign")) {
247  O << "s";
248  else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
249  O << "u";
250  else
251  O << "f";
252  } else if (!strcmp(Modifier, "vec")) {
253  if (Imm == NVPTX::PTXLdStInstCode::V2)
254  O << ".v2";
255  else if (Imm == NVPTX::PTXLdStInstCode::V4)
256  O << ".v4";
257  } else
258  llvm_unreachable("Unknown Modifier");
259  } else
260  llvm_unreachable("Empty Modifier");
261 }
262 
264  raw_ostream &O, const char *Modifier) {
265  printOperand(MI, OpNum, O);
266 
267  if (Modifier && !strcmp(Modifier, "add")) {
268  O << ", ";
269  printOperand(MI, OpNum + 1, O);
270  } else {
271  if (MI->getOperand(OpNum + 1).isImm() &&
272  MI->getOperand(OpNum + 1).getImm() == 0)
273  return; // don't print ',0' or '+0'
274  O << "+";
275  printOperand(MI, OpNum + 1, O);
276  }
277 }
278 
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();
285  O << Sym.getName();
286 }
void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool isReg() const
Definition: MCInst.h:56
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
void printInstruction(const MCInst *MI, raw_ostream &O)
void printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
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:34
Reg
All possible values of the reg field in the ModR/M byte.
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
void printMemOperand(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Definition: Object/ELF.h:236
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
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...
bool isImm() const
Definition: MCInst.h:57
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
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
bool isExpr() const
Definition: MCInst.h:59
static const char * getRegisterName(unsigned RegNo)
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:99
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int64_t getImm() const
Definition: MCInst.h:74
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:47
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:41
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:199
MCSubtargetInfo - Generic base class for all target subtargets.
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:33
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:44
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164
void printProtoIdent(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)