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/MCSubtargetInfo.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/FormattedStream.h"
27 #include "NVPTXGenAsmWriter.inc"
30 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31 const MCRegisterInfo &MRI,
32 const MCSubtargetInfo &STI)
33 : MCInstPrinter(MAI, MII, MRI) {
34 setAvailableFeatures(STI.getFeatureBits());
37 void NVPTXInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
38 // Decode the virtual register
39 // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
40 unsigned RCId = (RegNo >> 28);
42 default: report_fatal_error("Bad virtual register encoding");
44 // This is actually a physical register, so defer to the autogenerated
46 OS << getRegisterName(RegNo);
68 unsigned VReg = RegNo & 0x0FFFFFFF;
72 void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
74 printInstruction(MI, OS);
76 // Next always print the annotation.
77 printAnnotation(OS, Annot);
80 void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
82 const MCOperand &Op = MI->getOperand(OpNo);
84 unsigned Reg = Op.getReg();
86 } else if (Op.isImm()) {
87 O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
89 assert(Op.isExpr() && "Unknown operand kind in printOperand");
94 void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
95 const char *Modifier) {
96 const MCOperand &MO = MI->getOperand(OpNum);
97 int64_t Imm = MO.getImm();
99 if (strcmp(Modifier, "ftz") == 0) {
101 if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
103 } else if (strcmp(Modifier, "sat") == 0) {
105 if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
107 } else if (strcmp(Modifier, "base") == 0) {
109 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
112 case NVPTX::PTXCvtMode::NONE:
114 case NVPTX::PTXCvtMode::RNI:
117 case NVPTX::PTXCvtMode::RZI:
120 case NVPTX::PTXCvtMode::RMI:
123 case NVPTX::PTXCvtMode::RPI:
126 case NVPTX::PTXCvtMode::RN:
129 case NVPTX::PTXCvtMode::RZ:
132 case NVPTX::PTXCvtMode::RM:
135 case NVPTX::PTXCvtMode::RP:
140 llvm_unreachable("Invalid conversion modifier");
144 void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
145 const char *Modifier) {
146 const MCOperand &MO = MI->getOperand(OpNum);
147 int64_t Imm = MO.getImm();
149 if (strcmp(Modifier, "ftz") == 0) {
151 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
153 } else if (strcmp(Modifier, "base") == 0) {
154 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
157 case NVPTX::PTXCmpMode::EQ:
160 case NVPTX::PTXCmpMode::NE:
163 case NVPTX::PTXCmpMode::LT:
166 case NVPTX::PTXCmpMode::LE:
169 case NVPTX::PTXCmpMode::GT:
172 case NVPTX::PTXCmpMode::GE:
175 case NVPTX::PTXCmpMode::LO:
178 case NVPTX::PTXCmpMode::LS:
181 case NVPTX::PTXCmpMode::HI:
184 case NVPTX::PTXCmpMode::HS:
187 case NVPTX::PTXCmpMode::EQU:
190 case NVPTX::PTXCmpMode::NEU:
193 case NVPTX::PTXCmpMode::LTU:
196 case NVPTX::PTXCmpMode::LEU:
199 case NVPTX::PTXCmpMode::GTU:
202 case NVPTX::PTXCmpMode::GEU:
205 case NVPTX::PTXCmpMode::NUM:
208 case NVPTX::PTXCmpMode::NotANumber:
213 llvm_unreachable("Empty Modifier");
217 void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
218 raw_ostream &O, const char *Modifier) {
220 const MCOperand &MO = MI->getOperand(OpNum);
221 int Imm = (int) MO.getImm();
222 if (!strcmp(Modifier, "volatile")) {
225 } else if (!strcmp(Modifier, "addsp")) {
227 case NVPTX::PTXLdStInstCode::GLOBAL:
230 case NVPTX::PTXLdStInstCode::SHARED:
233 case NVPTX::PTXLdStInstCode::LOCAL:
236 case NVPTX::PTXLdStInstCode::PARAM:
239 case NVPTX::PTXLdStInstCode::CONSTANT:
242 case NVPTX::PTXLdStInstCode::GENERIC:
245 llvm_unreachable("Wrong Address Space");
247 } else if (!strcmp(Modifier, "sign")) {
248 if (Imm == NVPTX::PTXLdStInstCode::Signed)
250 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
254 } else if (!strcmp(Modifier, "vec")) {
255 if (Imm == NVPTX::PTXLdStInstCode::V2)
257 else if (Imm == NVPTX::PTXLdStInstCode::V4)
260 llvm_unreachable("Unknown Modifier");
262 llvm_unreachable("Empty Modifier");
265 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
266 raw_ostream &O, const char *Modifier) {
267 printOperand(MI, OpNum, O);
269 if (Modifier && !strcmp(Modifier, "add")) {
271 printOperand(MI, OpNum + 1, O);
273 if (MI->getOperand(OpNum + 1).isImm() &&
274 MI->getOperand(OpNum + 1).getImm() == 0)
275 return; // don't print ',0' or '+0'
277 printOperand(MI, OpNum + 1, O);