AMDGPUInstPrinter.cpp revision 360784
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
26using namespace llvm;
27using namespace llvm::AMDGPU;
28
29void 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
37void 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
43void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
44                                          raw_ostream &O) {
45  O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
46}
47
48void 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
60void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
61                                             raw_ostream &O) {
62  O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
63}
64
65void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
66                                             raw_ostream &O) {
67  O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
68}
69
70void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
71                                              raw_ostream &O) {
72  O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
73}
74
75void 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
81void 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
88void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
89                                   raw_ostream &O) {
90  printNamedBit(MI, OpNo, O, "offen");
91}
92
93void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
94                                   raw_ostream &O) {
95  printNamedBit(MI, OpNo, O, "idxen");
96}
97
98void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
99                                    raw_ostream &O) {
100  printNamedBit(MI, OpNo, O, "addr64");
101}
102
103void 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
111void 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
121void 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
143void 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
152void 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
161void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
162                                        const MCSubtargetInfo &STI,
163                                        raw_ostream &O) {
164  printU32ImmOperand(MI, OpNo, STI, O);
165}
166
167void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
168                                        const MCSubtargetInfo &STI,
169                                        raw_ostream &O) {
170  printU32ImmOperand(MI, OpNo, STI, O);
171}
172
173void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
174                                               const MCSubtargetInfo &STI,
175                                               raw_ostream &O) {
176  printU32ImmOperand(MI, OpNo, STI, O);
177}
178
179void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
180                                 const MCSubtargetInfo &STI, raw_ostream &O) {
181  printNamedBit(MI, OpNo, O, "gds");
182}
183
184void 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
190void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
191                                 const MCSubtargetInfo &STI, raw_ostream &O) {
192  printNamedBit(MI, OpNo, O, "glc");
193}
194
195void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
196                                 const MCSubtargetInfo &STI, raw_ostream &O) {
197  printNamedBit(MI, OpNo, O, "slc");
198}
199
200void AMDGPUInstPrinter::printSWZ(const MCInst *MI, unsigned OpNo,
201                                 const MCSubtargetInfo &STI, raw_ostream &O) {
202}
203
204void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
205                                 const MCSubtargetInfo &STI, raw_ostream &O) {
206  printNamedBit(MI, OpNo, O, "tfe");
207}
208
209void 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
217void 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
229void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
230                                   const MCSubtargetInfo &STI, raw_ostream &O) {
231  printNamedBit(MI, OpNo, O, "unorm");
232}
233
234void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
235                                const MCSubtargetInfo &STI, raw_ostream &O) {
236  printNamedBit(MI, OpNo, O, "da");
237}
238
239void 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
247void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
248                                 const MCSubtargetInfo &STI, raw_ostream &O) {
249  printNamedBit(MI, OpNo, O, "lwe");
250}
251
252void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
253                                 const MCSubtargetInfo &STI, raw_ostream &O) {
254  printNamedBit(MI, OpNo, O, "d16");
255}
256
257void 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
264void 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
271void 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
284void 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
303void 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
339void 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
349void 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
381void 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
388void 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
422void 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
461void 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
471void 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
481void 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
491void 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
502void 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
621void 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
656void 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
682void 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
696void 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
781void 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
788void 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
795void 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
804void 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
814void 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
831void 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
838void 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
845void 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
852void 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
867template <unsigned N>
868void 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
891void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
892                                     const MCSubtargetInfo &STI,
893                                     raw_ostream &O) {
894  printExpSrcN<0>(MI, OpNo, STI, O);
895}
896
897void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
898                                     const MCSubtargetInfo &STI,
899                                     raw_ostream &O) {
900  printExpSrcN<1>(MI, OpNo, STI, O);
901}
902
903void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
904                                     const MCSubtargetInfo &STI,
905                                     raw_ostream &O) {
906  printExpSrcN<2>(MI, OpNo, STI, O);
907}
908
909void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
910                                     const MCSubtargetInfo &STI,
911                                     raw_ostream &O) {
912  printExpSrcN<3>(MI, OpNo, STI, O);
913}
914
915void 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
939static 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
954void 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
998void 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
1016void 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
1022void 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
1028void 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
1034void 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
1053void 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
1060void 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
1067void 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
1090void 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
1098void 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
1110void 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
1118void 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
1125void 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
1132void 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
1144void 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
1174static 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
1207void 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
1280void 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
1310void 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
1333void 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
1346void 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
1354void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1355                               raw_ostream &O) {
1356  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1357}
1358
1359void 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
1383void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1384                                 raw_ostream &O) {
1385  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1386}
1387
1388void 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
1403void 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
1415void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1416                                raw_ostream &O) {
1417  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1418}
1419
1420void 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
1433void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1434                               raw_ostream &O) {
1435  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1436}
1437
1438void 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
1454void 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
1461void 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
1496void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1497                               raw_ostream &O) {
1498  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1499}
1500
1501void 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
1531void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1532                                          raw_ostream &O) {
1533  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1534}
1535
1536void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1537                                      raw_ostream &O) {
1538  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1539}
1540
1541void 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