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