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