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