xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (revision 454322c08b8aa181939c8d920472f03cfd591032)
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/MCAsmInfo.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrDesc.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/TargetParser/TargetParser.h"
23 
24 using namespace llvm;
25 using namespace llvm::AMDGPU;
26 
27 void AMDGPUInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {
28   // FIXME: The current implementation of
29   // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
30   // as an integer or we provide a name which represents a physical register.
31   // For CFI instructions we really want to emit a name for the DWARF register
32   // instead, because there may be multiple DWARF registers corresponding to a
33   // single physical register. One case where this problem manifests is with
34   // wave32/wave64 where using the physical register name is ambiguous: if we
35   // write e.g. `.cfi_undefined v0` we lose information about the wavefront
36   // size which we need to encode the register in the final DWARF. Ideally we
37   // would extend MC to support parsing DWARF register names so we could do
38   // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
39   // non-pretty DWARF register names in assembly text.
40   OS << Reg.id();
41 }
42 
43 void AMDGPUInstPrinter::printInst(const MCInst *MI, uint64_t Address,
44                                   StringRef Annot, const MCSubtargetInfo &STI,
45                                   raw_ostream &OS) {
46   printInstruction(MI, Address, STI, OS);
47   printAnnotation(OS, Annot);
48 }
49 
50 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
51                                            const MCSubtargetInfo &STI,
52                                            raw_ostream &O) {
53   const MCOperand &Op = MI->getOperand(OpNo);
54   if (Op.isExpr()) {
55     MAI.printExpr(O, *Op.getExpr());
56     return;
57   }
58 
59   // It's possible to end up with a 32-bit literal used with a 16-bit operand
60   // with ignored high bits. Print as 32-bit anyway in that case.
61   int64_t Imm = Op.getImm();
62   if (isInt<16>(Imm) || isUInt<16>(Imm))
63     O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
64   else
65     printU32ImmOperand(MI, OpNo, STI, O);
66 }
67 
68 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
69                                               raw_ostream &O) {
70   O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
71 }
72 
73 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
74                                            const MCSubtargetInfo &STI,
75                                            raw_ostream &O) {
76   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
77 }
78 
79 void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
80                                             const MCSubtargetInfo &STI,
81                                             raw_ostream &O) {
82   // KIMM64
83   // This part needs to align with AMDGPUInstPrinter::printImmediate64.
84   uint64_t Imm = MI->getOperand(OpNo).getImm();
85   if (STI.hasFeature(AMDGPU::Feature64BitLiterals) && Lo_32(Imm))
86     O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
87   else
88     O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
89 }
90 
91 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
92                                       raw_ostream &O, StringRef BitName) {
93   if (MI->getOperand(OpNo).getImm()) {
94     O << ' ' << BitName;
95   }
96 }
97 
98 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
99                                     const MCSubtargetInfo &STI,
100                                     raw_ostream &O) {
101   uint32_t Imm = MI->getOperand(OpNo).getImm();
102   if (Imm != 0) {
103     O << " offset:";
104 
105     // GFX12 uses a 24-bit signed offset for VBUFFER.
106     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
107     bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);
108     if (AMDGPU::isGFX12(STI) && IsVBuffer)
109       O << formatDec(SignExtend32<24>(Imm));
110     else
111       printU16ImmDecOperand(MI, OpNo, O);
112   }
113 }
114 
115 void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
116                                         const MCSubtargetInfo &STI,
117                                         raw_ostream &O) {
118   uint32_t Imm = MI->getOperand(OpNo).getImm();
119   if (Imm != 0) {
120     O << " offset:";
121 
122     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
123     bool AllowNegative = (Desc.TSFlags & (SIInstrFlags::FlatGlobal |
124                                           SIInstrFlags::FlatScratch)) ||
125                          AMDGPU::isGFX12(STI);
126 
127     if (AllowNegative) // Signed offset
128       O << formatDec(SignExtend32(Imm, AMDGPU::getNumFlatOffsetBits(STI)));
129     else // Unsigned offset
130       printU16ImmDecOperand(MI, OpNo, O);
131   }
132 }
133 
134 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
135                                         const MCSubtargetInfo &STI,
136                                         raw_ostream &O) {
137   printU32ImmOperand(MI, OpNo, STI, O);
138 }
139 
140 void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
141                                         const MCSubtargetInfo &STI,
142                                         raw_ostream &O) {
143   O << formatHex(MI->getOperand(OpNo).getImm());
144 }
145 
146 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
147                                                const MCSubtargetInfo &STI,
148                                                raw_ostream &O) {
149   printU32ImmOperand(MI, OpNo, STI, O);
150 }
151 
152 void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
153                                   const MCSubtargetInfo &STI, raw_ostream &O) {
154   auto Imm = MI->getOperand(OpNo).getImm();
155 
156   if (AMDGPU::isGFX12Plus(STI)) {
157     const int64_t TH = Imm & CPol::TH;
158     const int64_t Scope = Imm & CPol::SCOPE;
159 
160     printTH(MI, TH, Scope, O);
161     printScope(Scope, O);
162 
163     return;
164   }
165 
166   if (Imm & CPol::GLC)
167     O << ((AMDGPU::isGFX940(STI) &&
168            !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
169                                                                      : " glc");
170   if (Imm & CPol::SLC)
171     O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
172   if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
173     O << " dlc";
174   if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
175     O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
176   if (Imm & ~CPol::ALL_pregfx12)
177     O << " /* unexpected cache policy bit */";
178 }
179 
180 void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,
181                                 raw_ostream &O) {
182   // For th = 0 do not print this field
183   if (TH == 0)
184     return;
185 
186   const unsigned Opcode = MI->getOpcode();
187   const MCInstrDesc &TID = MII.get(Opcode);
188   unsigned THType = AMDGPU::getTemporalHintType(TID);
189   bool IsStore = (THType == AMDGPU::CPol::TH_TYPE_STORE);
190 
191   O << " th:";
192 
193   if (THType == AMDGPU::CPol::TH_TYPE_ATOMIC) {
194     O << "TH_ATOMIC_";
195     if (TH & AMDGPU::CPol::TH_ATOMIC_CASCADE) {
196       if (Scope >= AMDGPU::CPol::SCOPE_DEV)
197         O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");
198       else
199         O << formatHex(TH);
200     } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)
201       O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");
202     else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)
203       O << "RETURN";
204     else
205       O << formatHex(TH);
206   } else {
207     if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)
208       O << formatHex(TH);
209     else {
210       O << (IsStore ? "TH_STORE_" : "TH_LOAD_");
211       switch (TH) {
212       case AMDGPU::CPol::TH_NT:
213         O << "NT";
214         break;
215       case AMDGPU::CPol::TH_HT:
216         O << "HT";
217         break;
218       case AMDGPU::CPol::TH_BYPASS: // or LU or WB
219         O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"
220                                                : (IsStore ? "WB" : "LU"));
221         break;
222       case AMDGPU::CPol::TH_NT_RT:
223         O << "NT_RT";
224         break;
225       case AMDGPU::CPol::TH_RT_NT:
226         O << "RT_NT";
227         break;
228       case AMDGPU::CPol::TH_NT_HT:
229         O << "NT_HT";
230         break;
231       case AMDGPU::CPol::TH_NT_WB:
232         O << "NT_WB";
233         break;
234       default:
235         llvm_unreachable("unexpected th value");
236       }
237     }
238   }
239 }
240 
241 void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {
242   if (Scope == CPol::SCOPE_CU)
243     return;
244 
245   O << " scope:";
246 
247   if (Scope == CPol::SCOPE_SE)
248     O << "SCOPE_SE";
249   else if (Scope == CPol::SCOPE_DEV)
250     O << "SCOPE_DEV";
251   else if (Scope == CPol::SCOPE_SYS)
252     O << "SCOPE_SYS";
253   else
254     llvm_unreachable("unexpected scope policy value");
255 }
256 
257 void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
258                                  const MCSubtargetInfo &STI, raw_ostream &O) {
259   unsigned Dim = MI->getOperand(OpNo).getImm();
260   O << " dim:SQ_RSRC_IMG_";
261 
262   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
263   if (DimInfo)
264     O << DimInfo->AsmSuffix;
265   else
266     O << Dim;
267 }
268 
269 void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
270                                   const MCSubtargetInfo &STI, raw_ostream &O) {
271   if (STI.hasFeature(AMDGPU::FeatureR128A16))
272     printNamedBit(MI, OpNo, O, "a16");
273   else
274     printNamedBit(MI, OpNo, O, "r128");
275 }
276 
277 void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
278                                     const MCSubtargetInfo &STI,
279                                     raw_ostream &O) {
280 }
281 
282 void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
283                                             const MCSubtargetInfo &STI,
284                                             raw_ostream &O) {
285   using namespace llvm::AMDGPU::MTBUFFormat;
286 
287   int OpNo =
288     AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
289   assert(OpNo != -1);
290 
291   unsigned Val = MI->getOperand(OpNo).getImm();
292   if (AMDGPU::isGFX10Plus(STI)) {
293     if (Val == UFMT_DEFAULT)
294       return;
295     if (isValidUnifiedFormat(Val, STI)) {
296       O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
297     } else {
298       O << " format:" << Val;
299     }
300   } else {
301     if (Val == DFMT_NFMT_DEFAULT)
302       return;
303     if (isValidDfmtNfmt(Val, STI)) {
304       unsigned Dfmt;
305       unsigned Nfmt;
306       decodeDfmtNfmt(Val, Dfmt, Nfmt);
307       O << " format:[";
308       if (Dfmt != DFMT_DEFAULT) {
309         O << getDfmtName(Dfmt);
310         if (Nfmt != NFMT_DEFAULT) {
311           O << ',';
312         }
313       }
314       if (Nfmt != NFMT_DEFAULT) {
315         O << getNfmtName(Nfmt, STI);
316       }
317       O << ']';
318     } else {
319       O << " format:" << Val;
320     }
321   }
322 }
323 
324 void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,
325                                         const MCRegisterInfo &MRI) {
326 #if !defined(NDEBUG)
327   switch (Reg.id()) {
328   case AMDGPU::FP_REG:
329   case AMDGPU::SP_REG:
330   case AMDGPU::PRIVATE_RSRC_REG:
331     llvm_unreachable("pseudo-register should not ever be emitted");
332   default:
333     break;
334   }
335 #endif
336 
337   O << getRegisterName(Reg);
338 }
339 
340 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
341                                     const MCSubtargetInfo &STI, raw_ostream &O) {
342   auto Opcode = MI->getOpcode();
343   auto Flags = MII.get(Opcode).TSFlags;
344   if (OpNo == 0) {
345     if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
346       O << "_e64_dpp";
347     else if (Flags & SIInstrFlags::VOP3) {
348       if (!getVOP3IsSingle(Opcode))
349         O << "_e64";
350     } else if (Flags & SIInstrFlags::DPP)
351       O << "_dpp";
352     else if (Flags & SIInstrFlags::SDWA)
353       O << "_sdwa";
354     else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
355              ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
356       O << "_e32";
357     O << " ";
358   }
359 
360   printRegularOperand(MI, OpNo, STI, O);
361 
362   // Print default vcc/vcc_lo operand.
363   switch (Opcode) {
364   default: break;
365 
366   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
367   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
368   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
369   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
370   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
371   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
372   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
373   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
374   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
375   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
376   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
377   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
378   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
379   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
380   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
381   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
382   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
383   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
384   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
385   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
386   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
387   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
388   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
389   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
390   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
391   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
392   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
393   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
394   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
395   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
396     printDefaultVccOperand(false, STI, O);
397     break;
398   }
399 }
400 
401 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
402                                        const MCSubtargetInfo &STI, raw_ostream &O) {
403   if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
404     O << " ";
405   else
406     O << "_e32 ";
407 
408   printRegularOperand(MI, OpNo, STI, O);
409 }
410 
411 void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
412                                             const MCSubtargetInfo &STI,
413                                             raw_ostream &O) {
414   int32_t SImm = static_cast<int32_t>(Imm);
415   if (isInlinableIntLiteral(SImm)) {
416     O << SImm;
417     return;
418   }
419 
420   if (printImmediateFloat32(Imm, STI, O))
421     return;
422 
423   O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
424 }
425 
426 static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI,
427                                raw_ostream &O) {
428   if (Imm == 0x3C00)
429     O << "1.0";
430   else if (Imm == 0xBC00)
431     O << "-1.0";
432   else if (Imm == 0x3800)
433     O << "0.5";
434   else if (Imm == 0xB800)
435     O << "-0.5";
436   else if (Imm == 0x4000)
437     O << "2.0";
438   else if (Imm == 0xC000)
439     O << "-2.0";
440   else if (Imm == 0x4400)
441     O << "4.0";
442   else if (Imm == 0xC400)
443     O << "-4.0";
444   else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
445     O << "0.15915494";
446   else
447     return false;
448 
449   return true;
450 }
451 
452 static bool printImmediateBFloat16(uint32_t Imm, const MCSubtargetInfo &STI,
453                                    raw_ostream &O) {
454   if (Imm == 0x3F80)
455     O << "1.0";
456   else if (Imm == 0xBF80)
457     O << "-1.0";
458   else if (Imm == 0x3F00)
459     O << "0.5";
460   else if (Imm == 0xBF00)
461     O << "-0.5";
462   else if (Imm == 0x4000)
463     O << "2.0";
464   else if (Imm == 0xC000)
465     O << "-2.0";
466   else if (Imm == 0x4080)
467     O << "4.0";
468   else if (Imm == 0xC080)
469     O << "-4.0";
470   else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
471     O << "0.15915494";
472   else
473     return false;
474 
475   return true;
476 }
477 
478 void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,
479                                            const MCSubtargetInfo &STI,
480                                            raw_ostream &O) {
481   int16_t SImm = static_cast<int16_t>(Imm);
482   if (isInlinableIntLiteral(SImm)) {
483     O << SImm;
484     return;
485   }
486 
487   if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
488     return;
489 
490   O << formatHex(static_cast<uint64_t>(Imm));
491 }
492 
493 void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,
494                                           const MCSubtargetInfo &STI,
495                                           raw_ostream &O) {
496   int16_t SImm = static_cast<int16_t>(Imm);
497   if (isInlinableIntLiteral(SImm)) {
498     O << SImm;
499     return;
500   }
501 
502   uint16_t HImm = static_cast<uint16_t>(Imm);
503   if (printImmediateFP16(HImm, STI, O))
504     return;
505 
506   uint64_t Imm16 = static_cast<uint16_t>(Imm);
507   O << formatHex(Imm16);
508 }
509 
510 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,
511                                            const MCSubtargetInfo &STI,
512                                            raw_ostream &O) {
513   int32_t SImm = static_cast<int32_t>(Imm);
514   if (isInlinableIntLiteral(SImm)) {
515     O << SImm;
516     return;
517   }
518 
519   switch (OpType) {
520   case AMDGPU::OPERAND_REG_IMM_V2INT16:
521   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
522     if (printImmediateFloat32(Imm, STI, O))
523       return;
524     break;
525   case AMDGPU::OPERAND_REG_IMM_V2FP16:
526   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
527     if (isUInt<16>(Imm) &&
528         printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
529       return;
530     break;
531   case AMDGPU::OPERAND_REG_IMM_V2BF16:
532   case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
533     if (isUInt<16>(Imm) &&
534         printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
535       return;
536     break;
537   default:
538     llvm_unreachable("bad operand type");
539   }
540 
541   O << formatHex(static_cast<uint64_t>(Imm));
542 }
543 
544 bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,
545                                               const MCSubtargetInfo &STI,
546                                               raw_ostream &O) {
547   if (Imm == llvm::bit_cast<uint32_t>(0.0f))
548     O << "0.0";
549   else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
550     O << "1.0";
551   else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
552     O << "-1.0";
553   else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
554     O << "0.5";
555   else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
556     O << "-0.5";
557   else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
558     O << "2.0";
559   else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
560     O << "-2.0";
561   else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
562     O << "4.0";
563   else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
564     O << "-4.0";
565   else if (Imm == 0x3e22f983 &&
566            STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
567     O << "0.15915494";
568   else
569     return false;
570 
571   return true;
572 }
573 
574 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
575                                          const MCSubtargetInfo &STI,
576                                          raw_ostream &O) {
577   int32_t SImm = static_cast<int32_t>(Imm);
578   if (isInlinableIntLiteral(SImm)) {
579     O << SImm;
580     return;
581   }
582 
583   if (printImmediateFloat32(Imm, STI, O))
584     return;
585 
586   O << formatHex(static_cast<uint64_t>(Imm));
587 }
588 
589 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
590                                          const MCSubtargetInfo &STI,
591                                          raw_ostream &O, bool IsFP) {
592   int64_t SImm = static_cast<int64_t>(Imm);
593   if (SImm >= -16 && SImm <= 64) {
594     O << SImm;
595     return;
596   }
597 
598   if (Imm == llvm::bit_cast<uint64_t>(0.0))
599     O << "0.0";
600   else if (Imm == llvm::bit_cast<uint64_t>(1.0))
601     O << "1.0";
602   else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
603     O << "-1.0";
604   else if (Imm == llvm::bit_cast<uint64_t>(0.5))
605     O << "0.5";
606   else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
607     O << "-0.5";
608   else if (Imm == llvm::bit_cast<uint64_t>(2.0))
609     O << "2.0";
610   else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
611     O << "-2.0";
612   else if (Imm == llvm::bit_cast<uint64_t>(4.0))
613     O << "4.0";
614   else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
615     O << "-4.0";
616   else if (Imm == 0x3fc45f306dc9c882 &&
617            STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
618     O << "0.15915494309189532";
619   else {
620     // This part needs to align with AMDGPUOperand::addLiteralImmOperand.
621     if (IsFP) {
622       if (STI.hasFeature(AMDGPU::Feature64BitLiterals) && Lo_32(Imm))
623         O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
624       else
625         O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
626       return;
627     }
628 
629     if (STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
630         (!isInt<32>(Imm) || !isUInt<32>(Imm)))
631       O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
632     else
633       O << formatHex(static_cast<uint64_t>(Imm));
634   }
635 }
636 
637 void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
638                                   const MCSubtargetInfo &STI,
639                                   raw_ostream &O) {
640   unsigned Imm = MI->getOperand(OpNo).getImm();
641   if (!Imm)
642     return;
643 
644   if (AMDGPU::isGFX940(STI)) {
645     switch (MI->getOpcode()) {
646     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
647     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
648     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
649     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
650       O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
651         << ((Imm >> 2) & 1) << ']';
652       return;
653     }
654   }
655 
656   O << " blgp:" << Imm;
657 }
658 
659 void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
660                                                const MCSubtargetInfo &STI,
661                                                raw_ostream &O) {
662   if (!FirstOperand)
663     O << ", ";
664   printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize32)
665                       ? AMDGPU::VCC_LO
666                       : AMDGPU::VCC,
667                   O, MRI);
668   if (FirstOperand)
669     O << ", ";
670 }
671 
672 bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
673                                         unsigned OpNo) const {
674   return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
675          (Desc.TSFlags & SIInstrFlags::VOPC) &&
676          !isVOPCAsmOnly(Desc.getOpcode()) &&
677          (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
678           Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
679 }
680 
681 // Print default vcc/vcc_lo operand of VOPC.
682 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
683                                      const MCSubtargetInfo &STI,
684                                      raw_ostream &O) {
685   unsigned Opc = MI->getOpcode();
686   const MCInstrDesc &Desc = MII.get(Opc);
687   int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
688   // 0, 1 and 2 are the first printed operands in different cases
689   // If there are printed modifiers, printOperandAndFPInputMods or
690   // printOperandAndIntInputMods will be called instead
691   if ((OpNo == 0 ||
692        (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
693       (Desc.TSFlags & SIInstrFlags::VOPC) && !isVOPCAsmOnly(Desc.getOpcode()) &&
694       (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
695        Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
696     printDefaultVccOperand(true, STI, O);
697 
698   printRegularOperand(MI, OpNo, STI, O);
699 }
700 
701 // Print operands after vcc or modifier handling.
702 void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
703                                             const MCSubtargetInfo &STI,
704                                             raw_ostream &O) {
705   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
706 
707   if (OpNo >= MI->getNumOperands()) {
708     O << "/*Missing OP" << OpNo << "*/";
709     return;
710   }
711 
712   const MCOperand &Op = MI->getOperand(OpNo);
713   if (Op.isReg()) {
714     printRegOperand(Op.getReg(), O, MRI);
715 
716     // Check if operand register class contains register used.
717     // Intention: print disassembler message when invalid code is decoded,
718     // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
719     int RCID = Desc.operands()[OpNo].RegClass;
720     if (RCID != -1) {
721       const MCRegisterClass RC = MRI.getRegClass(RCID);
722       auto Reg = mc2PseudoReg(Op.getReg());
723       if (!RC.contains(Reg) && !isInlineValue(Reg)) {
724         O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
725           << "\' register class*/";
726       }
727     }
728   } else if (Op.isImm()) {
729     const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
730     switch (OpTy) {
731     case AMDGPU::OPERAND_REG_IMM_INT32:
732     case AMDGPU::OPERAND_REG_IMM_FP32:
733     case AMDGPU::OPERAND_REG_INLINE_C_INT32:
734     case AMDGPU::OPERAND_REG_INLINE_C_FP32:
735     case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
736     case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
737     case AMDGPU::OPERAND_REG_IMM_V2INT32:
738     case AMDGPU::OPERAND_REG_IMM_V2FP32:
739     case MCOI::OPERAND_IMMEDIATE:
740     case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
741       printImmediate32(Op.getImm(), STI, O);
742       break;
743     case AMDGPU::OPERAND_REG_IMM_INT64:
744     case AMDGPU::OPERAND_REG_INLINE_C_INT64:
745       printImmediate64(Op.getImm(), STI, O, false);
746       break;
747     case AMDGPU::OPERAND_REG_IMM_FP64:
748     case AMDGPU::OPERAND_REG_INLINE_C_FP64:
749     case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
750       printImmediate64(Op.getImm(), STI, O, true);
751       break;
752     case AMDGPU::OPERAND_REG_INLINE_C_INT16:
753     case AMDGPU::OPERAND_REG_IMM_INT16:
754       printImmediateInt16(Op.getImm(), STI, O);
755       break;
756     case AMDGPU::OPERAND_REG_INLINE_C_FP16:
757     case AMDGPU::OPERAND_REG_IMM_FP16:
758       printImmediateF16(Op.getImm(), STI, O);
759       break;
760     case AMDGPU::OPERAND_REG_INLINE_C_BF16:
761     case AMDGPU::OPERAND_REG_IMM_BF16:
762       printImmediateBF16(Op.getImm(), STI, O);
763       break;
764     case AMDGPU::OPERAND_REG_IMM_V2INT16:
765     case AMDGPU::OPERAND_REG_IMM_V2BF16:
766     case AMDGPU::OPERAND_REG_IMM_V2FP16:
767     case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
768     case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
769     case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
770       printImmediateV216(Op.getImm(), OpTy, STI, O);
771       break;
772     case MCOI::OPERAND_UNKNOWN:
773     case MCOI::OPERAND_PCREL:
774       O << formatDec(Op.getImm());
775       break;
776     case MCOI::OPERAND_REGISTER:
777       // Disassembler does not fail when operand should not allow immediate
778       // operands but decodes them into 32bit immediate operand.
779       printImmediate32(Op.getImm(), STI, O);
780       O << "/*Invalid immediate*/";
781       break;
782     default:
783       // We hit this for the immediate instruction bits that don't yet have a
784       // custom printer.
785       llvm_unreachable("unexpected immediate operand type");
786     }
787   } else if (Op.isDFPImm()) {
788     double Value = bit_cast<double>(Op.getDFPImm());
789     // We special case 0.0 because otherwise it will be printed as an integer.
790     if (Value == 0.0)
791       O << "0.0";
792     else {
793       const MCInstrDesc &Desc = MII.get(MI->getOpcode());
794       int RCID = Desc.operands()[OpNo].RegClass;
795       unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
796       if (RCBits == 32)
797         printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
798       else if (RCBits == 64)
799         printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
800       else
801         llvm_unreachable("Invalid register class size");
802     }
803   } else if (Op.isExpr()) {
804     const MCExpr *Exp = Op.getExpr();
805     MAI.printExpr(O, *Exp);
806   } else {
807     O << "/*INV_OP*/";
808   }
809 
810   // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
811   switch (MI->getOpcode()) {
812   default: break;
813 
814   case AMDGPU::V_CNDMASK_B32_e32_gfx10:
815   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
816   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
817   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
818   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
819   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
820   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
821   case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
822   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
823   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
824   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
825   case AMDGPU::V_CNDMASK_B32_e32_gfx11:
826   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
827   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
828   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
829   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
830   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
831   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
832   case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
833   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
834   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
835   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
836   case AMDGPU::V_CNDMASK_B32_e32_gfx12:
837   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
838   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
839   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
840   case AMDGPU::V_CNDMASK_B32_dpp_gfx12:
841   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
842   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
843   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
844   case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:
845   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
846   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
847   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
848 
849   case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
850   case AMDGPU::V_CNDMASK_B32_e32_vi:
851     if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
852                                                 AMDGPU::OpName::src1))
853       printDefaultVccOperand(OpNo == 0, STI, O);
854     break;
855   }
856 
857   if (Desc.TSFlags & SIInstrFlags::MTBUF) {
858     int SOffsetIdx =
859       AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
860     assert(SOffsetIdx != -1);
861     if ((int)OpNo == SOffsetIdx)
862       printSymbolicFormat(MI, STI, O);
863   }
864 }
865 
866 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
867                                                    unsigned OpNo,
868                                                    const MCSubtargetInfo &STI,
869                                                    raw_ostream &O) {
870   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
871   if (needsImpliedVcc(Desc, OpNo))
872     printDefaultVccOperand(true, STI, O);
873 
874   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
875 
876   // Use 'neg(...)' instead of '-' to avoid ambiguity.
877   // This is important for integer literals because
878   // -1 is not the same value as neg(1).
879   bool NegMnemo = false;
880 
881   if (InputModifiers & SISrcMods::NEG) {
882     if (OpNo + 1 < MI->getNumOperands() &&
883         (InputModifiers & SISrcMods::ABS) == 0) {
884       const MCOperand &Op = MI->getOperand(OpNo + 1);
885       NegMnemo = Op.isImm() || Op.isDFPImm();
886     }
887     if (NegMnemo) {
888       O << "neg(";
889     } else {
890       O << '-';
891     }
892   }
893 
894   if (InputModifiers & SISrcMods::ABS)
895     O << '|';
896   printRegularOperand(MI, OpNo + 1, STI, O);
897   if (InputModifiers & SISrcMods::ABS)
898     O << '|';
899 
900   if (NegMnemo) {
901     O << ')';
902   }
903 
904   // Print default vcc/vcc_lo operand of VOP2b.
905   switch (MI->getOpcode()) {
906   default:
907     break;
908 
909   case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
910   case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
911   case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
912     if ((int)OpNo + 1 ==
913         AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
914       printDefaultVccOperand(OpNo == 0, STI, O);
915     break;
916   }
917 }
918 
919 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
920                                                     unsigned OpNo,
921                                                     const MCSubtargetInfo &STI,
922                                                     raw_ostream &O) {
923   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
924   if (needsImpliedVcc(Desc, OpNo))
925     printDefaultVccOperand(true, STI, O);
926 
927   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
928   if (InputModifiers & SISrcMods::SEXT)
929     O << "sext(";
930   printRegularOperand(MI, OpNo + 1, STI, O);
931   if (InputModifiers & SISrcMods::SEXT)
932     O << ')';
933 
934   // Print default vcc/vcc_lo operand of VOP2b.
935   switch (MI->getOpcode()) {
936   default: break;
937 
938   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
939   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
940   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
941     if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
942                                                     AMDGPU::OpName::src1))
943       printDefaultVccOperand(OpNo == 0, STI, O);
944     break;
945   }
946 }
947 
948 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
949                                   const MCSubtargetInfo &STI,
950                                   raw_ostream &O) {
951   if (!AMDGPU::isGFX10Plus(STI))
952     llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
953 
954   unsigned Imm = MI->getOperand(OpNo).getImm();
955   O << "dpp8:[" << formatDec(Imm & 0x7);
956   for (size_t i = 1; i < 8; ++i) {
957     O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
958   }
959   O << ']';
960 }
961 
962 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
963                                      const MCSubtargetInfo &STI,
964                                      raw_ostream &O) {
965   using namespace AMDGPU::DPP;
966 
967   unsigned Imm = MI->getOperand(OpNo).getImm();
968   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
969 
970   if (!AMDGPU::isLegalDPALU_DPPControl(Imm) && AMDGPU::isDPALU_DPP(Desc)) {
971     O << " /* DP ALU dpp only supports row_newbcast */";
972     return;
973   }
974   if (Imm <= DppCtrl::QUAD_PERM_LAST) {
975     O << "quad_perm:[";
976     O << formatDec(Imm & 0x3)         << ',';
977     O << formatDec((Imm & 0xc)  >> 2) << ',';
978     O << formatDec((Imm & 0x30) >> 4) << ',';
979     O << formatDec((Imm & 0xc0) >> 6) << ']';
980   } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
981              (Imm <= DppCtrl::ROW_SHL_LAST)) {
982     O << "row_shl:" << formatDec(Imm - DppCtrl::ROW_SHL0);
983   } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
984              (Imm <= DppCtrl::ROW_SHR_LAST)) {
985     O << "row_shr:" << formatDec(Imm - DppCtrl::ROW_SHR0);
986   } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
987              (Imm <= DppCtrl::ROW_ROR_LAST)) {
988     O << "row_ror:" << formatDec(Imm - DppCtrl::ROW_ROR0);
989   } else if (Imm == DppCtrl::WAVE_SHL1) {
990     if (AMDGPU::isGFX10Plus(STI)) {
991       O << "/* wave_shl is not supported starting from GFX10 */";
992       return;
993     }
994     O << "wave_shl:1";
995   } else if (Imm == DppCtrl::WAVE_ROL1) {
996     if (AMDGPU::isGFX10Plus(STI)) {
997       O << "/* wave_rol is not supported starting from GFX10 */";
998       return;
999     }
1000     O << "wave_rol:1";
1001   } else if (Imm == DppCtrl::WAVE_SHR1) {
1002     if (AMDGPU::isGFX10Plus(STI)) {
1003       O << "/* wave_shr is not supported starting from GFX10 */";
1004       return;
1005     }
1006     O << "wave_shr:1";
1007   } else if (Imm == DppCtrl::WAVE_ROR1) {
1008     if (AMDGPU::isGFX10Plus(STI)) {
1009       O << "/* wave_ror is not supported starting from GFX10 */";
1010       return;
1011     }
1012     O << "wave_ror:1";
1013   } else if (Imm == DppCtrl::ROW_MIRROR) {
1014     O << "row_mirror";
1015   } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
1016     O << "row_half_mirror";
1017   } else if (Imm == DppCtrl::BCAST15) {
1018     if (AMDGPU::isGFX10Plus(STI)) {
1019       O << "/* row_bcast is not supported starting from GFX10 */";
1020       return;
1021     }
1022     O << "row_bcast:15";
1023   } else if (Imm == DppCtrl::BCAST31) {
1024     if (AMDGPU::isGFX10Plus(STI)) {
1025       O << "/* row_bcast is not supported starting from GFX10 */";
1026       return;
1027     }
1028     O << "row_bcast:31";
1029   } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
1030              (Imm <= DppCtrl::ROW_SHARE_LAST)) {
1031     if (AMDGPU::isGFX90A(STI)) {
1032       O << "row_newbcast:";
1033     } else if (AMDGPU::isGFX10Plus(STI)) {
1034       O << "row_share:";
1035     } else {
1036       O << " /* row_newbcast/row_share is not supported on ASICs earlier "
1037            "than GFX90A/GFX10 */";
1038       return;
1039     }
1040     O << formatDec(Imm - DppCtrl::ROW_SHARE_FIRST);
1041   } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
1042              (Imm <= DppCtrl::ROW_XMASK_LAST)) {
1043     if (!AMDGPU::isGFX10Plus(STI)) {
1044       O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
1045       return;
1046     }
1047     O << "row_xmask:" << formatDec(Imm - DppCtrl::ROW_XMASK_FIRST);
1048   } else {
1049     O << "/* Invalid dpp_ctrl value */";
1050   }
1051 }
1052 
1053 void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
1054                                           const MCSubtargetInfo &STI,
1055                                           raw_ostream &O) {
1056   unsigned Imm = MI->getOperand(OpNo).getImm();
1057   if (Imm) {
1058     O << " bound_ctrl:1";
1059   }
1060 }
1061 
1062 void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
1063                                    const MCSubtargetInfo &STI, raw_ostream &O) {
1064   using namespace llvm::AMDGPU::DPP;
1065   unsigned Imm = MI->getOperand(OpNo).getImm();
1066   if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1067     O << " fi:1";
1068   }
1069 }
1070 
1071 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1072                                      raw_ostream &O) {
1073   using namespace llvm::AMDGPU::SDWA;
1074 
1075   unsigned Imm = MI->getOperand(OpNo).getImm();
1076   switch (Imm) {
1077   case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1078   case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1079   case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1080   case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1081   case SdwaSel::WORD_0: O << "WORD_0"; break;
1082   case SdwaSel::WORD_1: O << "WORD_1"; break;
1083   case SdwaSel::DWORD: O << "DWORD"; break;
1084   default: llvm_unreachable("Invalid SDWA data select operand");
1085   }
1086 }
1087 
1088 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1089                                         const MCSubtargetInfo &STI,
1090                                         raw_ostream &O) {
1091   O << "dst_sel:";
1092   printSDWASel(MI, OpNo, O);
1093 }
1094 
1095 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1096                                          const MCSubtargetInfo &STI,
1097                                          raw_ostream &O) {
1098   O << "src0_sel:";
1099   printSDWASel(MI, OpNo, O);
1100 }
1101 
1102 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1103                                          const MCSubtargetInfo &STI,
1104                                          raw_ostream &O) {
1105   O << "src1_sel:";
1106   printSDWASel(MI, OpNo, O);
1107 }
1108 
1109 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1110                                            const MCSubtargetInfo &STI,
1111                                            raw_ostream &O) {
1112   using namespace llvm::AMDGPU::SDWA;
1113 
1114   O << "dst_unused:";
1115   unsigned Imm = MI->getOperand(OpNo).getImm();
1116   switch (Imm) {
1117   case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1118   case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1119   case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1120   default: llvm_unreachable("Invalid SDWA dest_unused operand");
1121   }
1122 }
1123 
1124 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1125                                      const MCSubtargetInfo &STI, raw_ostream &O,
1126                                      unsigned N) {
1127   unsigned Opc = MI->getOpcode();
1128   int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1129   unsigned En = MI->getOperand(EnIdx).getImm();
1130 
1131   int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1132 
1133   // If compr is set, print as src0, src0, src1, src1
1134   if (MI->getOperand(ComprIdx).getImm())
1135     OpNo = OpNo - N + N / 2;
1136 
1137   if (En & (1 << N))
1138     printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
1139   else
1140     O << "off";
1141 }
1142 
1143 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1144                                      const MCSubtargetInfo &STI,
1145                                      raw_ostream &O) {
1146   printExpSrcN(MI, OpNo, STI, O, 0);
1147 }
1148 
1149 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1150                                      const MCSubtargetInfo &STI,
1151                                      raw_ostream &O) {
1152   printExpSrcN(MI, OpNo, STI, O, 1);
1153 }
1154 
1155 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1156                                      const MCSubtargetInfo &STI,
1157                                      raw_ostream &O) {
1158   printExpSrcN(MI, OpNo, STI, O, 2);
1159 }
1160 
1161 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1162                                      const MCSubtargetInfo &STI,
1163                                      raw_ostream &O) {
1164   printExpSrcN(MI, OpNo, STI, O, 3);
1165 }
1166 
1167 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1168                                     const MCSubtargetInfo &STI,
1169                                     raw_ostream &O) {
1170   using namespace llvm::AMDGPU::Exp;
1171 
1172   // This is really a 6 bit field.
1173   unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1174 
1175   int Index;
1176   StringRef TgtName;
1177   if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1178     O << ' ' << TgtName;
1179     if (Index >= 0)
1180       O << Index;
1181   } else {
1182     O << " invalid_target_" << Id;
1183   }
1184 }
1185 
1186 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1187                                bool IsPacked, bool HasDstSel) {
1188   int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1189 
1190   for (int I = 0; I < NumOps; ++I) {
1191     if (!!(Ops[I] & Mod) != DefaultValue)
1192       return false;
1193   }
1194 
1195   if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1196     return false;
1197 
1198   return true;
1199 }
1200 
1201 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1202                                             StringRef Name,
1203                                             unsigned Mod,
1204                                             raw_ostream &O) {
1205   unsigned Opc = MI->getOpcode();
1206   int NumOps = 0;
1207   int Ops[3];
1208 
1209   std::pair<AMDGPU::OpName, AMDGPU::OpName> MOps[] = {
1210       {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},
1211       {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},
1212       {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};
1213   int DefaultValue = (Mod == SISrcMods::OP_SEL_1);
1214 
1215   for (auto [SrcMod, Src] : MOps) {
1216     if (!AMDGPU::hasNamedOperand(Opc, Src))
1217       break;
1218 
1219     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);
1220     Ops[NumOps++] =
1221         (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;
1222   }
1223 
1224   const bool HasDst =
1225       (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst) != -1) ||
1226       (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst) != -1);
1227 
1228   // Print three values of neg/opsel for wmma instructions (prints 0 when there
1229   // is no src_modifier operand instead of not printing anything).
1230   if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsSWMMAC ||
1231       MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsWMMA) {
1232     NumOps = 0;
1233     int DefaultValue = Mod == SISrcMods::OP_SEL_1;
1234     for (AMDGPU::OpName OpName :
1235          {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
1236           AMDGPU::OpName::src2_modifiers}) {
1237       int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1238       if (Idx != -1)
1239         Ops[NumOps++] = MI->getOperand(Idx).getImm();
1240       else
1241         Ops[NumOps++] = DefaultValue;
1242     }
1243   }
1244 
1245   const bool HasDstSel =
1246       HasDst && NumOps > 0 && Mod == SISrcMods::OP_SEL_0 &&
1247       MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
1248 
1249   const bool IsPacked =
1250     MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
1251 
1252   if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1253     return;
1254 
1255   O << Name;
1256   for (int I = 0; I < NumOps; ++I) {
1257     if (I != 0)
1258       O << ',';
1259 
1260     O << !!(Ops[I] & Mod);
1261   }
1262 
1263   if (HasDstSel) {
1264     O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1265   }
1266 
1267   O << ']';
1268 }
1269 
1270 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1271                                    const MCSubtargetInfo &STI,
1272                                    raw_ostream &O) {
1273   unsigned Opc = MI->getOpcode();
1274   if (isCvt_F32_Fp8_Bf8_e64(Opc)) {
1275     auto SrcMod =
1276         AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1277     unsigned Mod = MI->getOperand(SrcMod).getImm();
1278     unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);
1279     unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);
1280     if (Index0 || Index1)
1281       O << " op_sel:[" << Index0 << ',' << Index1 << ']';
1282     return;
1283   }
1284   if (isPermlane16(Opc)) {
1285     auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1286     auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1287     unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1288     unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1289     if (FI || BC)
1290       O << " op_sel:[" << FI << ',' << BC << ']';
1291     return;
1292   }
1293 
1294   printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1295 }
1296 
1297 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1298                                      const MCSubtargetInfo &STI,
1299                                      raw_ostream &O) {
1300   printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1301 }
1302 
1303 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1304                                    const MCSubtargetInfo &STI,
1305                                    raw_ostream &O) {
1306   printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1307 }
1308 
1309 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1310                                    const MCSubtargetInfo &STI,
1311                                    raw_ostream &O) {
1312   printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1313 }
1314 
1315 void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,
1316                                           const MCSubtargetInfo &STI,
1317                                           raw_ostream &O) {
1318   auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1319   if (Imm == 0)
1320     return;
1321 
1322   O << " index_key:" << Imm;
1323 }
1324 
1325 void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,
1326                                            const MCSubtargetInfo &STI,
1327                                            raw_ostream &O) {
1328   auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1329   if (Imm == 0)
1330     return;
1331 
1332   O << " index_key:" << Imm;
1333 }
1334 
1335 void AMDGPUInstPrinter::printIndexKey32bit(const MCInst *MI, unsigned OpNo,
1336                                            const MCSubtargetInfo &STI,
1337                                            raw_ostream &O) {
1338   auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1339   if (Imm == 0)
1340     return;
1341 
1342   O << " index_key:" << Imm;
1343 }
1344 
1345 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1346                                         const MCSubtargetInfo &STI,
1347                                         raw_ostream &O) {
1348   unsigned Imm = MI->getOperand(OpNum).getImm();
1349   switch (Imm) {
1350   case 0:
1351     O << "p10";
1352     break;
1353   case 1:
1354     O << "p20";
1355     break;
1356   case 2:
1357     O << "p0";
1358     break;
1359   default:
1360     O << "invalid_param_" << Imm;
1361   }
1362 }
1363 
1364 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1365                                         const MCSubtargetInfo &STI,
1366                                         raw_ostream &O) {
1367   unsigned Attr = MI->getOperand(OpNum).getImm();
1368   O << "attr" << Attr;
1369 }
1370 
1371 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1372                                         const MCSubtargetInfo &STI,
1373                                         raw_ostream &O) {
1374   unsigned Chan = MI->getOperand(OpNum).getImm();
1375   O << '.' << "xyzw"[Chan & 0x3];
1376 }
1377 
1378 void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,
1379                                         const MCSubtargetInfo &STI,
1380                                         raw_ostream &O) {
1381   using namespace llvm::AMDGPU::VGPRIndexMode;
1382   unsigned Val = MI->getOperand(OpNo).getImm();
1383 
1384   if ((Val & ~ENABLE_MASK) != 0) {
1385     O << formatHex(static_cast<uint64_t>(Val));
1386   } else {
1387     O << "gpr_idx(";
1388     bool NeedComma = false;
1389     for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1390       if (Val & (1 << ModeId)) {
1391         if (NeedComma)
1392           O << ',';
1393         O << IdSymbolic[ModeId];
1394         NeedComma = true;
1395       }
1396     }
1397     O << ')';
1398   }
1399 }
1400 
1401 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1402                                         const MCSubtargetInfo &STI,
1403                                         raw_ostream &O) {
1404   printRegularOperand(MI, OpNo, STI, O);
1405   O  << ", ";
1406   printRegularOperand(MI, OpNo + 1, STI, O);
1407 }
1408 
1409 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1410                                    raw_ostream &O, StringRef Asm,
1411                                    StringRef Default) {
1412   const MCOperand &Op = MI->getOperand(OpNo);
1413   assert(Op.isImm());
1414   if (Op.getImm() == 1) {
1415     O << Asm;
1416   } else {
1417     O << Default;
1418   }
1419 }
1420 
1421 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1422                                    raw_ostream &O, char Asm) {
1423   const MCOperand &Op = MI->getOperand(OpNo);
1424   assert(Op.isImm());
1425   if (Op.getImm() == 1)
1426     O << Asm;
1427 }
1428 
1429 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1430                                     const MCSubtargetInfo &STI,
1431                                     raw_ostream &O) {
1432   int Imm = MI->getOperand(OpNo).getImm();
1433   if (Imm == SIOutMods::MUL2)
1434     O << " mul:2";
1435   else if (Imm == SIOutMods::MUL4)
1436     O << " mul:4";
1437   else if (Imm == SIOutMods::DIV2)
1438     O << " div:2";
1439 }
1440 
1441 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1442                                      const MCSubtargetInfo &STI,
1443                                      raw_ostream &O) {
1444   using namespace llvm::AMDGPU::SendMsg;
1445 
1446   const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1447 
1448   uint16_t MsgId;
1449   uint16_t OpId;
1450   uint16_t StreamId;
1451   decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
1452 
1453   StringRef MsgName = getMsgName(MsgId, STI);
1454 
1455   if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1456       isValidMsgStream(MsgId, OpId, StreamId, STI)) {
1457     O << "sendmsg(" << MsgName;
1458     if (msgRequiresOp(MsgId, STI)) {
1459       O << ", " << getMsgOpName(MsgId, OpId, STI);
1460       if (msgSupportsStream(MsgId, OpId, STI)) {
1461         O << ", " << StreamId;
1462       }
1463     }
1464     O << ')';
1465   } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1466     O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1467   } else {
1468     O << Imm16; // Unknown imm16 code.
1469   }
1470 }
1471 
1472 static void printSwizzleBitmask(const uint16_t AndMask,
1473                                 const uint16_t OrMask,
1474                                 const uint16_t XorMask,
1475                                 raw_ostream &O) {
1476   using namespace llvm::AMDGPU::Swizzle;
1477 
1478   uint16_t Probe0 = ((0            & AndMask) | OrMask) ^ XorMask;
1479   uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1480 
1481   O << "\"";
1482 
1483   for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1484     uint16_t p0 = Probe0 & Mask;
1485     uint16_t p1 = Probe1 & Mask;
1486 
1487     if (p0 == p1) {
1488       if (p0 == 0) {
1489         O << "0";
1490       } else {
1491         O << "1";
1492       }
1493     } else {
1494       if (p0 == 0) {
1495         O << "p";
1496       } else {
1497         O << "i";
1498       }
1499     }
1500   }
1501 
1502   O << "\"";
1503 }
1504 
1505 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1506                                      const MCSubtargetInfo &STI,
1507                                      raw_ostream &O) {
1508   using namespace llvm::AMDGPU::Swizzle;
1509 
1510   uint16_t Imm = MI->getOperand(OpNo).getImm();
1511   if (Imm == 0) {
1512     return;
1513   }
1514 
1515   O << " offset:";
1516 
1517   // Rotate and FFT modes
1518   if (Imm >= ROTATE_MODE_LO && AMDGPU::isGFX9Plus(STI)) {
1519     if (Imm >= FFT_MODE_LO) {
1520       O << "swizzle(" << IdSymbolic[ID_FFT] << ',' << (Imm & FFT_SWIZZLE_MASK)
1521         << ')';
1522     } else if (Imm >= ROTATE_MODE_LO) {
1523       O << "swizzle(" << IdSymbolic[ID_ROTATE] << ','
1524         << ((Imm >> ROTATE_DIR_SHIFT) & ROTATE_DIR_MASK) << ','
1525         << ((Imm >> ROTATE_SIZE_SHIFT) & ROTATE_SIZE_MASK) << ')';
1526     }
1527     return;
1528   }
1529 
1530   // Basic mode
1531   if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1532     O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1533     for (unsigned I = 0; I < LANE_NUM; ++I) {
1534       O << ",";
1535       O << formatDec(Imm & LANE_MASK);
1536       Imm >>= LANE_SHIFT;
1537     }
1538     O << ")";
1539 
1540   } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1541 
1542     uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1543     uint16_t OrMask  = (Imm >> BITMASK_OR_SHIFT)  & BITMASK_MASK;
1544     uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1545 
1546     if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
1547 
1548       O << "swizzle(" << IdSymbolic[ID_SWAP];
1549       O << ",";
1550       O << formatDec(XorMask);
1551       O << ")";
1552 
1553     } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
1554                isPowerOf2_64(XorMask + 1)) {
1555 
1556       O << "swizzle(" << IdSymbolic[ID_REVERSE];
1557       O << ",";
1558       O << formatDec(XorMask + 1);
1559       O << ")";
1560 
1561     } else {
1562 
1563       uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1564       if (GroupSize > 1 &&
1565           isPowerOf2_64(GroupSize) &&
1566           OrMask < GroupSize &&
1567           XorMask == 0) {
1568 
1569         O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1570         O << ",";
1571         O << formatDec(GroupSize);
1572         O << ",";
1573         O << formatDec(OrMask);
1574         O << ")";
1575 
1576       } else {
1577         O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1578         O << ",";
1579         printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1580         O << ")";
1581       }
1582     }
1583   } else {
1584     printU16ImmDecOperand(MI, OpNo, O);
1585   }
1586 }
1587 
1588 void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,
1589                                       const MCSubtargetInfo &STI,
1590                                       raw_ostream &O) {
1591   AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1592 
1593   unsigned SImm16 = MI->getOperand(OpNo).getImm();
1594   unsigned Vmcnt, Expcnt, Lgkmcnt;
1595   decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1596 
1597   bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1598   bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1599   bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1600   bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1601 
1602   bool NeedSpace = false;
1603 
1604   if (!IsDefaultVmcnt || PrintAll) {
1605     O << "vmcnt(" << Vmcnt << ')';
1606     NeedSpace = true;
1607   }
1608 
1609   if (!IsDefaultExpcnt || PrintAll) {
1610     if (NeedSpace)
1611       O << ' ';
1612     O << "expcnt(" << Expcnt << ')';
1613     NeedSpace = true;
1614   }
1615 
1616   if (!IsDefaultLgkmcnt || PrintAll) {
1617     if (NeedSpace)
1618       O << ' ';
1619     O << "lgkmcnt(" << Lgkmcnt << ')';
1620   }
1621 }
1622 
1623 void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
1624                                     const MCSubtargetInfo &STI,
1625                                     raw_ostream &O) {
1626   using namespace llvm::AMDGPU::DepCtr;
1627 
1628   uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
1629 
1630   bool HasNonDefaultVal = false;
1631   if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
1632     int Id = 0;
1633     StringRef Name;
1634     unsigned Val;
1635     bool IsDefault;
1636     bool NeedSpace = false;
1637     while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
1638       if (!IsDefault || !HasNonDefaultVal) {
1639         if (NeedSpace)
1640           O << ' ';
1641         O << Name << '(' << Val << ')';
1642         NeedSpace = true;
1643       }
1644     }
1645   } else {
1646     O << formatHex(Imm16);
1647   }
1648 }
1649 
1650 void AMDGPUInstPrinter::printSDelayALU(const MCInst *MI, unsigned OpNo,
1651                                        const MCSubtargetInfo &STI,
1652                                        raw_ostream &O) {
1653   const char *BadInstId = "/* invalid instid value */";
1654   static const std::array<const char *, 12> InstIds = {
1655       "NO_DEP",        "VALU_DEP_1",    "VALU_DEP_2",
1656       "VALU_DEP_3",    "VALU_DEP_4",    "TRANS32_DEP_1",
1657       "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1658       "SALU_CYCLE_1",  "SALU_CYCLE_2",  "SALU_CYCLE_3"};
1659 
1660   const char *BadInstSkip = "/* invalid instskip value */";
1661   static const std::array<const char *, 6> InstSkips = {
1662       "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1663 
1664   unsigned SImm16 = MI->getOperand(OpNo).getImm();
1665   const char *Prefix = "";
1666 
1667   unsigned Value = SImm16 & 0xF;
1668   if (Value) {
1669     const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1670     O << Prefix << "instid0(" << Name << ')';
1671     Prefix = " | ";
1672   }
1673 
1674   Value = (SImm16 >> 4) & 7;
1675   if (Value) {
1676     const char *Name =
1677         Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1678     O << Prefix << "instskip(" << Name << ')';
1679     Prefix = " | ";
1680   }
1681 
1682   Value = (SImm16 >> 7) & 0xF;
1683   if (Value) {
1684     const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1685     O << Prefix << "instid1(" << Name << ')';
1686     Prefix = " | ";
1687   }
1688 
1689   if (!*Prefix)
1690     O << "0";
1691 }
1692 
1693 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1694                                    const MCSubtargetInfo &STI, raw_ostream &O) {
1695   using namespace llvm::AMDGPU::Hwreg;
1696   unsigned Val = MI->getOperand(OpNo).getImm();
1697   auto [Id, Offset, Width] = HwregEncoding::decode(Val);
1698   StringRef HwRegName = getHwreg(Id, STI);
1699 
1700   O << "hwreg(";
1701   if (!HwRegName.empty()) {
1702     O << HwRegName;
1703   } else {
1704     O << Id;
1705   }
1706   if (Width != HwregSize::Default || Offset != HwregOffset::Default)
1707     O << ", " << Offset << ", " << Width;
1708   O << ')';
1709 }
1710 
1711 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1712                                     const MCSubtargetInfo &STI,
1713                                     raw_ostream &O) {
1714   uint16_t Imm = MI->getOperand(OpNo).getImm();
1715   if (Imm == 0) {
1716     return;
1717   }
1718 
1719   O << ' ' << formatDec(Imm);
1720 }
1721 
1722 void AMDGPUInstPrinter::printNamedInt(const MCInst *MI, unsigned OpNo,
1723                                       const MCSubtargetInfo &STI,
1724                                       raw_ostream &O, StringRef Prefix,
1725                                       bool PrintInHex, bool AlwaysPrint) {
1726   int64_t V = MI->getOperand(OpNo).getImm();
1727   if (AlwaysPrint || V != 0)
1728     O << ' ' << Prefix << ':' << (PrintInHex ? formatHex(V) : formatDec(V));
1729 }
1730 
1731 void AMDGPUInstPrinter::printBitOp3(const MCInst *MI, unsigned OpNo,
1732                                     const MCSubtargetInfo &STI,
1733                                     raw_ostream &O) {
1734   uint8_t Imm = MI->getOperand(OpNo).getImm();
1735   if (!Imm)
1736     return;
1737 
1738   O << " bitop3:";
1739   if (Imm <= 10)
1740     O << formatDec(Imm);
1741   else
1742     O << formatHex(static_cast<uint64_t>(Imm));
1743 }
1744 
1745 #include "AMDGPUGenAsmWriter.inc"
1746