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