[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / lib / Target / NVPTX / MCTargetDesc / NVPTXInstPrinter.cpp
blobb6eefe206268a9eee40fbee97b28d9fa4991daae
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.
11 //===----------------------------------------------------------------------===//
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;
26 #define DEBUG_TYPE "asm-printer"
28 #include "NVPTXGenAsmWriter.inc"
30 NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
31 const MCRegisterInfo &MRI)
32 : MCInstPrinter(MAI, MII, MRI) {}
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;
71 unsigned VReg = RegNo & 0x0FFFFFFF;
72 OS << VReg;
75 void NVPTXInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
76 StringRef Annot, const MCSubtargetInfo &STI) {
77 printInstruction(MI, OS);
79 // Next always print the annotation.
80 printAnnotation(OS, Annot);
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);
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();
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;
142 } else {
143 llvm_unreachable("Invalid conversion modifier");
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();
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;
215 } else {
216 llvm_unreachable("Empty Modifier");
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");
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");
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");
286 void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
287 raw_ostream &O, const char *Modifier) {
288 printOperand(MI, OpNum, O);
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);
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();