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