blob: 1cb8a9a26e4b121e00ed1ee50e618c566b0b0a72 [file] [log] [blame]
Justin Holewinskia2a63d22013-08-06 14:13:27 +00001//===-- 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
14#define DEBUG_TYPE "asm-printer"
15#include "InstPrinter/NVPTXInstPrinter.h"
16#include "NVPTX.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"
24#include <cctype>
25using namespace llvm;
26
27#include "NVPTXGenAsmWriter.inc"
28
29
30NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31 const MCRegisterInfo &MRI,
32 const MCSubtargetInfo &STI)
33 : MCInstPrinter(MAI, MII, MRI) {
34 setAvailableFeatures(STI.getFeatureBits());
35}
36
37void 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);
41 switch (RCId) {
42 default: report_fatal_error("Bad virtual register encoding");
43 case 0:
44 OS << "%p";
45 break;
46 case 1:
47 OS << "%rs";
48 break;
49 case 2:
50 OS << "%r";
51 break;
52 case 3:
53 OS << "%rl";
54 break;
55 case 4:
56 OS << "%f";
57 break;
58 case 5:
59 OS << "%fl";
60 break;
61 }
62
63 unsigned VReg = RegNo & 0x0FFFFFFF;
64 OS << VReg;
65}
66
67void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
68 StringRef Annot) {
69 printInstruction(MI, OS);
70
71 // Next always print the annotation.
72 printAnnotation(OS, Annot);
73}
74
75void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
76 raw_ostream &O) {
77 const MCOperand &Op = MI->getOperand(OpNo);
78 if (Op.isReg()) {
79 unsigned Reg = Op.getReg();
80 printRegName(O, Reg);
81 } else if (Op.isImm()) {
82 O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
83 } else {
84 assert(Op.isExpr() && "Unknown operand kind in printOperand");
85 O << *Op.getExpr();
86 }
87}
88
89void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
90 const char *Modifier) {
91 const MCOperand &MO = MI->getOperand(OpNum);
92 int64_t Imm = MO.getImm();
93
94 if (strcmp(Modifier, "ftz") == 0) {
95 // FTZ flag
96 if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
97 O << ".ftz";
98 } else if (strcmp(Modifier, "sat") == 0) {
99 // SAT flag
100 if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
101 O << ".sat";
102 } else if (strcmp(Modifier, "base") == 0) {
103 // Default operand
104 switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
105 default:
106 return;
107 case NVPTX::PTXCvtMode::NONE:
108 break;
109 case NVPTX::PTXCvtMode::RNI:
110 O << ".rni";
111 break;
112 case NVPTX::PTXCvtMode::RZI:
113 O << ".rzi";
114 break;
115 case NVPTX::PTXCvtMode::RMI:
116 O << ".rmi";
117 break;
118 case NVPTX::PTXCvtMode::RPI:
119 O << ".rpi";
120 break;
121 case NVPTX::PTXCvtMode::RN:
122 O << ".rn";
123 break;
124 case NVPTX::PTXCvtMode::RZ:
125 O << ".rz";
126 break;
127 case NVPTX::PTXCvtMode::RM:
128 O << ".rm";
129 break;
130 case NVPTX::PTXCvtMode::RP:
131 O << ".rp";
132 break;
133 }
134 } else {
135 llvm_unreachable("Invalid conversion modifier");
136 }
137}
138
139void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
140 const char *Modifier) {
141 const MCOperand &MO = MI->getOperand(OpNum);
142 int64_t Imm = MO.getImm();
143
144 if (strcmp(Modifier, "ftz") == 0) {
145 // FTZ flag
146 if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
147 O << ".ftz";
148 } else if (strcmp(Modifier, "base") == 0) {
149 switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
150 default:
151 return;
152 case NVPTX::PTXCmpMode::EQ:
153 O << ".eq";
154 break;
155 case NVPTX::PTXCmpMode::NE:
156 O << ".ne";
157 break;
158 case NVPTX::PTXCmpMode::LT:
159 O << ".lt";
160 break;
161 case NVPTX::PTXCmpMode::LE:
162 O << ".le";
163 break;
164 case NVPTX::PTXCmpMode::GT:
165 O << ".gt";
166 break;
167 case NVPTX::PTXCmpMode::GE:
168 O << ".ge";
169 break;
170 case NVPTX::PTXCmpMode::LO:
171 O << ".lo";
172 break;
173 case NVPTX::PTXCmpMode::LS:
174 O << ".ls";
175 break;
176 case NVPTX::PTXCmpMode::HI:
177 O << ".hi";
178 break;
179 case NVPTX::PTXCmpMode::HS:
180 O << ".hs";
181 break;
182 case NVPTX::PTXCmpMode::EQU:
183 O << ".equ";
184 break;
185 case NVPTX::PTXCmpMode::NEU:
186 O << ".neu";
187 break;
188 case NVPTX::PTXCmpMode::LTU:
189 O << ".ltu";
190 break;
191 case NVPTX::PTXCmpMode::LEU:
192 O << ".leu";
193 break;
194 case NVPTX::PTXCmpMode::GTU:
195 O << ".gtu";
196 break;
197 case NVPTX::PTXCmpMode::GEU:
198 O << ".geu";
199 break;
200 case NVPTX::PTXCmpMode::NUM:
201 O << ".num";
202 break;
203 case NVPTX::PTXCmpMode::NotANumber:
204 O << ".nan";
205 break;
206 }
207 } else {
208 llvm_unreachable("Empty Modifier");
209 }
210}
211
212void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
213 raw_ostream &O, const char *Modifier) {
214 if (Modifier) {
215 const MCOperand &MO = MI->getOperand(OpNum);
216 int Imm = (int) MO.getImm();
217 if (!strcmp(Modifier, "volatile")) {
218 if (Imm)
219 O << ".volatile";
220 } else if (!strcmp(Modifier, "addsp")) {
221 switch (Imm) {
222 case NVPTX::PTXLdStInstCode::GLOBAL:
223 O << ".global";
224 break;
225 case NVPTX::PTXLdStInstCode::SHARED:
226 O << ".shared";
227 break;
228 case NVPTX::PTXLdStInstCode::LOCAL:
229 O << ".local";
230 break;
231 case NVPTX::PTXLdStInstCode::PARAM:
232 O << ".param";
233 break;
234 case NVPTX::PTXLdStInstCode::CONSTANT:
235 O << ".const";
236 break;
237 case NVPTX::PTXLdStInstCode::GENERIC:
238 break;
239 default:
240 llvm_unreachable("Wrong Address Space");
241 }
242 } else if (!strcmp(Modifier, "sign")) {
243 if (Imm == NVPTX::PTXLdStInstCode::Signed)
244 O << "s";
245 else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
246 O << "u";
247 else
248 O << "f";
249 } else if (!strcmp(Modifier, "vec")) {
250 if (Imm == NVPTX::PTXLdStInstCode::V2)
251 O << ".v2";
252 else if (Imm == NVPTX::PTXLdStInstCode::V4)
253 O << ".v4";
254 } else
255 llvm_unreachable("Unknown Modifier");
256 } else
257 llvm_unreachable("Empty Modifier");
258}
259
260void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
261 raw_ostream &O, const char *Modifier) {
262 printOperand(MI, OpNum, O);
263
264 if (Modifier && !strcmp(Modifier, "add")) {
265 O << ", ";
266 printOperand(MI, OpNum + 1, O);
267 } else {
268 if (MI->getOperand(OpNum + 1).isImm() &&
269 MI->getOperand(OpNum + 1).getImm() == 0)
270 return; // don't print ',0' or '+0'
271 O << "+";
272 printOperand(MI, OpNum + 1, O);
273 }
274}