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