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_CNDMASK_B32_dpp_gfx10:
603  case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
604  case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
605  case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
606  case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
607  case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
608  case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
609  case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
610 
611  case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
612  case AMDGPU::V_CNDMASK_B32_e32_vi:
613  if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
614  AMDGPU::OpName::src1))
615  printDefaultVccOperand(OpNo, STI, O);
616  break;
617  }
618 }
619 
620 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
621  unsigned OpNo,
622  const MCSubtargetInfo &STI,
623  raw_ostream &O) {
624  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
625 
626  // Use 'neg(...)' instead of '-' to avoid ambiguity.
627  // This is important for integer literals because
628  // -1 is not the same value as neg(1).
629  bool NegMnemo = false;
630 
631  if (InputModifiers & SISrcMods::NEG) {
632  if (OpNo + 1 < MI->getNumOperands() &&
633  (InputModifiers & SISrcMods::ABS) == 0) {
634  const MCOperand &Op = MI->getOperand(OpNo + 1);
635  NegMnemo = Op.isImm() || Op.isFPImm();
636  }
637  if (NegMnemo) {
638  O << "neg(";
639  } else {
640  O << '-';
641  }
642  }
643 
644  if (InputModifiers & SISrcMods::ABS)
645  O << '|';
646  printOperand(MI, OpNo + 1, STI, O);
647  if (InputModifiers & SISrcMods::ABS)
648  O << '|';
649 
650  if (NegMnemo) {
651  O << ')';
652  }
653 }
654 
655 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
656  unsigned OpNo,
657  const MCSubtargetInfo &STI,
658  raw_ostream &O) {
659  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
660  if (InputModifiers & SISrcMods::SEXT)
661  O << "sext(";
662  printOperand(MI, OpNo + 1, STI, O);
663  if (InputModifiers & SISrcMods::SEXT)
664  O << ')';
665 
666  // Print default vcc/vcc_lo operand of VOP2b.
667  switch (MI->getOpcode()) {
668  default: break;
669 
670  case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
671  case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
672  case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
673  case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
674  if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
675  AMDGPU::OpName::src1))
676  printDefaultVccOperand(OpNo, STI, O);
677  break;
678  }
679 }
680 
681 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
682  const MCSubtargetInfo &STI,
683  raw_ostream &O) {
684  if (!AMDGPU::isGFX10(STI))
685  llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
686 
687  unsigned Imm = MI->getOperand(OpNo).getImm();
688  O << " dpp8:[" << formatDec(Imm & 0x7);
689  for (size_t i = 1; i < 8; ++i) {
690  O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
691  }
692  O << ']';
693 }
694 
695 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
696  const MCSubtargetInfo &STI,
697  raw_ostream &O) {
698  using namespace AMDGPU::DPP;
699 
700  unsigned Imm = MI->getOperand(OpNo).getImm();
701  if (Imm <= DppCtrl::QUAD_PERM_LAST) {
702  O << " quad_perm:[";
703  O << formatDec(Imm & 0x3) << ',';
704  O << formatDec((Imm & 0xc) >> 2) << ',';
705  O << formatDec((Imm & 0x30) >> 4) << ',';
706  O << formatDec((Imm & 0xc0) >> 6) << ']';
707  } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
708  (Imm <= DppCtrl::ROW_SHL_LAST)) {
709  O << " row_shl:";
710  printU4ImmDecOperand(MI, OpNo, O);
711  } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
712  (Imm <= DppCtrl::ROW_SHR_LAST)) {
713  O << " row_shr:";
714  printU4ImmDecOperand(MI, OpNo, O);
715  } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
716  (Imm <= DppCtrl::ROW_ROR_LAST)) {
717  O << " row_ror:";
718  printU4ImmDecOperand(MI, OpNo, O);
719  } else if (Imm == DppCtrl::WAVE_SHL1) {
720  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
721  O << " /* wave_shl is not supported starting from GFX10 */";
722  return;
723  }
724  O << " wave_shl:1";
725  } else if (Imm == DppCtrl::WAVE_ROL1) {
726  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
727  O << " /* wave_rol is not supported starting from GFX10 */";
728  return;
729  }
730  O << " wave_rol:1";
731  } else if (Imm == DppCtrl::WAVE_SHR1) {
732  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
733  O << " /* wave_shr is not supported starting from GFX10 */";
734  return;
735  }
736  O << " wave_shr:1";
737  } else if (Imm == DppCtrl::WAVE_ROR1) {
738  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
739  O << " /* wave_ror is not supported starting from GFX10 */";
740  return;
741  }
742  O << " wave_ror:1";
743  } else if (Imm == DppCtrl::ROW_MIRROR) {
744  O << " row_mirror";
745  } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
746  O << " row_half_mirror";
747  } else if (Imm == DppCtrl::BCAST15) {
748  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
749  O << " /* row_bcast is not supported starting from GFX10 */";
750  return;
751  }
752  O << " row_bcast:15";
753  } else if (Imm == DppCtrl::BCAST31) {
754  if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) {
755  O << " /* row_bcast is not supported starting from GFX10 */";
756  return;
757  }
758  O << " row_bcast:31";
759  } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
760  (Imm <= DppCtrl::ROW_SHARE_LAST)) {
761  if (!AMDGPU::isGFX10(STI)) {
762  O << " /* row_share is not supported on ASICs earlier than GFX10 */";
763  return;
764  }
765  O << " row_share:";
766  printU4ImmDecOperand(MI, OpNo, O);
767  } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
768  (Imm <= DppCtrl::ROW_XMASK_LAST)) {
769  if (!AMDGPU::isGFX10(STI)) {
770  O << " /* row_xmask is not supported on ASICs earlier than GFX10 */";
771  return;
772  }
773  O << "row_xmask:";
774  printU4ImmDecOperand(MI, OpNo, O);
775  } else {
776  O << " /* Invalid dpp_ctrl value */";
777  }
778 }
779 
780 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
781  const MCSubtargetInfo &STI,
782  raw_ostream &O) {
783  O << " row_mask:";
784  printU4ImmOperand(MI, OpNo, STI, O);
785 }
786 
787 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
788  const MCSubtargetInfo &STI,
789  raw_ostream &O) {
790  O << " bank_mask:";
791  printU4ImmOperand(MI, OpNo, STI, O);
792 }
793 
794 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
795  const MCSubtargetInfo &STI,
796  raw_ostream &O) {
797  unsigned Imm = MI->getOperand(OpNo).getImm();
798  if (Imm) {
799  O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
800  }
801 }
802 
803 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo,
804  const MCSubtargetInfo &STI,
805  raw_ostream &O) {
806  using namespace llvm::AMDGPU::DPP;
807  unsigned Imm = MI->getOperand(OpNo).getImm();
808  if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
809  O << " fi:1";
810  }
811 }
812 
813 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
814  raw_ostream &O) {
815  using namespace llvm::AMDGPU::SDWA;
816 
817  unsigned Imm = MI->getOperand(OpNo).getImm();
818  switch (Imm) {
819  case SdwaSel::BYTE_0: O << "BYTE_0"; break;
820  case SdwaSel::BYTE_1: O << "BYTE_1"; break;
821  case SdwaSel::BYTE_2: O << "BYTE_2"; break;
822  case SdwaSel::BYTE_3: O << "BYTE_3"; break;
823  case SdwaSel::WORD_0: O << "WORD_0"; break;
824  case SdwaSel::WORD_1: O << "WORD_1"; break;
825  case SdwaSel::DWORD: O << "DWORD"; break;
826  default: llvm_unreachable("Invalid SDWA data select operand");
827  }
828 }
829 
830 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
831  const MCSubtargetInfo &STI,
832  raw_ostream &O) {
833  O << "dst_sel:";
834  printSDWASel(MI, OpNo, O);
835 }
836 
837 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
838  const MCSubtargetInfo &STI,
839  raw_ostream &O) {
840  O << "src0_sel:";
841  printSDWASel(MI, OpNo, O);
842 }
843 
844 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
845  const MCSubtargetInfo &STI,
846  raw_ostream &O) {
847  O << "src1_sel:";
848  printSDWASel(MI, OpNo, O);
849 }
850 
851 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
852  const MCSubtargetInfo &STI,
853  raw_ostream &O) {
854  using namespace llvm::AMDGPU::SDWA;
855 
856  O << "dst_unused:";
857  unsigned Imm = MI->getOperand(OpNo).getImm();
858  switch (Imm) {
859  case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
860  case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
861  case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
862  default: llvm_unreachable("Invalid SDWA dest_unused operand");
863  }
864 }
865 
866 template <unsigned N>
867 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
868  const MCSubtargetInfo &STI,
869  raw_ostream &O) {
870  unsigned Opc = MI->getOpcode();
871  int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
872  unsigned En = MI->getOperand(EnIdx).getImm();
873 
874  int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
875 
876  // If compr is set, print as src0, src0, src1, src1
877  if (MI->getOperand(ComprIdx).getImm()) {
878  if (N == 1 || N == 2)
879  --OpNo;
880  else if (N == 3)
881  OpNo -= 2;
882  }
883 
884  if (En & (1 << N))
885  printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
886  else
887  O << "off";
888 }
889 
890 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
891  const MCSubtargetInfo &STI,
892  raw_ostream &O) {
893  printExpSrcN<0>(MI, OpNo, STI, O);
894 }
895 
896 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
897  const MCSubtargetInfo &STI,
898  raw_ostream &O) {
899  printExpSrcN<1>(MI, OpNo, STI, O);
900 }
901 
902 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
903  const MCSubtargetInfo &STI,
904  raw_ostream &O) {
905  printExpSrcN<2>(MI, OpNo, STI, O);
906 }
907 
908 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
909  const MCSubtargetInfo &STI,
910  raw_ostream &O) {
911  printExpSrcN<3>(MI, OpNo, STI, O);
912 }
913 
914 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
915  const MCSubtargetInfo &STI,
916  raw_ostream &O) {
917  // This is really a 6 bit field.
918  uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
919 
920  if (Tgt <= 7)
921  O << " mrt" << Tgt;
922  else if (Tgt == 8)
923  O << " mrtz";
924  else if (Tgt == 9)
925  O << " null";
926  else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI)))
927  O << " pos" << Tgt - 12;
928  else if (AMDGPU::isGFX10(STI) && Tgt == 20)
929  O << " prim";
930  else if (Tgt >= 32 && Tgt <= 63)
931  O << " param" << Tgt - 32;
932  else {
933  // Reserved values 10, 11
934  O << " invalid_target_" << Tgt;
935  }
936 }
937 
938 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
939  bool IsPacked, bool HasDstSel) {
940  int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
941 
942  for (int I = 0; I < NumOps; ++I) {
943  if (!!(Ops[I] & Mod) != DefaultValue)
944  return false;
945  }
946 
947  if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
948  return false;
949 
950  return true;
951 }
952 
953 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
954  StringRef Name,
955  unsigned Mod,
956  raw_ostream &O) {
957  unsigned Opc = MI->getOpcode();
958  int NumOps = 0;
959  int Ops[3];
960 
961  for (int OpName : { AMDGPU::OpName::src0_modifiers,
962  AMDGPU::OpName::src1_modifiers,
963  AMDGPU::OpName::src2_modifiers }) {
964  int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
965  if (Idx == -1)
966  break;
967 
968  Ops[NumOps++] = MI->getOperand(Idx).getImm();
969  }
970 
971  const bool HasDstSel =
972  NumOps > 0 &&
973  Mod == SISrcMods::OP_SEL_0 &&
974  MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
975 
976  const bool IsPacked =
977  MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
978 
979  if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
980  return;
981 
982  O << Name;
983  for (int I = 0; I < NumOps; ++I) {
984  if (I != 0)
985  O << ',';
986 
987  O << !!(Ops[I] & Mod);
988  }
989 
990  if (HasDstSel) {
991  O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
992  }
993 
994  O << ']';
995 }
996 
997 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
998  const MCSubtargetInfo &STI,
999  raw_ostream &O) {
1000  unsigned Opc = MI->getOpcode();
1001  if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
1002  Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
1003  auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1004  auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
1005  unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
1006  unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
1007  if (FI || BC)
1008  O << " op_sel:[" << FI << ',' << BC << ']';
1009  return;
1010  }
1011 
1012  printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1013 }
1014 
1015 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1016  const MCSubtargetInfo &STI,
1017  raw_ostream &O) {
1018  printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1019 }
1020 
1021 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1022  const MCSubtargetInfo &STI,
1023  raw_ostream &O) {
1024  printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1025 }
1026 
1027 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1028  const MCSubtargetInfo &STI,
1029  raw_ostream &O) {
1030  printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1031 }
1032 
1033 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1034  const MCSubtargetInfo &STI,
1035  raw_ostream &O) {
1036  unsigned Imm = MI->getOperand(OpNum).getImm();
1037  switch (Imm) {
1038  case 0:
1039  O << "p10";
1040  break;
1041  case 1:
1042  O << "p20";
1043  break;
1044  case 2:
1045  O << "p0";
1046  break;
1047  default:
1048  O << "invalid_param_" << Imm;
1049  }
1050 }
1051 
1052 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1053  const MCSubtargetInfo &STI,
1054  raw_ostream &O) {
1055  unsigned Attr = MI->getOperand(OpNum).getImm();
1056  O << "attr" << Attr;
1057 }
1058 
1059 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1060  const MCSubtargetInfo &STI,
1061  raw_ostream &O) {
1062  unsigned Chan = MI->getOperand(OpNum).getImm();
1063  O << '.' << "xyzw"[Chan & 0x3];
1064 }
1065 
1066 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1067  const MCSubtargetInfo &STI,
1068  raw_ostream &O) {
1069  using namespace llvm::AMDGPU::VGPRIndexMode;
1070  unsigned Val = MI->getOperand(OpNo).getImm();
1071 
1072  if ((Val & ~ENABLE_MASK) != 0) {
1073  O << " " << formatHex(static_cast<uint64_t>(Val));
1074  } else {
1075  O << " gpr_idx(";
1076  bool NeedComma = false;
1077  for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1078  if (Val & (1 << ModeId)) {
1079  if (NeedComma)
1080  O << ',';
1081  O << IdSymbolic[ModeId];
1082  NeedComma = true;
1083  }
1084  }
1085  O << ')';
1086  }
1087 }
1088 
1089 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1090  const MCSubtargetInfo &STI,
1091  raw_ostream &O) {
1092  printOperand(MI, OpNo, STI, O);
1093  O << ", ";
1094  printOperand(MI, OpNo + 1, STI, O);
1095 }
1096 
1097 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1099  StringRef Default) {
1100  const MCOperand &Op = MI->getOperand(OpNo);
1101  assert(Op.isImm());
1102  if (Op.getImm() == 1) {
1103  O << Asm;
1104  } else {
1105  O << Default;
1106  }
1107 }
1108 
1109 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1110  raw_ostream &O, char Asm) {
1111  const MCOperand &Op = MI->getOperand(OpNo);
1112  assert(Op.isImm());
1113  if (Op.getImm() == 1)
1114  O << Asm;
1115 }
1116 
1117 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1118  const MCSubtargetInfo &STI,
1119  raw_ostream &O) {
1120  if (MI->getOperand(OpNo).getImm())
1121  O << " high";
1122 }
1123 
1124 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1125  const MCSubtargetInfo &STI,
1126  raw_ostream &O) {
1127  if (MI->getOperand(OpNo).getImm())
1128  O << " clamp";
1129 }
1130 
1131 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1132  const MCSubtargetInfo &STI,
1133  raw_ostream &O) {
1134  int Imm = MI->getOperand(OpNo).getImm();
1135  if (Imm == SIOutMods::MUL2)
1136  O << " mul:2";
1137  else if (Imm == SIOutMods::MUL4)
1138  O << " mul:4";
1139  else if (Imm == SIOutMods::DIV2)
1140  O << " div:2";
1141 }
1142 
1143 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1144  const MCSubtargetInfo &STI,
1145  raw_ostream &O) {
1146  using namespace llvm::AMDGPU::SendMsg;
1147 
1148  const unsigned Imm16 = MI->getOperand(OpNo).getImm();
1149 
1150  uint16_t MsgId;
1151  uint16_t OpId;
1152  uint16_t StreamId;
1153  decodeMsg(Imm16, MsgId, OpId, StreamId);
1154 
1155  if (isValidMsgId(MsgId, STI) &&
1156  isValidMsgOp(MsgId, OpId) &&
1157  isValidMsgStream(MsgId, OpId, StreamId)) {
1158  O << "sendmsg(" << getMsgName(MsgId);
1159  if (msgRequiresOp(MsgId)) {
1160  O << ", " << getMsgOpName(MsgId, OpId);
1161  if (msgSupportsStream(MsgId, OpId)) {
1162  O << ", " << StreamId;
1163  }
1164  }
1165  O << ')';
1166  } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
1167  O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
1168  } else {
1169  O << Imm16; // Unknown imm16 code.
1170  }
1171 }
1172 
1173 static void printSwizzleBitmask(const uint16_t AndMask,
1174  const uint16_t OrMask,
1175  const uint16_t XorMask,
1176  raw_ostream &O) {
1177  using namespace llvm::AMDGPU::Swizzle;
1178 
1179  uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1180  uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1181 
1182  O << "\"";
1183 
1184  for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1185  uint16_t p0 = Probe0 & Mask;
1186  uint16_t p1 = Probe1 & Mask;
1187 
1188  if (p0 == p1) {
1189  if (p0 == 0) {
1190  O << "0";
1191  } else {
1192  O << "1";
1193  }
1194  } else {
1195  if (p0 == 0) {
1196  O << "p";
1197  } else {
1198  O << "i";
1199  }
1200  }
1201  }
1202 
1203  O << "\"";
1204 }
1205 
1206 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1207  const MCSubtargetInfo &STI,
1208  raw_ostream &O) {
1209  using namespace llvm::AMDGPU::Swizzle;
1210 
1211  uint16_t Imm = MI->getOperand(OpNo).getImm();
1212  if (Imm == 0) {
1213  return;
1214  }
1215 
1216  O << " offset:";
1217 
1218  if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1219 
1220  O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1221  for (unsigned I = 0; I < LANE_NUM; ++I) {
1222  O << ",";
1223  O << formatDec(Imm & LANE_MASK);
1224  Imm >>= LANE_SHIFT;
1225  }
1226  O << ")";
1227 
1228  } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1229 
1230  uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1231  uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1232  uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1233 
1234  if (AndMask == BITMASK_MAX &&
1235  OrMask == 0 &&
1236  countPopulation(XorMask) == 1) {
1237 
1238  O << "swizzle(" << IdSymbolic[ID_SWAP];
1239  O << ",";
1240  O << formatDec(XorMask);
1241  O << ")";
1242 
1243  } else if (AndMask == BITMASK_MAX &&
1244  OrMask == 0 && XorMask > 0 &&
1245  isPowerOf2_64(XorMask + 1)) {
1246 
1247  O << "swizzle(" << IdSymbolic[ID_REVERSE];
1248  O << ",";
1249  O << formatDec(XorMask + 1);
1250  O << ")";
1251 
1252  } else {
1253 
1254  uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1255  if (GroupSize > 1 &&
1256  isPowerOf2_64(GroupSize) &&
1257  OrMask < GroupSize &&
1258  XorMask == 0) {
1259 
1260  O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1261  O << ",";
1262  O << formatDec(GroupSize);
1263  O << ",";
1264  O << formatDec(OrMask);
1265  O << ")";
1266 
1267  } else {
1268  O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1269  O << ",";
1270  printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1271  O << ")";
1272  }
1273  }
1274  } else {
1275  printU16ImmDecOperand(MI, OpNo, O);
1276  }
1277 }
1278 
1279 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1280  const MCSubtargetInfo &STI,
1281  raw_ostream &O) {
1283 
1284  unsigned SImm16 = MI->getOperand(OpNo).getImm();
1285  unsigned Vmcnt, Expcnt, Lgkmcnt;
1286  decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1287 
1288  bool NeedSpace = false;
1289 
1290  if (Vmcnt != getVmcntBitMask(ISA)) {
1291  O << "vmcnt(" << Vmcnt << ')';
1292  NeedSpace = true;
1293  }
1294 
1295  if (Expcnt != getExpcntBitMask(ISA)) {
1296  if (NeedSpace)
1297  O << ' ';
1298  O << "expcnt(" << Expcnt << ')';
1299  NeedSpace = true;
1300  }
1301 
1302  if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1303  if (NeedSpace)
1304  O << ' ';
1305  O << "lgkmcnt(" << Lgkmcnt << ')';
1306  }
1307 }
1308 
1309 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1310  const MCSubtargetInfo &STI, raw_ostream &O) {
1311  unsigned Id;
1312  unsigned Offset;
1313  unsigned Width;
1314 
1315  using namespace llvm::AMDGPU::Hwreg;
1316  unsigned Val = MI->getOperand(OpNo).getImm();
1317  decodeHwreg(Val, Id, Offset, Width);
1318  StringRef HwRegName = getHwreg(Id, STI);
1319 
1320  O << "hwreg(";
1321  if (!HwRegName.empty()) {
1322  O << HwRegName;
1323  } else {
1324  O << Id;
1325  }
1326  if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1327  O << ", " << Offset << ", " << Width;
1328  }
1329  O << ')';
1330 }
1331 
1332 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1333  const MCSubtargetInfo &STI,
1334  raw_ostream &O) {
1335  uint16_t Imm = MI->getOperand(OpNo).getImm();
1336  if (Imm == 0) {
1337  return;
1338  }
1339 
1340  O << ' ' << formatDec(Imm);
1341 }
1342 
1343 #include "AMDGPUGenAsmWriter.inc"
1344 
1346  StringRef Annot, const MCSubtargetInfo &STI) {
1347  O.flush();
1348  printInstruction(MI, O);
1349  printAnnotation(O, Annot);
1350 }
1351 
1352 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1353  raw_ostream &O) {
1354  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1355 }
1356 
1357 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1358  raw_ostream &O) {
1359  int BankSwizzle = MI->getOperand(OpNo).getImm();
1360  switch (BankSwizzle) {
1361  case 1:
1362  O << "BS:VEC_021/SCL_122";
1363  break;
1364  case 2:
1365  O << "BS:VEC_120/SCL_212";
1366  break;
1367  case 3:
1368  O << "BS:VEC_102/SCL_221";
1369  break;
1370  case 4:
1371  O << "BS:VEC_201";
1372  break;
1373  case 5:
1374  O << "BS:VEC_210";
1375  break;
1376  default:
1377  break;
1378  }
1379 }
1380 
1381 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1382  raw_ostream &O) {
1383  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1384 }
1385 
1386 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1387  raw_ostream &O) {
1388  unsigned CT = MI->getOperand(OpNo).getImm();
1389  switch (CT) {
1390  case 0:
1391  O << 'U';
1392  break;
1393  case 1:
1394  O << 'N';
1395  break;
1396  default:
1397  break;
1398  }
1399 }
1400 
1401 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1402  raw_ostream &O) {
1403  int KCacheMode = MI->getOperand(OpNo).getImm();
1404  if (KCacheMode > 0) {
1405  int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1406  O << "CB" << KCacheBank << ':';
1407  int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1408  int LineSize = (KCacheMode == 1) ? 16 : 32;
1409  O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1410  }
1411 }
1412 
1413 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1414  raw_ostream &O) {
1415  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1416 }
1417 
1418 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1419  raw_ostream &O) {
1420  const MCOperand &Op = MI->getOperand(OpNo);
1421  assert(Op.isImm() || Op.isExpr());
1422  if (Op.isImm()) {
1423  int64_t Imm = Op.getImm();
1424  O << Imm << '(' << BitsToFloat(Imm) << ')';
1425  }
1426  if (Op.isExpr()) {
1427  Op.getExpr()->print(O << '@', &MAI);
1428  }
1429 }
1430 
1431 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1432  raw_ostream &O) {
1433  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1434 }
1435 
1436 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1437  raw_ostream &O) {
1438  switch (MI->getOperand(OpNo).getImm()) {
1439  default: break;
1440  case 1:
1441  O << " * 2.0";
1442  break;
1443  case 2:
1444  O << " * 4.0";
1445  break;
1446  case 3:
1447  O << " / 2.0";
1448  break;
1449  }
1450 }
1451 
1452 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1453  raw_ostream &O) {
1454  printOperand(MI, OpNo, O);
1455  O << ", ";
1456  printOperand(MI, OpNo + 1, O);
1457 }
1458 
1459 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1460  raw_ostream &O) {
1461  if (OpNo >= MI->getNumOperands()) {
1462  O << "/*Missing OP" << OpNo << "*/";
1463  return;
1464  }
1465 
1466  const MCOperand &Op = MI->getOperand(OpNo);
1467  if (Op.isReg()) {
1468  switch (Op.getReg()) {
1469  // This is the default predicate state, so we don't need to print it.
1470  case R600::PRED_SEL_OFF:
1471  break;
1472 
1473  default:
1474  O << getRegisterName(Op.getReg());
1475  break;
1476  }
1477  } else if (Op.isImm()) {
1478  O << Op.getImm();
1479  } else if (Op.isFPImm()) {
1480  // We special case 0.0 because otherwise it will be printed as an integer.
1481  if (Op.getFPImm() == 0.0)
1482  O << "0.0";
1483  else {
1484  O << Op.getFPImm();
1485  }
1486  } else if (Op.isExpr()) {
1487  const MCExpr *Exp = Op.getExpr();
1488  Exp->print(O, &MAI);
1489  } else {
1490  O << "/*INV_OP*/";
1491  }
1492 }
1493 
1494 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1495  raw_ostream &O) {
1496  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1497 }
1498 
1499 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1500  raw_ostream &O) {
1501  unsigned Sel = MI->getOperand(OpNo).getImm();
1502  switch (Sel) {
1503  case 0:
1504  O << 'X';
1505  break;
1506  case 1:
1507  O << 'Y';
1508  break;
1509  case 2:
1510  O << 'Z';
1511  break;
1512  case 3:
1513  O << 'W';
1514  break;
1515  case 4:
1516  O << '0';
1517  break;
1518  case 5:
1519  O << '1';
1520  break;
1521  case 7:
1522  O << '_';
1523  break;
1524  default:
1525  break;
1526  }
1527 }
1528 
1529 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1530  raw_ostream &O) {
1531  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1532 }
1533 
1534 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1535  raw_ostream &O) {
1536  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1537 }
1538 
1539 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1540  raw_ostream &O) {
1541  const MCOperand &Op = MI->getOperand(OpNo);
1542  if (Op.getImm() == 0) {
1543  O << " (MASKED)";
1544  }
1545 }
1546 
1547 #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...