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