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