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