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