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