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