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