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::LDS_DIRECT:
272  O << "src_lds_direct";
273  return;
274  case AMDGPU::VCC_LO:
275  O << "vcc_lo";
276  return;
277  case AMDGPU::VCC_HI:
278  O << "vcc_hi";
279  return;
280  case AMDGPU::TBA_LO:
281  O << "tba_lo";
282  return;
283  case AMDGPU::TBA_HI:
284  O << "tba_hi";
285  return;
286  case AMDGPU::TMA_LO:
287  O << "tma_lo";
288  return;
289  case AMDGPU::TMA_HI:
290  O << "tma_hi";
291  return;
292  case AMDGPU::EXEC_LO:
293  O << "exec_lo";
294  return;
295  case AMDGPU::EXEC_HI:
296  O << "exec_hi";
297  return;
298  case AMDGPU::FLAT_SCR_LO:
299  O << "flat_scratch_lo";
300  return;
301  case AMDGPU::FLAT_SCR_HI:
302  O << "flat_scratch_hi";
303  return;
304  case AMDGPU::XNACK_MASK_LO:
305  O << "xnack_mask_lo";
306  return;
307  case AMDGPU::XNACK_MASK_HI:
308  O << "xnack_mask_hi";
309  return;
310  case AMDGPU::FP_REG:
311  case AMDGPU::SP_REG:
312  case AMDGPU::SCRATCH_WAVE_OFFSET_REG:
313  case AMDGPU::PRIVATE_RSRC_REG:
314  llvm_unreachable("pseudo-register should not ever be emitted");
315  default:
316  break;
317  }
318 
319  // The low 8 bits of the encoding value is the register index, for both VGPRs
320  // and SGPRs.
321  unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1);
322 
323  unsigned NumRegs;
324  if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) {
325  O << 'v';
326  NumRegs = 1;
327  } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) {
328  O << 's';
329  NumRegs = 1;
330  } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) {
331  O <<'v';
332  NumRegs = 2;
333  } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) {
334  O << 's';
335  NumRegs = 2;
336  } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) {
337  O << 'v';
338  NumRegs = 4;
339  } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) {
340  O << 's';
341  NumRegs = 4;
342  } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) {
343  O << 'v';
344  NumRegs = 3;
345  } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) {
346  O << 'v';
347  NumRegs = 8;
348  } else if (MRI.getRegClass(AMDGPU::SGPR_256RegClassID).contains(RegNo)) {
349  O << 's';
350  NumRegs = 8;
351  } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) {
352  O << 'v';
353  NumRegs = 16;
354  } else if (MRI.getRegClass(AMDGPU::SGPR_512RegClassID).contains(RegNo)) {
355  O << 's';
356  NumRegs = 16;
357  } else {
358  O << getRegisterName(RegNo);
359  return;
360  }
361 
362  if (NumRegs == 1) {
363  O << RegIdx;
364  return;
365  }
366 
367  O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
368 }
369 
370 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
371  const MCSubtargetInfo &STI, raw_ostream &O) {
372  if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
373  O << "_e64 ";
374  else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
375  O << "_dpp ";
376  else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
377  O << "_sdwa ";
378  else
379  O << "_e32 ";
380 
381  printOperand(MI, OpNo, STI, O);
382 }
383 
384 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
385  const MCSubtargetInfo &STI, raw_ostream &O) {
386  if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
387  O << " ";
388  else
389  O << "_e32 ";
390 
391  printOperand(MI, OpNo, STI, O);
392 }
393 
394 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
395  const MCSubtargetInfo &STI,
396  raw_ostream &O) {
397  int16_t SImm = static_cast<int16_t>(Imm);
398  if (SImm >= -16 && SImm <= 64) {
399  O << SImm;
400  return;
401  }
402 
403  if (Imm == 0x3C00)
404  O<< "1.0";
405  else if (Imm == 0xBC00)
406  O<< "-1.0";
407  else if (Imm == 0x3800)
408  O<< "0.5";
409  else if (Imm == 0xB800)
410  O<< "-0.5";
411  else if (Imm == 0x4000)
412  O<< "2.0";
413  else if (Imm == 0xC000)
414  O<< "-2.0";
415  else if (Imm == 0x4400)
416  O<< "4.0";
417  else if (Imm == 0xC400)
418  O<< "-4.0";
419  else if (Imm == 0x3118) {
420  assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
421  O << "0.15915494";
422  } else
423  O << formatHex(static_cast<uint64_t>(Imm));
424 }
425 
426 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
427  const MCSubtargetInfo &STI,
428  raw_ostream &O) {
429  uint16_t Lo16 = static_cast<uint16_t>(Imm);
430  printImmediate16(Lo16, STI, O);
431 }
432 
433 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
434  const MCSubtargetInfo &STI,
435  raw_ostream &O) {
436  int32_t SImm = static_cast<int32_t>(Imm);
437  if (SImm >= -16 && SImm <= 64) {
438  O << SImm;
439  return;
440  }
441 
442  if (Imm == FloatToBits(0.0f))
443  O << "0.0";
444  else if (Imm == FloatToBits(1.0f))
445  O << "1.0";
446  else if (Imm == FloatToBits(-1.0f))
447  O << "-1.0";
448  else if (Imm == FloatToBits(0.5f))
449  O << "0.5";
450  else if (Imm == FloatToBits(-0.5f))
451  O << "-0.5";
452  else if (Imm == FloatToBits(2.0f))
453  O << "2.0";
454  else if (Imm == FloatToBits(-2.0f))
455  O << "-2.0";
456  else if (Imm == FloatToBits(4.0f))
457  O << "4.0";
458  else if (Imm == FloatToBits(-4.0f))
459  O << "-4.0";
460  else if (Imm == 0x3e22f983 &&
461  STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
462  O << "0.15915494";
463  else
464  O << formatHex(static_cast<uint64_t>(Imm));
465 }
466 
467 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
468  const MCSubtargetInfo &STI,
469  raw_ostream &O) {
470  int64_t SImm = static_cast<int64_t>(Imm);
471  if (SImm >= -16 && SImm <= 64) {
472  O << SImm;
473  return;
474  }
475 
476  if (Imm == DoubleToBits(0.0))
477  O << "0.0";
478  else if (Imm == DoubleToBits(1.0))
479  O << "1.0";
480  else if (Imm == DoubleToBits(-1.0))
481  O << "-1.0";
482  else if (Imm == DoubleToBits(0.5))
483  O << "0.5";
484  else if (Imm == DoubleToBits(-0.5))
485  O << "-0.5";
486  else if (Imm == DoubleToBits(2.0))
487  O << "2.0";
488  else if (Imm == DoubleToBits(-2.0))
489  O << "-2.0";
490  else if (Imm == DoubleToBits(4.0))
491  O << "4.0";
492  else if (Imm == DoubleToBits(-4.0))
493  O << "-4.0";
494  else if (Imm == 0x3fc45f306dc9c882 &&
495  STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
496  O << "0.15915494309189532";
497  else {
498  assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
499 
500  // In rare situations, we will have a 32-bit literal in a 64-bit
501  // operand. This is technically allowed for the encoding of s_mov_b64.
502  O << formatHex(static_cast<uint64_t>(Imm));
503  }
504 }
505 
506 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
507  const MCSubtargetInfo &STI,
508  raw_ostream &O) {
509  if (OpNo >= MI->getNumOperands()) {
510  O << "/*Missing OP" << OpNo << "*/";
511  return;
512  }
513 
514  const MCOperand &Op = MI->getOperand(OpNo);
515  if (Op.isReg()) {
516  printRegOperand(Op.getReg(), O, MRI);
517  } else if (Op.isImm()) {
518  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
519  switch (Desc.OpInfo[OpNo].OperandType) {
525  printImmediate32(Op.getImm(), STI, O);
526  break;
531  printImmediate64(Op.getImm(), STI, O);
532  break;
537  printImmediate16(Op.getImm(), STI, O);
538  break;
541  printImmediateV216(Op.getImm(), STI, O);
542  break;
544  case MCOI::OPERAND_PCREL:
545  O << formatDec(Op.getImm());
546  break;
548  // FIXME: This should be removed and handled somewhere else. Seems to come
549  // from a disassembler bug.
550  O << "/*invalid immediate*/";
551  break;
552  default:
553  // We hit this for the immediate instruction bits that don't yet have a
554  // custom printer.
555  llvm_unreachable("unexpected immediate operand type");
556  }
557  } else if (Op.isFPImm()) {
558  // We special case 0.0 because otherwise it will be printed as an integer.
559  if (Op.getFPImm() == 0.0)
560  O << "0.0";
561  else {
562  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
563  int RCID = Desc.OpInfo[OpNo].RegClass;
564  unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
565  if (RCBits == 32)
566  printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
567  else if (RCBits == 64)
568  printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
569  else
570  llvm_unreachable("Invalid register class size");
571  }
572  } else if (Op.isExpr()) {
573  const MCExpr *Exp = Op.getExpr();
574  Exp->print(O, &MAI);
575  } else {
576  O << "/*INV_OP*/";
577  }
578 }
579 
580 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
581  unsigned OpNo,
582  const MCSubtargetInfo &STI,
583  raw_ostream &O) {
584  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
585 
586  // Use 'neg(...)' instead of '-' to avoid ambiguity.
587  // This is important for integer literals because
588  // -1 is not the same value as neg(1).
589  bool NegMnemo = false;
590 
591  if (InputModifiers & SISrcMods::NEG) {
592  if (OpNo + 1 < MI->getNumOperands() &&
593  (InputModifiers & SISrcMods::ABS) == 0) {
594  const MCOperand &Op = MI->getOperand(OpNo + 1);
595  NegMnemo = Op.isImm() || Op.isFPImm();
596  }
597  if (NegMnemo) {
598  O << "neg(";
599  } else {
600  O << '-';
601  }
602  }
603 
604  if (InputModifiers & SISrcMods::ABS)
605  O << '|';
606  printOperand(MI, OpNo + 1, STI, O);
607  if (InputModifiers & SISrcMods::ABS)
608  O << '|';
609 
610  if (NegMnemo) {
611  O << ')';
612  }
613 }
614 
615 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
616  unsigned OpNo,
617  const MCSubtargetInfo &STI,
618  raw_ostream &O) {
619  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
620  if (InputModifiers & SISrcMods::SEXT)
621  O << "sext(";
622  printOperand(MI, OpNo + 1, STI, O);
623  if (InputModifiers & SISrcMods::SEXT)
624  O << ')';
625 }
626 
627 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
628  const MCSubtargetInfo &STI,
629  raw_ostream &O) {
630  using namespace AMDGPU::DPP;
631 
632  unsigned Imm = MI->getOperand(OpNo).getImm();
633  if (Imm <= DppCtrl::QUAD_PERM_LAST) {
634  O << " quad_perm:[";
635  O << formatDec(Imm & 0x3) << ',';
636  O << formatDec((Imm & 0xc) >> 2) << ',';
637  O << formatDec((Imm & 0x30) >> 4) << ',';
638  O << formatDec((Imm & 0xc0) >> 6) << ']';
639  } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
640  (Imm <= DppCtrl::ROW_SHL_LAST)) {
641  O << " row_shl:";
642  printU4ImmDecOperand(MI, OpNo, O);
643  } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
644  (Imm <= DppCtrl::ROW_SHR_LAST)) {
645  O << " row_shr:";
646  printU4ImmDecOperand(MI, OpNo, O);
647  } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
648  (Imm <= DppCtrl::ROW_ROR_LAST)) {
649  O << " row_ror:";
650  printU4ImmDecOperand(MI, OpNo, O);
651  } else if (Imm == DppCtrl::WAVE_SHL1) {
652  O << " wave_shl:1";
653  } else if (Imm == DppCtrl::WAVE_ROL1) {
654  O << " wave_rol:1";
655  } else if (Imm == DppCtrl::WAVE_SHR1) {
656  O << " wave_shr:1";
657  } else if (Imm == DppCtrl::WAVE_ROR1) {
658  O << " wave_ror:1";
659  } else if (Imm == DppCtrl::ROW_MIRROR) {
660  O << " row_mirror";
661  } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
662  O << " row_half_mirror";
663  } else if (Imm == DppCtrl::BCAST15) {
664  O << " row_bcast:15";
665  } else if (Imm == DppCtrl::BCAST31) {
666  O << " row_bcast:31";
667  } else {
668  O << " /* Invalid dpp_ctrl value */";
669  }
670 }
671 
672 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
673  const MCSubtargetInfo &STI,
674  raw_ostream &O) {
675  O << " row_mask:";
676  printU4ImmOperand(MI, OpNo, STI, O);
677 }
678 
679 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
680  const MCSubtargetInfo &STI,
681  raw_ostream &O) {
682  O << " bank_mask:";
683  printU4ImmOperand(MI, OpNo, STI, O);
684 }
685 
686 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
687  const MCSubtargetInfo &STI,
688  raw_ostream &O) {
689  unsigned Imm = MI->getOperand(OpNo).getImm();
690  if (Imm) {
691  O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
692  }
693 }
694 
695 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
696  raw_ostream &O) {
697  using namespace llvm::AMDGPU::SDWA;
698 
699  unsigned Imm = MI->getOperand(OpNo).getImm();
700  switch (Imm) {
701  case SdwaSel::BYTE_0: O << "BYTE_0"; break;
702  case SdwaSel::BYTE_1: O << "BYTE_1"; break;
703  case SdwaSel::BYTE_2: O << "BYTE_2"; break;
704  case SdwaSel::BYTE_3: O << "BYTE_3"; break;
705  case SdwaSel::WORD_0: O << "WORD_0"; break;
706  case SdwaSel::WORD_1: O << "WORD_1"; break;
707  case SdwaSel::DWORD: O << "DWORD"; break;
708  default: llvm_unreachable("Invalid SDWA data select operand");
709  }
710 }
711 
712 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
713  const MCSubtargetInfo &STI,
714  raw_ostream &O) {
715  O << "dst_sel:";
716  printSDWASel(MI, OpNo, O);
717 }
718 
719 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
720  const MCSubtargetInfo &STI,
721  raw_ostream &O) {
722  O << "src0_sel:";
723  printSDWASel(MI, OpNo, O);
724 }
725 
726 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
727  const MCSubtargetInfo &STI,
728  raw_ostream &O) {
729  O << "src1_sel:";
730  printSDWASel(MI, OpNo, O);
731 }
732 
733 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
734  const MCSubtargetInfo &STI,
735  raw_ostream &O) {
736  using namespace llvm::AMDGPU::SDWA;
737 
738  O << "dst_unused:";
739  unsigned Imm = MI->getOperand(OpNo).getImm();
740  switch (Imm) {
741  case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
742  case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
743  case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
744  default: llvm_unreachable("Invalid SDWA dest_unused operand");
745  }
746 }
747 
748 template <unsigned N>
749 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
750  const MCSubtargetInfo &STI,
751  raw_ostream &O) {
752  unsigned Opc = MI->getOpcode();
753  int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
754  unsigned En = MI->getOperand(EnIdx).getImm();
755 
756  int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
757 
758  // If compr is set, print as src0, src0, src1, src1
759  if (MI->getOperand(ComprIdx).getImm()) {
760  if (N == 1 || N == 2)
761  --OpNo;
762  else if (N == 3)
763  OpNo -= 2;
764  }
765 
766  if (En & (1 << N))
767  printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
768  else
769  O << "off";
770 }
771 
772 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
773  const MCSubtargetInfo &STI,
774  raw_ostream &O) {
775  printExpSrcN<0>(MI, OpNo, STI, O);
776 }
777 
778 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
779  const MCSubtargetInfo &STI,
780  raw_ostream &O) {
781  printExpSrcN<1>(MI, OpNo, STI, O);
782 }
783 
784 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
785  const MCSubtargetInfo &STI,
786  raw_ostream &O) {
787  printExpSrcN<2>(MI, OpNo, STI, O);
788 }
789 
790 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
791  const MCSubtargetInfo &STI,
792  raw_ostream &O) {
793  printExpSrcN<3>(MI, OpNo, STI, O);
794 }
795 
796 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
797  const MCSubtargetInfo &STI,
798  raw_ostream &O) {
799  // This is really a 6 bit field.
800  uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
801 
802  if (Tgt <= 7)
803  O << " mrt" << Tgt;
804  else if (Tgt == 8)
805  O << " mrtz";
806  else if (Tgt == 9)
807  O << " null";
808  else if (Tgt >= 12 && Tgt <= 15)
809  O << " pos" << Tgt - 12;
810  else if (Tgt >= 32 && Tgt <= 63)
811  O << " param" << Tgt - 32;
812  else {
813  // Reserved values 10, 11
814  O << " invalid_target_" << Tgt;
815  }
816 }
817 
818 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
819  bool IsPacked, bool HasDstSel) {
820  int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
821 
822  for (int I = 0; I < NumOps; ++I) {
823  if (!!(Ops[I] & Mod) != DefaultValue)
824  return false;
825  }
826 
827  if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
828  return false;
829 
830  return true;
831 }
832 
833 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
834  StringRef Name,
835  unsigned Mod,
836  raw_ostream &O) {
837  unsigned Opc = MI->getOpcode();
838  int NumOps = 0;
839  int Ops[3];
840 
841  for (int OpName : { AMDGPU::OpName::src0_modifiers,
842  AMDGPU::OpName::src1_modifiers,
843  AMDGPU::OpName::src2_modifiers }) {
844  int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
845  if (Idx == -1)
846  break;
847 
848  Ops[NumOps++] = MI->getOperand(Idx).getImm();
849  }
850 
851  const bool HasDstSel =
852  NumOps > 0 &&
853  Mod == SISrcMods::OP_SEL_0 &&
854  MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
855 
856  const bool IsPacked =
857  MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
858 
859  if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
860  return;
861 
862  O << Name;
863  for (int I = 0; I < NumOps; ++I) {
864  if (I != 0)
865  O << ',';
866 
867  O << !!(Ops[I] & Mod);
868  }
869 
870  if (HasDstSel) {
871  O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
872  }
873 
874  O << ']';
875 }
876 
877 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
878  const MCSubtargetInfo &STI,
879  raw_ostream &O) {
880  printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
881 }
882 
883 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
884  const MCSubtargetInfo &STI,
885  raw_ostream &O) {
886  printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
887 }
888 
889 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
890  const MCSubtargetInfo &STI,
891  raw_ostream &O) {
892  printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
893 }
894 
895 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
896  const MCSubtargetInfo &STI,
897  raw_ostream &O) {
898  printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
899 }
900 
901 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
902  const MCSubtargetInfo &STI,
903  raw_ostream &O) {
904  unsigned Imm = MI->getOperand(OpNum).getImm();
905  switch (Imm) {
906  case 0:
907  O << "p10";
908  break;
909  case 1:
910  O << "p20";
911  break;
912  case 2:
913  O << "p0";
914  break;
915  default:
916  O << "invalid_param_" << Imm;
917  }
918 }
919 
920 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
921  const MCSubtargetInfo &STI,
922  raw_ostream &O) {
923  unsigned Attr = MI->getOperand(OpNum).getImm();
924  O << "attr" << Attr;
925 }
926 
927 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
928  const MCSubtargetInfo &STI,
929  raw_ostream &O) {
930  unsigned Chan = MI->getOperand(OpNum).getImm();
931  O << '.' << "xyzw"[Chan & 0x3];
932 }
933 
934 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
935  const MCSubtargetInfo &STI,
936  raw_ostream &O) {
937  unsigned Val = MI->getOperand(OpNo).getImm();
938  if (Val == 0) {
939  O << " 0";
940  return;
941  }
942 
943  if (Val & VGPRIndexMode::DST_ENABLE)
944  O << " dst";
945 
946  if (Val & VGPRIndexMode::SRC0_ENABLE)
947  O << " src0";
948 
949  if (Val & VGPRIndexMode::SRC1_ENABLE)
950  O << " src1";
951 
952  if (Val & VGPRIndexMode::SRC2_ENABLE)
953  O << " src2";
954 }
955 
956 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
957  const MCSubtargetInfo &STI,
958  raw_ostream &O) {
959  printOperand(MI, OpNo, STI, O);
960  O << ", ";
961  printOperand(MI, OpNo + 1, STI, O);
962 }
963 
964 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
966  StringRef Default) {
967  const MCOperand &Op = MI->getOperand(OpNo);
968  assert(Op.isImm());
969  if (Op.getImm() == 1) {
970  O << Asm;
971  } else {
972  O << Default;
973  }
974 }
975 
976 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
977  raw_ostream &O, char Asm) {
978  const MCOperand &Op = MI->getOperand(OpNo);
979  assert(Op.isImm());
980  if (Op.getImm() == 1)
981  O << Asm;
982 }
983 
984 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
985  const MCSubtargetInfo &STI,
986  raw_ostream &O) {
987  if (MI->getOperand(OpNo).getImm())
988  O << " high";
989 }
990 
991 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
992  const MCSubtargetInfo &STI,
993  raw_ostream &O) {
994  if (MI->getOperand(OpNo).getImm())
995  O << " clamp";
996 }
997 
998 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
999  const MCSubtargetInfo &STI,
1000  raw_ostream &O) {
1001  int Imm = MI->getOperand(OpNo).getImm();
1002  if (Imm == SIOutMods::MUL2)
1003  O << " mul:2";
1004  else if (Imm == SIOutMods::MUL4)
1005  O << " mul:4";
1006  else if (Imm == SIOutMods::DIV2)
1007  O << " div:2";
1008 }
1009 
1010 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1011  const MCSubtargetInfo &STI,
1012  raw_ostream &O) {
1013  using namespace llvm::AMDGPU::SendMsg;
1014 
1015  const unsigned SImm16 = MI->getOperand(OpNo).getImm();
1016  const unsigned Id = SImm16 & ID_MASK_;
1017  do {
1018  if (Id == ID_INTERRUPT) {
1019  if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0.
1020  break;
1021  O << "sendmsg(" << IdSymbolic[Id] << ')';
1022  return;
1023  }
1024  if (Id == ID_GS || Id == ID_GS_DONE) {
1025  if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0.
1026  break;
1027  const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_;
1028  const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
1029  if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only.
1030  break;
1031  if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits.
1032  break;
1033  O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs];
1034  if (OpGs != OP_GS_NOP) { O << ", " << StreamId; }
1035  O << ')';
1036  return;
1037  }
1038  if (Id == ID_SYSMSG) {
1039  if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0.
1040  break;
1041  const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_;
1042  if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown.
1043  break;
1044  O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')';
1045  return;
1046  }
1047  } while (false);
1048  O << SImm16; // Unknown simm16 code.
1049 }
1050 
1051 static void printSwizzleBitmask(const uint16_t AndMask,
1052  const uint16_t OrMask,
1053  const uint16_t XorMask,
1054  raw_ostream &O) {
1055  using namespace llvm::AMDGPU::Swizzle;
1056 
1057  uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1058  uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1059 
1060  O << "\"";
1061 
1062  for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1063  uint16_t p0 = Probe0 & Mask;
1064  uint16_t p1 = Probe1 & Mask;
1065 
1066  if (p0 == p1) {
1067  if (p0 == 0) {
1068  O << "0";
1069  } else {
1070  O << "1";
1071  }
1072  } else {
1073  if (p0 == 0) {
1074  O << "p";
1075  } else {
1076  O << "i";
1077  }
1078  }
1079  }
1080 
1081  O << "\"";
1082 }
1083 
1084 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1085  const MCSubtargetInfo &STI,
1086  raw_ostream &O) {
1087  using namespace llvm::AMDGPU::Swizzle;
1088 
1089  uint16_t Imm = MI->getOperand(OpNo).getImm();
1090  if (Imm == 0) {
1091  return;
1092  }
1093 
1094  O << " offset:";
1095 
1096  if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1097 
1098  O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1099  for (auto i = 0; i < LANE_NUM; ++i) {
1100  O << ",";
1101  O << formatDec(Imm & LANE_MASK);
1102  Imm >>= LANE_SHIFT;
1103  }
1104  O << ")";
1105 
1106  } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1107 
1108  uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1109  uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1110  uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1111 
1112  if (AndMask == BITMASK_MAX &&
1113  OrMask == 0 &&
1114  countPopulation(XorMask) == 1) {
1115 
1116  O << "swizzle(" << IdSymbolic[ID_SWAP];
1117  O << ",";
1118  O << formatDec(XorMask);
1119  O << ")";
1120 
1121  } else if (AndMask == BITMASK_MAX &&
1122  OrMask == 0 && XorMask > 0 &&
1123  isPowerOf2_64(XorMask + 1)) {
1124 
1125  O << "swizzle(" << IdSymbolic[ID_REVERSE];
1126  O << ",";
1127  O << formatDec(XorMask + 1);
1128  O << ")";
1129 
1130  } else {
1131 
1132  uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1133  if (GroupSize > 1 &&
1134  isPowerOf2_64(GroupSize) &&
1135  OrMask < GroupSize &&
1136  XorMask == 0) {
1137 
1138  O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1139  O << ",";
1140  O << formatDec(GroupSize);
1141  O << ",";
1142  O << formatDec(OrMask);
1143  O << ")";
1144 
1145  } else {
1146  O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1147  O << ",";
1148  printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1149  O << ")";
1150  }
1151  }
1152  } else {
1153  printU16ImmDecOperand(MI, OpNo, O);
1154  }
1155 }
1156 
1157 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1158  const MCSubtargetInfo &STI,
1159  raw_ostream &O) {
1161 
1162  unsigned SImm16 = MI->getOperand(OpNo).getImm();
1163  unsigned Vmcnt, Expcnt, Lgkmcnt;
1164  decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1165 
1166  bool NeedSpace = false;
1167 
1168  if (Vmcnt != getVmcntBitMask(ISA)) {
1169  O << "vmcnt(" << Vmcnt << ')';
1170  NeedSpace = true;
1171  }
1172 
1173  if (Expcnt != getExpcntBitMask(ISA)) {
1174  if (NeedSpace)
1175  O << ' ';
1176  O << "expcnt(" << Expcnt << ')';
1177  NeedSpace = true;
1178  }
1179 
1180  if (Lgkmcnt != getLgkmcntBitMask(ISA)) {
1181  if (NeedSpace)
1182  O << ' ';
1183  O << "lgkmcnt(" << Lgkmcnt << ')';
1184  }
1185 }
1186 
1187 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1188  const MCSubtargetInfo &STI, raw_ostream &O) {
1189  using namespace llvm::AMDGPU::Hwreg;
1190 
1191  unsigned SImm16 = MI->getOperand(OpNo).getImm();
1192  const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_;
1193  const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_;
1194  const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1;
1195 
1196  O << "hwreg(";
1197  unsigned Last = ID_SYMBOLIC_LAST_;
1198  if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI) || AMDGPU::isVI(STI))
1199  Last = ID_SYMBOLIC_FIRST_GFX9_;
1200  if (ID_SYMBOLIC_FIRST_ <= Id && Id < Last && IdSymbolic[Id]) {
1201  O << IdSymbolic[Id];
1202  } else {
1203  O << Id;
1204  }
1205  if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) {
1206  O << ", " << Offset << ", " << Width;
1207  }
1208  O << ')';
1209 }
1210 
1211 #include "AMDGPUGenAsmWriter.inc"
1212 
1214  StringRef Annot, const MCSubtargetInfo &STI) {
1215  O.flush();
1216  printInstruction(MI, O);
1217  printAnnotation(O, Annot);
1218 }
1219 
1220 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
1221  raw_ostream &O) {
1222  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
1223 }
1224 
1225 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
1226  raw_ostream &O) {
1227  int BankSwizzle = MI->getOperand(OpNo).getImm();
1228  switch (BankSwizzle) {
1229  case 1:
1230  O << "BS:VEC_021/SCL_122";
1231  break;
1232  case 2:
1233  O << "BS:VEC_120/SCL_212";
1234  break;
1235  case 3:
1236  O << "BS:VEC_102/SCL_221";
1237  break;
1238  case 4:
1239  O << "BS:VEC_201";
1240  break;
1241  case 5:
1242  O << "BS:VEC_210";
1243  break;
1244  default:
1245  break;
1246  }
1247 }
1248 
1249 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
1250  raw_ostream &O) {
1251  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
1252 }
1253 
1254 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo,
1255  raw_ostream &O) {
1256  unsigned CT = MI->getOperand(OpNo).getImm();
1257  switch (CT) {
1258  case 0:
1259  O << 'U';
1260  break;
1261  case 1:
1262  O << 'N';
1263  break;
1264  default:
1265  break;
1266  }
1267 }
1268 
1269 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1270  raw_ostream &O) {
1271  int KCacheMode = MI->getOperand(OpNo).getImm();
1272  if (KCacheMode > 0) {
1273  int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1274  O << "CB" << KCacheBank << ':';
1275  int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1276  int LineSize = (KCacheMode == 1) ? 16 : 32;
1277  O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1278  }
1279 }
1280 
1281 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
1282  raw_ostream &O) {
1283  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
1284 }
1285 
1286 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
1287  raw_ostream &O) {
1288  const MCOperand &Op = MI->getOperand(OpNo);
1289  assert(Op.isImm() || Op.isExpr());
1290  if (Op.isImm()) {
1291  int64_t Imm = Op.getImm();
1292  O << Imm << '(' << BitsToFloat(Imm) << ')';
1293  }
1294  if (Op.isExpr()) {
1295  Op.getExpr()->print(O << '@', &MAI);
1296  }
1297 }
1298 
1299 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
1300  raw_ostream &O) {
1301  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
1302 }
1303 
1304 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
1305  raw_ostream &O) {
1306  switch (MI->getOperand(OpNo).getImm()) {
1307  default: break;
1308  case 1:
1309  O << " * 2.0";
1310  break;
1311  case 2:
1312  O << " * 4.0";
1313  break;
1314  case 3:
1315  O << " / 2.0";
1316  break;
1317  }
1318 }
1319 
1320 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1321  raw_ostream &O) {
1322  printOperand(MI, OpNo, O);
1323  O << ", ";
1324  printOperand(MI, OpNo + 1, O);
1325 }
1326 
1327 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
1328  raw_ostream &O) {
1329  if (OpNo >= MI->getNumOperands()) {
1330  O << "/*Missing OP" << OpNo << "*/";
1331  return;
1332  }
1333 
1334  const MCOperand &Op = MI->getOperand(OpNo);
1335  if (Op.isReg()) {
1336  switch (Op.getReg()) {
1337  // This is the default predicate state, so we don't need to print it.
1338  case R600::PRED_SEL_OFF:
1339  break;
1340 
1341  default:
1342  O << getRegisterName(Op.getReg());
1343  break;
1344  }
1345  } else if (Op.isImm()) {
1346  O << Op.getImm();
1347  } else if (Op.isFPImm()) {
1348  // We special case 0.0 because otherwise it will be printed as an integer.
1349  if (Op.getFPImm() == 0.0)
1350  O << "0.0";
1351  else {
1352  O << Op.getFPImm();
1353  }
1354  } else if (Op.isExpr()) {
1355  const MCExpr *Exp = Op.getExpr();
1356  Exp->print(O, &MAI);
1357  } else {
1358  O << "/*INV_OP*/";
1359  }
1360 }
1361 
1362 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
1363  raw_ostream &O) {
1364  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
1365 }
1366 
1367 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
1368  raw_ostream &O) {
1369  unsigned Sel = MI->getOperand(OpNo).getImm();
1370  switch (Sel) {
1371  case 0:
1372  O << 'X';
1373  break;
1374  case 1:
1375  O << 'Y';
1376  break;
1377  case 2:
1378  O << 'Z';
1379  break;
1380  case 3:
1381  O << 'W';
1382  break;
1383  case 4:
1384  O << '0';
1385  break;
1386  case 5:
1387  O << '1';
1388  break;
1389  case 7:
1390  O << '_';
1391  break;
1392  default:
1393  break;
1394  }
1395 }
1396 
1397 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
1398  raw_ostream &O) {
1399  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
1400 }
1401 
1402 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
1403  raw_ostream &O) {
1404  AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
1405 }
1406 
1407 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
1408  raw_ostream &O) {
1409  const MCOperand &Op = MI->getOperand(OpNo);
1410  if (Op.getImm() == 0) {
1411  O << " (MASKED)";
1412  }
1413 }
1414 
1415 #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 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:920
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.
Operands with register or inline constant.
Definition: SIDefines.h:123
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)
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.
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:345
Operands with register or 32-bit immediate.
Definition: SIDefines.h:115
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...