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