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