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