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