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 #define DEBUG_TYPE "asm-printer"
15 #include "InstPrinter/NVPTXInstPrinter.h"
17 #include "MCTargetDesc/NVPTXBaseInfo.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"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/FormattedStream.h"
28 #include "NVPTXGenAsmWriter.inc"
31 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
32 const MCRegisterInfo &MRI,
33 const MCSubtargetInfo &STI)
34 : MCInstPrinter(MAI, MII, MRI) {
35 setAvailableFeatures(STI.getFeatureBits());
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);
43 default: report_fatal_error("Bad virtual register encoding");
45 // This is actually a physical register, so defer to the autogenerated
47 OS << getRegisterName(RegNo);
69 unsigned VReg = RegNo & 0x0FFFFFFF;
73 void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
75 printInstruction(MI, OS);
77 // Next always print the annotation.
78 printAnnotation(OS, Annot);
81 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
83 const MCOperand &Op = MI->getOperand(OpNo);
85 unsigned Reg = Op.getReg();
87 } else if (Op.isImm()) {
88 O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
90 assert(Op.isExpr() && "Unknown operand kind in printOperand");
95 void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
96 const char *Modifier) {
97 const MCOperand &MO = MI->getOperand(OpNum);
98 int64_t Imm = MO.getImm();
100 if (strcmp(Modifier, "ftz") == 0) {
102 if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
104 } else if (strcmp(Modifier, "sat") == 0) {
106 if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
108 } else if (strcmp(Modifier, "base") == 0) {
110 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
113 case NVPTX::PTXCvtMode::NONE:
115 case NVPTX::PTXCvtMode::RNI:
118 case NVPTX::PTXCvtMode::RZI:
121 case NVPTX::PTXCvtMode::RMI:
124 case NVPTX::PTXCvtMode::RPI:
127 case NVPTX::PTXCvtMode::RN:
130 case NVPTX::PTXCvtMode::RZ:
133 case NVPTX::PTXCvtMode::RM:
136 case NVPTX::PTXCvtMode::RP:
141 llvm_unreachable("Invalid conversion modifier");
145 void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
146 const char *Modifier) {
147 const MCOperand &MO = MI->getOperand(OpNum);
148 int64_t Imm = MO.getImm();
150 if (strcmp(Modifier, "ftz") == 0) {
152 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
154 } else if (strcmp(Modifier, "base") == 0) {
155 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
158 case NVPTX::PTXCmpMode::EQ:
161 case NVPTX::PTXCmpMode::NE:
164 case NVPTX::PTXCmpMode::LT:
167 case NVPTX::PTXCmpMode::LE:
170 case NVPTX::PTXCmpMode::GT:
173 case NVPTX::PTXCmpMode::GE:
176 case NVPTX::PTXCmpMode::LO:
179 case NVPTX::PTXCmpMode::LS:
182 case NVPTX::PTXCmpMode::HI:
185 case NVPTX::PTXCmpMode::HS:
188 case NVPTX::PTXCmpMode::EQU:
191 case NVPTX::PTXCmpMode::NEU:
194 case NVPTX::PTXCmpMode::LTU:
197 case NVPTX::PTXCmpMode::LEU:
200 case NVPTX::PTXCmpMode::GTU:
203 case NVPTX::PTXCmpMode::GEU:
206 case NVPTX::PTXCmpMode::NUM:
209 case NVPTX::PTXCmpMode::NotANumber:
214 llvm_unreachable("Empty Modifier");
218 void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
219 raw_ostream &O, const char *Modifier) {
221 const MCOperand &MO = MI->getOperand(OpNum);
222 int Imm = (int) MO.getImm();
223 if (!strcmp(Modifier, "volatile")) {
226 } else if (!strcmp(Modifier, "addsp")) {
228 case NVPTX::PTXLdStInstCode::GLOBAL:
231 case NVPTX::PTXLdStInstCode::SHARED:
234 case NVPTX::PTXLdStInstCode::LOCAL:
237 case NVPTX::PTXLdStInstCode::PARAM:
240 case NVPTX::PTXLdStInstCode::CONSTANT:
243 case NVPTX::PTXLdStInstCode::GENERIC:
246 llvm_unreachable("Wrong Address Space");
248 } else if (!strcmp(Modifier, "sign")) {
249 if (Imm == NVPTX::PTXLdStInstCode::Signed)
251 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
255 } else if (!strcmp(Modifier, "vec")) {
256 if (Imm == NVPTX::PTXLdStInstCode::V2)
258 else if (Imm == NVPTX::PTXLdStInstCode::V4)
261 llvm_unreachable("Unknown Modifier");
263 llvm_unreachable("Empty Modifier");
266 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
267 raw_ostream &O, const char *Modifier) {
268 printOperand(MI, OpNum, O);
270 if (Modifier && !strcmp(Modifier, "add")) {
272 printOperand(MI, OpNum + 1, O);
274 if (MI->getOperand(OpNum + 1).isImm() &&
275 MI->getOperand(OpNum + 1).getImm() == 0)
276 return; // don't print ',0' or '+0'
278 printOperand(MI, OpNum + 1, O);
282 void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
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();