LLVM  9.0.0svn
NVPTXInstPrinter.cpp
Go to the documentation of this file.
1 //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Print MCInst instructions to .ptx format.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 #include "NVPTX.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCSymbol.h"
23 #include <cctype>
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "asm-printer"
27 
28 #include "NVPTXGenAsmWriter.inc"
29 
31  const MCRegisterInfo &MRI)
32  : MCInstPrinter(MAI, MII, MRI) {}
33 
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);
38  switch (RCId) {
39  default: report_fatal_error("Bad virtual register encoding");
40  case 0:
41  // This is actually a physical register, so defer to the autogenerated
42  // register printer
43  OS << getRegisterName(RegNo);
44  return;
45  case 1:
46  OS << "%p";
47  break;
48  case 2:
49  OS << "%rs";
50  break;
51  case 3:
52  OS << "%r";
53  break;
54  case 4:
55  OS << "%rd";
56  break;
57  case 5:
58  OS << "%f";
59  break;
60  case 6:
61  OS << "%fd";
62  break;
63  case 7:
64  OS << "%h";
65  break;
66  case 8:
67  OS << "%hh";
68  break;
69  }
70 
71  unsigned VReg = RegNo & 0x0FFFFFFF;
72  OS << VReg;
73 }
74 
76  StringRef Annot, const MCSubtargetInfo &STI) {
77  printInstruction(MI, OS);
78 
79  // Next always print the annotation.
80  printAnnotation(OS, Annot);
81 }
82 
83 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
84  raw_ostream &O) {
85  const MCOperand &Op = MI->getOperand(OpNo);
86  if (Op.isReg()) {
87  unsigned Reg = Op.getReg();
88  printRegName(O, Reg);
89  } else if (Op.isImm()) {
90  O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
91  } else {
92  assert(Op.isExpr() && "Unknown operand kind in printOperand");
93  Op.getExpr()->print(O, &MAI);
94  }
95 }
96 
98  const char *Modifier) {
99  const MCOperand &MO = MI->getOperand(OpNum);
100  int64_t Imm = MO.getImm();
101 
102  if (strcmp(Modifier, "ftz") == 0) {
103  // FTZ flag
104  if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
105  O << ".ftz";
106  } else if (strcmp(Modifier, "sat") == 0) {
107  // SAT flag
108  if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
109  O << ".sat";
110  } else if (strcmp(Modifier, "base") == 0) {
111  // Default operand
112  switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
113  default:
114  return;
116  break;
118  O << ".rni";
119  break;
121  O << ".rzi";
122  break;
124  O << ".rmi";
125  break;
127  O << ".rpi";
128  break;
130  O << ".rn";
131  break;
133  O << ".rz";
134  break;
136  O << ".rm";
137  break;
139  O << ".rp";
140  break;
141  }
142  } else {
143  llvm_unreachable("Invalid conversion modifier");
144  }
145 }
146 
148  const char *Modifier) {
149  const MCOperand &MO = MI->getOperand(OpNum);
150  int64_t Imm = MO.getImm();
151 
152  if (strcmp(Modifier, "ftz") == 0) {
153  // FTZ flag
154  if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
155  O << ".ftz";
156  } else if (strcmp(Modifier, "base") == 0) {
157  switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
158  default:
159  return;
161  O << ".eq";
162  break;
164  O << ".ne";
165  break;
167  O << ".lt";
168  break;
170  O << ".le";
171  break;
173  O << ".gt";
174  break;
176  O << ".ge";
177  break;
179  O << ".lo";
180  break;
182  O << ".ls";
183  break;
185  O << ".hi";
186  break;
188  O << ".hs";
189  break;
191  O << ".equ";
192  break;
194  O << ".neu";
195  break;
197  O << ".ltu";
198  break;
200  O << ".leu";
201  break;
203  O << ".gtu";
204  break;
206  O << ".geu";
207  break;
209  O << ".num";
210  break;
212  O << ".nan";
213  break;
214  }
215  } else {
216  llvm_unreachable("Empty Modifier");
217  }
218 }
219 
221  raw_ostream &O, const char *Modifier) {
222  if (Modifier) {
223  const MCOperand &MO = MI->getOperand(OpNum);
224  int Imm = (int) MO.getImm();
225  if (!strcmp(Modifier, "volatile")) {
226  if (Imm)
227  O << ".volatile";
228  } else if (!strcmp(Modifier, "addsp")) {
229  switch (Imm) {
231  O << ".global";
232  break;
234  O << ".shared";
235  break;
237  O << ".local";
238  break;
240  O << ".param";
241  break;
243  O << ".const";
244  break;
246  break;
247  default:
248  llvm_unreachable("Wrong Address Space");
249  }
250  } else if (!strcmp(Modifier, "sign")) {
252  O << "s";
253  else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
254  O << "u";
255  else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
256  O << "b";
257  else if (Imm == NVPTX::PTXLdStInstCode::Float)
258  O << "f";
259  else
260  llvm_unreachable("Unknown register type");
261  } else if (!strcmp(Modifier, "vec")) {
262  if (Imm == NVPTX::PTXLdStInstCode::V2)
263  O << ".v2";
264  else if (Imm == NVPTX::PTXLdStInstCode::V4)
265  O << ".v4";
266  } else
267  llvm_unreachable("Unknown Modifier");
268  } else
269  llvm_unreachable("Empty Modifier");
270 }
271 
273  raw_ostream &O, const char *Modifier) {
274  printOperand(MI, OpNum, O);
275 
276  if (Modifier && !strcmp(Modifier, "add")) {
277  O << ", ";
278  printOperand(MI, OpNum + 1, O);
279  } else {
280  if (MI->getOperand(OpNum + 1).isImm() &&
281  MI->getOperand(OpNum + 1).getImm() == 0)
282  return; // don't print ',0' or '+0'
283  O << "+";
284  printOperand(MI, OpNum + 1, O);
285  }
286 }
287 
289  raw_ostream &O, const char *Modifier) {
290  const MCOperand &Op = MI->getOperand(OpNum);
291  assert(Op.isExpr() && "Call prototype is not an MCExpr?");
292  const MCExpr *Expr = Op.getExpr();
293  const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
294  O << Sym.getName();
295 }
void printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)
bool isImm() const
Definition: MCInst.h:58
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:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
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:57
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:35
NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
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:99
const MCExpr * getExpr() const
Definition: MCInst.h:95
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Definition: ELF.h:334
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
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:55
int64_t getImm() const
Definition: MCInst.h:75
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
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:23
static const char * getRegisterName(unsigned RegNo)
bool isExpr() const
Definition: MCInst.h:60
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:179
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:45
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:39
Generic base class for all target subtargets.
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:202
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:45
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34
void printProtoIdent(const MCInst *MI, int OpNum, raw_ostream &O, const char *Modifier=nullptr)