]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / NVPTX / MCTargetDesc / NVPTXInstPrinter.cpp
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 }