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