]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AMDGPU / MCTargetDesc / AMDGPUInstPrinter.cpp
1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
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 // \file
8 //===----------------------------------------------------------------------===//
9
10 #include "AMDGPUInstPrinter.h"
11 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
12 #include "SIDefines.h"
13 #include "Utils/AMDGPUAsmUtils.h"
14 #include "Utils/AMDGPUBaseInfo.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCInstrDesc.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <cassert>
25
26 using namespace llvm;
27 using namespace llvm::AMDGPU;
28
29 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
30                                   StringRef Annot, const MCSubtargetInfo &STI) {
31   OS.flush();
32   printInstruction(MI, STI, OS);
33   printAnnotation(OS, Annot);
34 }
35
36 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
37                                           const MCSubtargetInfo &STI,
38                                           raw_ostream &O) {
39   O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
40 }
41
42 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
43                                           raw_ostream &O) {
44   O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
45 }
46
47 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
48                                            const MCSubtargetInfo &STI,
49                                            raw_ostream &O) {
50   // It's possible to end up with a 32-bit literal used with a 16-bit operand
51   // with ignored high bits. Print as 32-bit anyway in that case.
52   int64_t Imm = MI->getOperand(OpNo).getImm();
53   if (isInt<16>(Imm) || isUInt<16>(Imm))
54     O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
55   else
56     printU32ImmOperand(MI, OpNo, STI, O);
57 }
58
59 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
60                                              raw_ostream &O) {
61   O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
62 }
63
64 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
65                                              raw_ostream &O) {
66   O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
67 }
68
69 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
70                                               raw_ostream &O) {
71   O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
72 }
73
74 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
75                                            const MCSubtargetInfo &STI,
76                                            raw_ostream &O) {
77   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
78 }
79
80 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
81                                       raw_ostream &O, StringRef BitName) {
82   if (MI->getOperand(OpNo).getImm()) {
83     O << ' ' << BitName;
84   }
85 }
86
87 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
88                                    raw_ostream &O) {
89   printNamedBit(MI, OpNo, O, "offen");
90 }
91
92 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
93                                    raw_ostream &O) {
94   printNamedBit(MI, OpNo, O, "idxen");
95 }
96
97 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
98                                     raw_ostream &O) {
99   printNamedBit(MI, OpNo, O, "addr64");
100 }
101
102 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
103                                         raw_ostream &O) {
104   if (MI->getOperand(OpNo).getImm()) {
105     O << " offset:";
106     printU16ImmDecOperand(MI, OpNo, O);
107   }
108 }
109
110 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
111                                     const MCSubtargetInfo &STI,
112                                     raw_ostream &O) {
113   uint16_t Imm = MI->getOperand(OpNo).getImm();
114   if (Imm != 0) {
115     O << ((OpNo == 0)? "offset:" : " offset:");
116     printU16ImmDecOperand(MI, OpNo, O);
117   }
118 }
119
120 void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
121                                         const MCSubtargetInfo &STI,
122                                         raw_ostream &O) {
123   uint16_t Imm = MI->getOperand(OpNo).getImm();
124   if (Imm != 0) {
125     O << ((OpNo == 0)? "offset:" : " offset:");
126
127     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
128     bool IsFlatSeg = !(Desc.TSFlags & SIInstrFlags::IsNonFlatSeg);
129
130     if (IsFlatSeg) { // Unsigned offset
131       printU16ImmDecOperand(MI, OpNo, O);
132     } else {         // Signed offset
133       if (AMDGPU::isGFX10(STI)) {
134         O << formatDec(SignExtend32<12>(MI->getOperand(OpNo).getImm()));
135       } else {
136         O << formatDec(SignExtend32<13>(MI->getOperand(OpNo).getImm()));
137       }
138     }
139   }
140 }
141
142 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
143                                      const MCSubtargetInfo &STI,
144                                      raw_ostream &O) {
145   if (MI->getOperand(OpNo).getImm()) {
146     O << " offset0:";
147     printU8ImmDecOperand(MI, OpNo, O);
148   }
149 }
150
151 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
152                                      const MCSubtargetInfo &STI,
153                                      raw_ostream &O) {
154   if (MI->getOperand(OpNo).getImm()) {
155     O << " offset1:";
156     printU8ImmDecOperand(MI, OpNo, O);
157   }
158 }
159
160 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
161                                         const MCSubtargetInfo &STI,
162                                         raw_ostream &O) {
163   printU32ImmOperand(MI, OpNo, STI, O);
164 }
165
166 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
167                                         const MCSubtargetInfo &STI,
168                                         raw_ostream &O) {
169   printU32ImmOperand(MI, OpNo, STI, O);
170 }
171
172 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
173                                                const MCSubtargetInfo &STI,
174                                                raw_ostream &O) {
175   printU32ImmOperand(MI, OpNo, STI, O);
176 }
177
178 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
179                                  const MCSubtargetInfo &STI, raw_ostream &O) {
180   printNamedBit(MI, OpNo, O, "gds");
181 }
182
183 void AMDGPUInstPrinter::printDLC(const MCInst *MI, unsigned OpNo,
184                                  const MCSubtargetInfo &STI, raw_ostream &O) {
185   if (AMDGPU::isGFX10(STI))
186     printNamedBit(MI, OpNo, O, "dlc");
187 }
188
189 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
190                                  const MCSubtargetInfo &STI, raw_ostream &O) {
191   printNamedBit(MI, OpNo, O, "glc");
192 }
193
194 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
195                                  const MCSubtargetInfo &STI, raw_ostream &O) {
196   printNamedBit(MI, OpNo, O, "slc");
197 }
198
199 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
200                                  const MCSubtargetInfo &STI, raw_ostream &O) {
201   printNamedBit(MI, OpNo, O, "tfe");
202 }
203
204 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
205                                    const MCSubtargetInfo &STI, raw_ostream &O) {
206   if (MI->getOperand(OpNo).getImm()) {
207     O << " dmask:";
208     printU16ImmOperand(MI, OpNo, STI, O);
209   }
210 }
211
212 void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
213                                  const MCSubtargetInfo &STI, raw_ostream &O) {
214   unsigned Dim = MI->getOperand(OpNo).getImm();
215   O << " dim:SQ_RSRC_IMG_";
216
217   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
218   if (DimInfo)
219     O << DimInfo->AsmSuffix;
220   else
221     O << Dim;
222 }
223
224 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
225                                    const MCSubtargetInfo &STI, raw_ostream &O) {
226   printNamedBit(MI, OpNo, O, "unorm");
227 }
228
229 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
230                                 const MCSubtargetInfo &STI, raw_ostream &O) {
231   printNamedBit(MI, OpNo, O, "da");
232 }
233
234 void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
235                                   const MCSubtargetInfo &STI, raw_ostream &O) {
236   if (STI.hasFeature(AMDGPU::FeatureR128A16))
237     printNamedBit(MI, OpNo, O, "a16");
238   else
239     printNamedBit(MI, OpNo, O, "r128");
240 }
241
242 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
243                                  const MCSubtargetInfo &STI, raw_ostream &O) {
244   printNamedBit(MI, OpNo, O, "lwe");
245 }
246
247 void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
248                                  const MCSubtargetInfo &STI, raw_ostream &O) {
249   printNamedBit(MI, OpNo, O, "d16");
250 }
251
252 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
253                                       const MCSubtargetInfo &STI,
254                                       raw_ostream &O) {
255   if (MI->getOperand(OpNo).getImm())
256     O << " compr";
257 }
258
259 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
260                                    const MCSubtargetInfo &STI,
261                                    raw_ostream &O) {
262   if (MI->getOperand(OpNo).getImm())
263     O << " vm";
264 }
265
266 void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
267                                     const MCSubtargetInfo &STI,
268                                     raw_ostream &O) {
269   if (unsigned Val = MI->getOperand(OpNo).getImm()) {
270     if (AMDGPU::isGFX10(STI))
271       O << " format:" << Val;
272     else {
273       O << " dfmt:" << (Val & 15);
274       O << ", nfmt:" << (Val >> 4);
275     }
276   }
277 }
278
279 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
280                                         const MCRegisterInfo &MRI) {
281 #if !defined(NDEBUG)
282   switch (RegNo) {
283   case AMDGPU::FP_REG:
284   case AMDGPU::SP_REG:
285   case AMDGPU::SCRATCH_WAVE_OFFSET_REG:
286   case AMDGPU::PRIVATE_RSRC_REG:
287     llvm_unreachable("pseudo-register should not ever be emitted");
288   case AMDGPU::SCC:
289     llvm_unreachable("pseudo scc should not ever be emitted");
290   default:
291     break;
292   }
293 #endif
294
295   unsigned AltName = AMDGPU::Reg32;
296
297   if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo) ||
298       MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo) ||
299       MRI.getRegClass(AMDGPU::AReg_64RegClassID).contains(RegNo))
300     AltName = AMDGPU::Reg64;
301   else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo) ||
302            MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo) ||
303            MRI.getRegClass(AMDGPU::AReg_128RegClassID).contains(RegNo))
304     AltName = AMDGPU::Reg128;
305   else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo) ||
306            MRI.getRegClass(AMDGPU::SReg_96RegClassID).contains(RegNo))
307     AltName = AMDGPU::Reg96;
308   else if (MRI.getRegClass(AMDGPU::VReg_160RegClassID).contains(RegNo) ||
309            MRI.getRegClass(AMDGPU::SReg_160RegClassID).contains(RegNo))
310     AltName = AMDGPU::Reg160;
311   else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo) ||
312            MRI.getRegClass(AMDGPU::SGPR_256RegClassID).contains(RegNo))
313     AltName = AMDGPU::Reg256;
314   else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo) ||
315            MRI.getRegClass(AMDGPU::SGPR_512RegClassID).contains(RegNo) ||
316            MRI.getRegClass(AMDGPU::AReg_512RegClassID).contains(RegNo))
317     AltName = AMDGPU::Reg512;
318   else if (MRI.getRegClass(AMDGPU::VReg_1024RegClassID).contains(RegNo) ||
319            MRI.getRegClass(AMDGPU::SReg_1024RegClassID).contains(RegNo) ||
320            MRI.getRegClass(AMDGPU::AReg_1024RegClassID).contains(RegNo))
321     AltName = AMDGPU::Reg1024;
322
323   O << getRegisterName(RegNo, AltName);
324 }
325
326 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
327                                     const MCSubtargetInfo &STI, raw_ostream &O) {
328   if (OpNo == 0) {
329     if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
330       O << "_e64 ";
331     else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
332       O << "_dpp ";
333     else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
334       O << "_sdwa ";
335     else
336       O << "_e32 ";
337   }
338
339   printOperand(MI, OpNo, STI, O);
340
341   // Print default vcc/vcc_lo operand.
342   switch (MI->getOpcode()) {
343   default: break;
344
345   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
346   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
347   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
348   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
349   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
350   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
351   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
352   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
353   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
354   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
355   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
356   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
357     printDefaultVccOperand(1, STI, O);
358     break;
359   }
360 }
361
362 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
363                                        const MCSubtargetInfo &STI, raw_ostream &O) {
364   if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
365     O << " ";
366   else
367     O << "_e32 ";
368
369   printOperand(MI, OpNo, STI, O);
370 }
371
372 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
373                                          const MCSubtargetInfo &STI,
374                                          raw_ostream &O) {
375   int16_t SImm = static_cast<int16_t>(Imm);
376   if (SImm >= -16 && SImm <= 64) {
377     O << SImm;
378     return;
379   }
380
381   if (Imm == 0x3C00)
382     O<< "1.0";
383   else if (Imm == 0xBC00)
384     O<< "-1.0";
385   else if (Imm == 0x3800)
386     O<< "0.5";
387   else if (Imm == 0xB800)
388     O<< "-0.5";
389   else if (Imm == 0x4000)
390     O<< "2.0";
391   else if (Imm == 0xC000)
392     O<< "-2.0";
393   else if (Imm == 0x4400)
394     O<< "4.0";
395   else if (Imm == 0xC400)
396     O<< "-4.0";
397   else if (Imm == 0x3118) {
398     assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
399     O << "0.15915494";
400   } else
401     O << formatHex(static_cast<uint64_t>(Imm));
402 }
403
404 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
405                                            const MCSubtargetInfo &STI,
406                                            raw_ostream &O) {
407   uint16_t Lo16 = static_cast<uint16_t>(Imm);
408   printImmediate16(Lo16, STI, O);
409 }
410
411 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
412                                          const MCSubtargetInfo &STI,
413                                          raw_ostream &O) {
414   int32_t SImm = static_cast<int32_t>(Imm);
415   if (SImm >= -16 && SImm <= 64) {
416     O << SImm;
417     return;
418   }
419
420   if (Imm == FloatToBits(0.0f))
421     O << "0.0";
422   else if (Imm == FloatToBits(1.0f))
423     O << "1.0";
424   else if (Imm == FloatToBits(-1.0f))
425     O << "-1.0";
426   else if (Imm == FloatToBits(0.5f))
427     O << "0.5";
428   else if (Imm == FloatToBits(-0.5f))
429     O << "-0.5";
430   else if (Imm == FloatToBits(2.0f))
431     O << "2.0";
432   else if (Imm == FloatToBits(-2.0f))
433     O << "-2.0";
434   else if (Imm == FloatToBits(4.0f))
435     O << "4.0";
436   else if (Imm == FloatToBits(-4.0f))
437     O << "-4.0";
438   else if (Imm == 0x3e22f983 &&
439            STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
440     O << "0.15915494";
441   else
442     O << formatHex(static_cast<uint64_t>(Imm));
443 }
444
445 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
446                                          const MCSubtargetInfo &STI,
447                                          raw_ostream &O) {
448   int64_t SImm = static_cast<int64_t>(Imm);
449   if (SImm >= -16 && SImm <= 64) {
450     O << SImm;
451     return;
452   }
453
454   if (Imm == DoubleToBits(0.0))
455     O << "0.0";
456   else if (Imm == DoubleToBits(1.0))
457     O << "1.0";
458   else if (Imm == DoubleToBits(-1.0))
459     O << "-1.0";
460   else if (Imm == DoubleToBits(0.5))
461     O << "0.5";
462   else if (Imm == DoubleToBits(-0.5))
463     O << "-0.5";
464   else if (Imm == DoubleToBits(2.0))
465     O << "2.0";
466   else if (Imm == DoubleToBits(-2.0))
467     O << "-2.0";
468   else if (Imm == DoubleToBits(4.0))
469     O << "4.0";
470   else if (Imm == DoubleToBits(-4.0))
471     O << "-4.0";
472   else if (Imm == 0x3fc45f306dc9c882 &&
473            STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
474     O << "0.15915494309189532";
475   else {
476     assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
477
478     // In rare situations, we will have a 32-bit literal in a 64-bit
479     // operand. This is technically allowed for the encoding of s_mov_b64.
480     O << formatHex(static_cast<uint64_t>(Imm));
481   }
482 }
483
484 void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
485                                   const MCSubtargetInfo &STI,
486                                   raw_ostream &O) {
487   unsigned Imm = MI->getOperand(OpNo).getImm();
488   if (!Imm)
489     return;
490
491   O << " blgp:" << Imm;
492 }
493
494 void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
495                                   const MCSubtargetInfo &STI,
496                                   raw_ostream &O) {
497   unsigned Imm = MI->getOperand(OpNo).getImm();
498   if (!Imm)
499     return;
500
501   O << " cbsz:" << Imm;
502 }
503
504 void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
505                                   const MCSubtargetInfo &STI,
506                                   raw_ostream &O) {
507   unsigned Imm = MI->getOperand(OpNo).getImm();
508   if (!Imm)
509     return;
510
511   O << " abid:" << Imm;
512 }
513
514 void AMDGPUInstPrinter::printDefaultVccOperand(unsigned OpNo,
515                                                const MCSubtargetInfo &STI,
516                                                raw_ostream &O) {
517   if (OpNo > 0)
518     O << ", ";
519   printRegOperand(STI.getFeatureBits()[AMDGPU::FeatureWavefrontSize64] ?
520                   AMDGPU::VCC : AMDGPU::VCC_LO, O, MRI);
521   if (OpNo == 0)
522     O << ", ";
523 }
524
525 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
526                                      const MCSubtargetInfo &STI,
527                                      raw_ostream &O) {
528   // Print default vcc/vcc_lo operand of VOPC.
529   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
530   if (OpNo == 0 && (Desc.TSFlags & SIInstrFlags::VOPC) &&
531       (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
532        Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
533     printDefaultVccOperand(OpNo, STI, O);
534
535   if (OpNo >= MI->getNumOperands()) {
536     O << "/*Missing OP" << OpNo << "*/";
537     return;
538   }
539
540   const MCOperand &Op = MI->getOperand(OpNo);
541   if (Op.isReg()) {
542     printRegOperand(Op.getReg(), O, MRI);
543   } else if (Op.isImm()) {
544     switch (Desc.OpInfo[OpNo].OperandType) {
545     case AMDGPU::OPERAND_REG_IMM_INT32:
546     case AMDGPU::OPERAND_REG_IMM_FP32:
547     case AMDGPU::OPERAND_REG_INLINE_C_INT32:
548     case AMDGPU::OPERAND_REG_INLINE_C_FP32:
549     case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
550     case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
551     case MCOI::OPERAND_IMMEDIATE:
552       printImmediate32(Op.getImm(), STI, O);
553       break;
554     case AMDGPU::OPERAND_REG_IMM_INT64:
555     case AMDGPU::OPERAND_REG_IMM_FP64:
556     case AMDGPU::OPERAND_REG_INLINE_C_INT64:
557     case AMDGPU::OPERAND_REG_INLINE_C_FP64:
558       printImmediate64(Op.getImm(), STI, O);
559       break;
560     case AMDGPU::OPERAND_REG_INLINE_C_INT16:
561     case AMDGPU::OPERAND_REG_INLINE_C_FP16:
562     case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
563     case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
564     case AMDGPU::OPERAND_REG_IMM_INT16:
565     case AMDGPU::OPERAND_REG_IMM_FP16:
566       printImmediate16(Op.getImm(), STI, O);
567       break;
568     case AMDGPU::OPERAND_REG_IMM_V2INT16:
569     case AMDGPU::OPERAND_REG_IMM_V2FP16:
570       if (!isUInt<16>(Op.getImm()) &&
571           STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
572         printImmediate32(Op.getImm(), STI, O);
573         break;
574       }
575       LLVM_FALLTHROUGH;
576     case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
577     case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
578     case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
579     case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
580       printImmediateV216(Op.getImm(), STI, O);
581       break;
582     case MCOI::OPERAND_UNKNOWN:
583     case MCOI::OPERAND_PCREL:
584       O << formatDec(Op.getImm());
585       break;
586     case MCOI::OPERAND_REGISTER:
587       // FIXME: This should be removed and handled somewhere else. Seems to come
588       // from a disassembler bug.
589       O << "/*invalid immediate*/";
590       break;
591     default:
592       // We hit this for the immediate instruction bits that don't yet have a
593       // custom printer.
594       llvm_unreachable("unexpected immediate operand type");
595     }
596   } else if (Op.isFPImm()) {
597     // We special case 0.0 because otherwise it will be printed as an integer.
598     if (Op.getFPImm() == 0.0)
599       O << "0.0";
600     else {
601       const MCInstrDesc &Desc = MII.get(MI->getOpcode());
602       int RCID = Desc.OpInfo[OpNo].RegClass;
603       unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
604       if (RCBits == 32)
605         printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
606       else if (RCBits == 64)
607         printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
608       else
609         llvm_unreachable("Invalid register class size");
610     }
611   } else if (Op.isExpr()) {
612     const MCExpr *Exp = Op.getExpr();
613     Exp->print(O, &MAI);
614   } else {
615     O << "/*INV_OP*/";
616   }
617
618   // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
619   switch (MI->getOpcode()) {
620   default: break;
621
622   case AMDGPU::V_CNDMASK_B32_e32_gfx10:
623   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
624   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
625   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
626   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
627   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
628   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
629   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
630   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
631   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
632
633   case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
634   case AMDGPU::V_CNDMASK_B32_e32_vi:
635     if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
636                                                 AMDGPU::OpName::src1))
637       printDefaultVccOperand(OpNo, STI, O);
638     break;
639   }
640 }
641
642 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
643                                                    unsigned OpNo,
644                                                    const MCSubtargetInfo &STI,
645                                                    raw_ostream &O) {
646   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
647
648   // Use 'neg(...)' instead of '-' to avoid ambiguity.
649   // This is important for integer literals because
650   // -1 is not the same value as neg(1).
651   bool NegMnemo = false;
652
653   if (InputModifiers & SISrcMods::NEG) {
654     if (OpNo + 1 < MI->getNumOperands() &&
655         (InputModifiers & SISrcMods::ABS) == 0) {
656       const MCOperand &Op = MI->getOperand(OpNo + 1);
657       NegMnemo = Op.isImm() || Op.isFPImm();
658     }
659     if (NegMnemo) {
660       O << "neg(";
661     } else {
662       O << '-';
663     }
664   }
665
666   if (InputModifiers & SISrcMods::ABS)
667     O << '|';
668   printOperand(MI, OpNo + 1, STI, O);
669   if (InputModifiers & SISrcMods::ABS)
670     O << '|';
671
672   if (NegMnemo) {
673     O << ')';
674   }
675 }
676
677 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
678                                                     unsigned OpNo,
679                                                     const MCSubtargetInfo &STI,
680                                                     raw_ostream &O) {
681   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
682   if (InputModifiers & SISrcMods::SEXT)
683     O << "sext(";
684   printOperand(MI, OpNo + 1, STI, O);
685   if (InputModifiers & SISrcMods::SEXT)
686     O << ')';
687
688   // Print default vcc/vcc_lo operand of VOP2b.
689   switch (MI->getOpcode()) {
690   default: break;
691
692   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
693   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
694   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
695     if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
696                                                     AMDGPU::OpName::src1))
697       printDefaultVccOperand(OpNo, STI, O);
698     break;
699   }
700 }
701
702 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
703                                   const MCSubtargetInfo &STI,
704                                   raw_ostream &O) {
705   if (!AMDGPU::isGFX10(STI))
706     llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
707
708   unsigned Imm = MI->getOperand(OpNo).getImm();
709   O << " dpp8:[" << formatDec(Imm & 0x7);
710   for (size_t i = 1; i < 8; ++i) {
711     O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
712   }
713   O << ']';
714 }
715
716 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
717                                      const MCSubtargetInfo &STI,
718                                      raw_ostream &O) {
719   using namespace AMDGPU::DPP;
720
721   unsigned Imm = MI->getOperand(OpNo).getImm();
722   if (Imm <= DppCtrl::QUAD_PERM_LAST) {
723     O << " quad_perm:[";
724     O << formatDec(Imm & 0x3)         << ',';
725     O << formatDec((Imm & 0xc)  >> 2) << ',';
726     O << formatDec((Imm & 0x30) >> 4) << ',';
727     O << formatDec((Imm & 0xc0) >> 6) << ']';
728   } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
729              (Imm <= DppCtrl::ROW_SHL_LAST)) {
730     O << " row_shl:";
731     printU4ImmDecOperand(MI, OpNo, O);
732   } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
733              (Imm <= DppCtrl::ROW_SHR_LAST)) {
734     O << " row_shr:";
735     printU4ImmDecOperand(MI, OpNo, O);
736   } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
737              (Imm <= DppCtrl::ROW_ROR_LAST)) {
738     O << " row_ror:";
739     printU4ImmDecOperand(MI, OpNo, O);
740   } else if (Imm == DppCtrl::WAVE_SHL1) {
741     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
742       O << " /* wave_shl is not supported starting from GFX10 */";
743       return;
744     }
745     O << " wave_shl:1";
746   } else if (Imm == DppCtrl::WAVE_ROL1) {
747     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
748       O << " /* wave_rol is not supported starting from GFX10 */";
749       return;
750     }
751     O << " wave_rol:1";
752   } else if (Imm == DppCtrl::WAVE_SHR1) {
753     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
754       O << " /* wave_shr is not supported starting from GFX10 */";
755       return;
756     }
757     O << " wave_shr:1";
758   } else if (Imm == DppCtrl::WAVE_ROR1) {
759     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
760       O << " /* wave_ror is not supported starting from GFX10 */";
761       return;
762     }
763     O << " wave_ror:1";
764   } else if (Imm == DppCtrl::ROW_MIRROR) {
765     O << " row_mirror";
766   } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
767     O << " row_half_mirror";
768   } else if (Imm == DppCtrl::BCAST15) {
769     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
770       O << " /* row_bcast is not supported starting from GFX10 */";
771       return;
772     }
773     O << " row_bcast:15";
774   } else if (Imm == DppCtrl::BCAST31) {
775     if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
776       O << " /* row_bcast is not supported starting from GFX10 */";
777       return;
778     }
779     O << " row_bcast:31";
780   } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
781              (Imm <= DppCtrl::ROW_SHARE_LAST)) {
782     if (!AMDGPU::isGFX10(STI)) {
783       O << " /* row_share is not supported on ASICs earlier than GFX10 */";
784       return;
785     }
786     O << " row_share:";
787     printU4ImmDecOperand(MI, OpNo, O);
788   } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
789              (Imm <= DppCtrl::ROW_XMASK_LAST)) {
790     if (!AMDGPU::isGFX10(STI)) {
791       O << " /* row_xmask is not supported on ASICs earlier than GFX10 */";
792       return;
793     }
794     O << "row_xmask:";
795     printU4ImmDecOperand(MI, OpNo, O);
796   } else {
797     O << " /* Invalid dpp_ctrl value */";
798   }
799 }
800
801 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
802                                      const MCSubtargetInfo &STI,
803                                      raw_ostream &O) {
804   O << " row_mask:";
805   printU4ImmOperand(MI, OpNo, STI, O);
806 }
807
808 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
809                                       const MCSubtargetInfo &STI,
810                                       raw_ostream &O) {
811   O << " bank_mask:";
812   printU4ImmOperand(MI, OpNo, STI, O);
813 }
814
815 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
816                                        const MCSubtargetInfo &STI,
817                                        raw_ostream &O) {
818   unsigned Imm = MI->getOperand(OpNo).getImm();
819   if (Imm) {
820     O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
821   }
822 }
823
824 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo,
825                                 const MCSubtargetInfo &STI,
826                                 raw_ostream &O) {
827   using namespace llvm::AMDGPU::DPP;
828   unsigned Imm = MI->getOperand(OpNo).getImm();
829   if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
830     O << " fi:1";
831   }
832 }
833
834 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
835                                      raw_ostream &O) {
836   using namespace llvm::AMDGPU::SDWA;
837
838   unsigned Imm = MI->getOperand(OpNo).getImm();
839   switch (Imm) {
840   case SdwaSel::BYTE_0: O << "BYTE_0"; break;
841   case SdwaSel::BYTE_1: O << "BYTE_1"; break;
842   case SdwaSel::BYTE_2: O << "BYTE_2"; break;
843   case SdwaSel::BYTE_3: O << "BYTE_3"; break;
844   case SdwaSel::WORD_0: O << "WORD_0"; break;
845   case SdwaSel::WORD_1: O << "WORD_1"; break;
846   case SdwaSel::DWORD: O << "DWORD"; break;
847   default: llvm_unreachable("Invalid SDWA data select operand");
848   }
849 }
850
851 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
852                                         const MCSubtargetInfo &STI,
853                                         raw_ostream &O) {
854   O << "dst_sel:";
855   printSDWASel(MI, OpNo, O);
856 }
857
858 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
859                                          const MCSubtargetInfo &STI,
860                                          raw_ostream &O) {
861   O << "src0_sel:";
862   printSDWASel(MI, OpNo, O);
863 }
864
865 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
866                                          const MCSubtargetInfo &STI,
867                                          raw_ostream &O) {
868   O << "src1_sel:";
869   printSDWASel(MI, OpNo, O);
870 }
871
872 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
873                                            const MCSubtargetInfo &STI,
874                                            raw_ostream &O) {
875   using namespace llvm::AMDGPU::SDWA;
876
877   O << "dst_unused:";
878   unsigned Imm = MI->getOperand(OpNo).getImm();
879   switch (Imm) {
880   case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
881   case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
882   case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
883   default: llvm_unreachable("Invalid SDWA dest_unused operand");
884   }
885 }
886
887 template <unsigned N>
888 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
889                                      const MCSubtargetInfo &STI,
890                                      raw_ostream &O) {
891   unsigned Opc = MI->getOpcode();
892   int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
893   unsigned En = MI->getOperand(EnIdx).getImm();
894
895   int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
896
897   // If compr is set, print as src0, src0, src1, src1
898   if (MI->getOperand(ComprIdx).getImm()) {
899     if (N == 1 || N == 2)
900       --OpNo;
901     else if (N == 3)
902       OpNo -= 2;
903   }
904
905   if (En & (1 << N))
906     printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
907   else
908     O << "off";
909 }
910
911 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
912                                      const MCSubtargetInfo &STI,
913                                      raw_ostream &O) {
914   printExpSrcN<0>(MI, OpNo, STI, O);
915 }
916
917 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
918                                      const MCSubtargetInfo &STI,
919                                      raw_ostream &O) {
920   printExpSrcN<1>(MI, OpNo, STI, O);
921 }
922
923 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
924                                      const MCSubtargetInfo &STI,
925                                      raw_ostream &O) {
926   printExpSrcN<2>(MI, OpNo, STI, O);
927 }
928
929 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
930                                      const MCSubtargetInfo &STI,
931                                      raw_ostream &O) {
932   printExpSrcN<3>(MI, OpNo, STI, O);
933 }
934
935 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
936                                     const MCSubtargetInfo &STI,
937                                     raw_ostream &O) {
938   // This is really a 6 bit field.
939   uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
940
941   if (Tgt <= 7)
942     O << " mrt" << Tgt;
943   else if (Tgt == 8)
944     O << " mrtz";
945   else if (Tgt == 9)
946     O << " null";
947   else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI)))
948     O << " pos" << Tgt - 12;
949   else if (AMDGPU::isGFX10(STI) && Tgt == 20)
950     O << " prim";
951   else if (Tgt >= 32 && Tgt <= 63)
952     O << " param" << Tgt - 32;
953   else {
954     // Reserved values 10, 11
955     O << " invalid_target_" << Tgt;
956   }
957 }
958
959 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
960                                bool IsPacked, bool HasDstSel) {
961   int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
962
963   for (int I = 0; I < NumOps; ++I) {
964     if (!!(Ops[I] & Mod) != DefaultValue)
965       return false;
966   }
967
968   if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
969     return false;
970
971   return true;
972 }
973
974 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
975                                             StringRef Name,
976                                             unsigned Mod,
977                                             raw_ostream &O) {
978   unsigned Opc = MI->getOpcode();
979   int NumOps = 0;
980   int Ops[3];
981
982   for (int OpName : { AMDGPU::OpName::src0_modifiers,
983                       AMDGPU::OpName::src1_modifiers,
984                       AMDGPU::OpName::src2_modifiers }) {
985     int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
986     if (Idx == -1)
987       break;
988
989     Ops[NumOps++] = MI->getOperand(Idx).getImm();
990   }
991
992   const bool HasDstSel =
993     NumOps > 0 &&
994     Mod == SISrcMods::OP_SEL_0 &&
995     MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
996
997   const bool IsPacked =
998     MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
999
1000   if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1001     return;
1002
1003   O << Name;
1004   for (int I = 0; I < NumOps; ++I) {
1005     if (I != 0)
1006       O << ',';
1007
1008     O << !!(Ops[I] & Mod);
1009   }
1010
1011   if (HasDstSel) {
1012     O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1013   }
1014
1015   O << ']';
1016 }
1017
1018 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1019                                    const MCSubtargetInfo &STI,
1020                                    raw_ostream &O) {
1021   unsigned Opc = MI->getOpcode();
1022   if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
1023       Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
1024     auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1025     auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1026     unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1027     unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1028     if (FI || BC)
1029       O << " op_sel:[" << FI << ',' << BC << ']';
1030     return;
1031   }
1032
1033   printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1034 }
1035
1036 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1037                                      const MCSubtargetInfo &STI,
1038                                      raw_ostream &O) {
1039   printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1040 }
1041
1042 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1043                                    const MCSubtargetInfo &STI,
1044                                    raw_ostream &O) {
1045   printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1046 }
1047
1048 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1049                                    const MCSubtargetInfo &STI,
1050                                    raw_ostream &O) {
1051   printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1052 }
1053
1054 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1055                                         const MCSubtargetInfo &STI,
1056                                         raw_ostream &O) {
1057   unsigned Imm = MI->getOperand(OpNum).getImm();
1058   switch (Imm) {
1059   case 0:
1060     O << "p10";
1061     break;
1062   case 1:
1063     O << "p20";
1064     break;
1065   case 2:
1066     O << "p0";
1067     break;
1068   default:
1069     O << "invalid_param_" << Imm;
1070   }
1071 }
1072
1073 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1074                                         const MCSubtargetInfo &STI,
1075                                         raw_ostream &O) {
1076   unsigned Attr = MI->getOperand(OpNum).getImm();
1077   O << "attr" << Attr;
1078 }
1079
1080 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1081                                         const MCSubtargetInfo &STI,
1082                                         raw_ostream &O) {
1083   unsigned Chan = MI->getOperand(OpNum).getImm();
1084   O << '.' << "xyzw"[Chan & 0x3];
1085 }
1086
1087 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1088                                            const MCSubtargetInfo &STI,
1089                                            raw_ostream &O) {
1090   using namespace llvm::AMDGPU::VGPRIndexMode;
1091   unsigned Val = MI->getOperand(OpNo).getImm();
1092
1093   if ((Val & ~ENABLE_MASK) != 0) {
1094     O << " " << formatHex(static_cast<uint64_t>(Val));
1095   } else {
1096     O << " gpr_idx(";
1097     bool NeedComma = false;
1098     for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1099       if (Val & (1 << ModeId)) {
1100         if (NeedComma)
1101           O << ',';
1102         O << IdSymbolic[ModeId];
1103         NeedComma = true;
1104       }
1105     }
1106     O << ')';
1107   }
1108 }
1109
1110 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1111                                         const MCSubtargetInfo &STI,
1112                                         raw_ostream &O) {
1113   printOperand(MI, OpNo, STI, O);
1114   O  << ", ";
1115   printOperand(MI, OpNo + 1, STI, O);
1116 }
1117
1118 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1119                                    raw_ostream &O, StringRef Asm,
1120                                    StringRef Default) {
1121   const MCOperand &Op = MI->getOperand(OpNo);
1122   assert(Op.isImm());
1123   if (Op.getImm() == 1) {
1124     O << Asm;
1125   } else {
1126     O << Default;
1127   }
1128 }
1129
1130 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1131                                    raw_ostream &O, char Asm) {
1132   const MCOperand &Op = MI->getOperand(OpNo);
1133   assert(Op.isImm());
1134   if (Op.getImm() == 1)
1135     O << Asm;
1136 }
1137
1138 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1139                                   const MCSubtargetInfo &STI,
1140                                   raw_ostream &O) {
1141   if (MI->getOperand(OpNo).getImm())
1142     O << " high";
1143 }
1144
1145 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1146                                      const MCSubtargetInfo &STI,
1147                                      raw_ostream &O) {
1148   if (MI->getOperand(OpNo).getImm())
1149     O << " clamp";
1150 }
1151
1152 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1153                                     const MCSubtargetInfo &STI,
1154                                     raw_ostream &O) {
1155   int Imm = MI->getOperand(OpNo).getImm();
1156   if (Imm == SIOutMods::MUL2)
1157     O << " mul:2";
1158   else if (Imm == SIOutMods::MUL4)
1159     O << " mul:4";
1160   else if (Imm == SIOutMods::DIV2)
1161     O << " div:2";
1162 }
1163
1164 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1165                                      const MCSubtargetInfo &STI,
1166                                      raw_ostream &O) {
1167   using namespace llvm::AMDGPU::SendMsg;
1168
1169   const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1170
1171   uint16_t MsgId;
1172   uint16_t OpId;
1173   uint16_t StreamId;
1174   decodeMsg(Imm16, MsgId, OpId, StreamId);
1175
1176   if (isValidMsgId(MsgId, STI) &&
1177       isValidMsgOp(MsgId, OpId) &&
1178       isValidMsgStream(MsgId, OpId, StreamId)) {
1179     O << "sendmsg(" << getMsgName(MsgId);
1180     if (msgRequiresOp(MsgId)) {
1181       O << ", " << getMsgOpName(MsgId, OpId);
1182       if (msgSupportsStream(MsgId, OpId)) {
1183         O << ", " << StreamId;
1184       }
1185     }
1186     O << ')';
1187   } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1188     O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1189   } else {
1190     O << Imm16; // Unknown imm16 code.
1191   }
1192 }
1193
1194 static void printSwizzleBitmask(const uint16_t AndMask,
1195                                 const uint16_t OrMask,
1196                                 const uint16_t XorMask,
1197                                 raw_ostream &O) {
1198   using namespace llvm::AMDGPU::Swizzle;
1199
1200   uint16_t Probe0 = ((0            & AndMask) | OrMask) ^ XorMask;
1201   uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1202
1203   O << "\"";
1204
1205   for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1206     uint16_t p0 = Probe0 & Mask;
1207     uint16_t p1 = Probe1 & Mask;
1208
1209     if (p0 == p1) {
1210       if (p0 == 0) {
1211         O << "0";
1212       } else {
1213         O << "1";
1214       }
1215     } else {
1216       if (p0 == 0) {
1217         O << "p";
1218       } else {
1219         O << "i";
1220       }
1221     }
1222   }
1223
1224   O << "\"";
1225 }
1226
1227 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1228                                      const MCSubtargetInfo &STI,
1229                                      raw_ostream &O) {
1230   using namespace llvm::AMDGPU::Swizzle;
1231
1232   uint16_t Imm = MI->getOperand(OpNo).getImm();
1233   if (Imm == 0) {
1234     return;
1235   }
1236
1237   O << " offset:";
1238
1239   if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1240
1241     O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1242     for (unsigned I = 0; I < LANE_NUM; ++I) {
1243       O << ",";
1244       O << formatDec(Imm & LANE_MASK);
1245       Imm >>= LANE_SHIFT;
1246     }
1247     O << ")";
1248
1249   } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1250
1251     uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1252     uint16_t OrMask  = (Imm >> BITMASK_OR_SHIFT)  & BITMASK_MASK;
1253     uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1254
1255     if (AndMask == BITMASK_MAX &&
1256         OrMask == 0 &&
1257         countPopulation(XorMask) == 1) {
1258
1259       O << "swizzle(" << IdSymbolic[ID_SWAP];
1260       O << ",";
1261       O << formatDec(XorMask);
1262       O << ")";
1263
1264     } else if (AndMask == BITMASK_MAX &&
1265                OrMask == 0 && XorMask > 0 &&
1266                isPowerOf2_64(XorMask + 1)) {
1267
1268       O << "swizzle(" << IdSymbolic[ID_REVERSE];
1269       O << ",";
1270       O << formatDec(XorMask + 1);
1271       O << ")";
1272
1273     } else {
1274
1275       uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1276       if (GroupSize > 1 &&
1277           isPowerOf2_64(GroupSize) &&
1278           OrMask < GroupSize &&
1279           XorMask == 0) {
1280
1281         O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1282         O << ",";
1283         O << formatDec(GroupSize);
1284         O << ",";
1285         O << formatDec(OrMask);
1286         O << ")";
1287
1288       } else {
1289         O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1290         O << ",";
1291         printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1292         O << ")";
1293       }
1294     }
1295   } else {
1296     printU16ImmDecOperand(MI, OpNo, O);
1297   }
1298 }
1299
1300 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1301                                       const MCSubtargetInfo &STI,
1302                                       raw_ostream &O) {
1303   AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1304
1305   unsigned SImm16 = MI->getOperand(OpNo).getImm();
1306   unsigned Vmcnt, Expcnt, Lgkmcnt;
1307   decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1308
1309   bool NeedSpace = false;
1310
1311   if (Vmcnt != getVmcntBitMask(ISA)) {
1312     O << "vmcnt(" << Vmcnt << ')';
1313     NeedSpace = true;
1314   }
1315
1316   if (Expcnt != getExpcntBitMask(ISA)) {
1317     if (NeedSpace)
1318       O << ' ';
1319     O << "expcnt(" << Expcnt << ')';
1320     NeedSpace = true;
1321   }
1322
1323   if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1324     if (NeedSpace)
1325       O << ' ';
1326     O << "lgkmcnt(" << Lgkmcnt << ')';
1327   }
1328 }
1329
1330 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1331                                    const MCSubtargetInfo &STI, raw_ostream &O) {
1332   unsigned Id;
1333   unsigned Offset;
1334   unsigned Width;
1335
1336   using namespace llvm::AMDGPU::Hwreg;
1337   unsigned Val = MI->getOperand(OpNo).getImm();
1338   decodeHwreg(Val, Id, Offset, Width);
1339   StringRef HwRegName = getHwreg(Id, STI);
1340
1341   O << "hwreg(";
1342   if (!HwRegName.empty()) {
1343     O << HwRegName;
1344   } else {
1345     O << Id;
1346   }
1347   if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1348     O << ", " << Offset << ", " << Width;
1349   }
1350   O << ')';
1351 }
1352
1353 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1354                                     const MCSubtargetInfo &STI,
1355                                     raw_ostream &O) {
1356   uint16_t Imm = MI->getOperand(OpNo).getImm();
1357   if (Imm == 0) {
1358     return;
1359   }
1360
1361   O << ' ' << formatDec(Imm);
1362 }
1363
1364 #include "AMDGPUGenAsmWriter.inc"
1365
1366 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
1367                                 StringRef Annot, const MCSubtargetInfo &STI) {
1368   O.flush();
1369   printInstruction(MI, O);
1370   printAnnotation(O, Annot);
1371 }
1372
1373 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1374                                raw_ostream &O) {
1375   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1376 }
1377
1378 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1379                                        raw_ostream &O) {
1380   int BankSwizzle = MI->getOperand(OpNo).getImm();
1381   switch (BankSwizzle) {
1382   case 1:
1383     O << "BS:VEC_021/SCL_122";
1384     break;
1385   case 2:
1386     O << "BS:VEC_120/SCL_212";
1387     break;
1388   case 3:
1389     O << "BS:VEC_102/SCL_221";
1390     break;
1391   case 4:
1392     O << "BS:VEC_201";
1393     break;
1394   case 5:
1395     O << "BS:VEC_210";
1396     break;
1397   default:
1398     break;
1399   }
1400 }
1401
1402 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1403                                  raw_ostream &O) {
1404   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1405 }
1406
1407 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1408                                 raw_ostream &O) {
1409   unsigned CT = MI->getOperand(OpNo).getImm();
1410   switch (CT) {
1411   case 0:
1412     O << 'U';
1413     break;
1414   case 1:
1415     O << 'N';
1416     break;
1417   default:
1418     break;
1419   }
1420 }
1421
1422 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1423                                   raw_ostream &O) {
1424   int KCacheMode = MI->getOperand(OpNo).getImm();
1425   if (KCacheMode > 0) {
1426     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1427     O << "CB" << KCacheBank << ':';
1428     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1429     int LineSize = (KCacheMode == 1) ? 16 : 32;
1430     O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1431   }
1432 }
1433
1434 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1435                                 raw_ostream &O) {
1436   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1437 }
1438
1439 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1440                                    raw_ostream &O) {
1441   const MCOperand &Op = MI->getOperand(OpNo);
1442   assert(Op.isImm() || Op.isExpr());
1443   if (Op.isImm()) {
1444     int64_t Imm = Op.getImm();
1445     O << Imm << '(' << BitsToFloat(Imm) << ')';
1446   }
1447   if (Op.isExpr()) {
1448     Op.getExpr()->print(O << '@', &MAI);
1449   }
1450 }
1451
1452 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1453                                raw_ostream &O) {
1454   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1455 }
1456
1457 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1458                                 raw_ostream &O) {
1459   switch (MI->getOperand(OpNo).getImm()) {
1460   default: break;
1461   case 1:
1462     O << " * 2.0";
1463     break;
1464   case 2:
1465     O << " * 4.0";
1466     break;
1467   case 3:
1468     O << " / 2.0";
1469     break;
1470   }
1471 }
1472
1473 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1474                                       raw_ostream &O) {
1475   printOperand(MI, OpNo, O);
1476   O  << ", ";
1477   printOperand(MI, OpNo + 1, O);
1478 }
1479
1480 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1481                                    raw_ostream &O) {
1482   if (OpNo >= MI->getNumOperands()) {
1483     O << "/*Missing OP" << OpNo << "*/";
1484     return;
1485   }
1486
1487   const MCOperand &Op = MI->getOperand(OpNo);
1488   if (Op.isReg()) {
1489     switch (Op.getReg()) {
1490     // This is the default predicate state, so we don't need to print it.
1491     case R600::PRED_SEL_OFF:
1492       break;
1493
1494     default:
1495       O << getRegisterName(Op.getReg());
1496       break;
1497     }
1498   } else if (Op.isImm()) {
1499       O << Op.getImm();
1500   } else if (Op.isFPImm()) {
1501     // We special case 0.0 because otherwise it will be printed as an integer.
1502     if (Op.getFPImm() == 0.0)
1503       O << "0.0";
1504     else {
1505       O << Op.getFPImm();
1506     }
1507   } else if (Op.isExpr()) {
1508     const MCExpr *Exp = Op.getExpr();
1509     Exp->print(O, &MAI);
1510   } else {
1511     O << "/*INV_OP*/";
1512   }
1513 }
1514
1515 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1516                                raw_ostream &O) {
1517   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1518 }
1519
1520 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1521                                   raw_ostream &O) {
1522   unsigned Sel = MI->getOperand(OpNo).getImm();
1523   switch (Sel) {
1524   case 0:
1525     O << 'X';
1526     break;
1527   case 1:
1528     O << 'Y';
1529     break;
1530   case 2:
1531     O << 'Z';
1532     break;
1533   case 3:
1534     O << 'W';
1535     break;
1536   case 4:
1537     O << '0';
1538     break;
1539   case 5:
1540     O << '1';
1541     break;
1542   case 7:
1543     O << '_';
1544     break;
1545   default:
1546     break;
1547   }
1548 }
1549
1550 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1551                                           raw_ostream &O) {
1552   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1553 }
1554
1555 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1556                                       raw_ostream &O) {
1557   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1558 }
1559
1560 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1561                                  raw_ostream &O) {
1562   const MCOperand &Op = MI->getOperand(OpNo);
1563   if (Op.getImm() == 0) {
1564     O << " (MASKED)";
1565   }
1566 }
1567
1568 #include "R600GenAsmWriter.inc"