LLVM  4.0.0
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"
12 #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::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
76  const MCSubtargetInfo &STI,
77  raw_ostream &O) {
78  O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
79 }
80 
81 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
82  raw_ostream &O, StringRef BitName) {
83  if (MI->getOperand(OpNo).getImm()) {
84  O << ' ' << BitName;
85  }
86 }
87 
88 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
89  raw_ostream &O) {
90  printNamedBit(MI, OpNo, O, "offen");
91 }
92 
93 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
94  raw_ostream &O) {
95  printNamedBit(MI, OpNo, O, "idxen");
96 }
97 
98 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
99  raw_ostream &O) {
100  printNamedBit(MI, OpNo, O, "addr64");
101 }
102 
103 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
104  raw_ostream &O) {
105  if (MI->getOperand(OpNo).getImm()) {
106  O << " offset:";
107  printU16ImmDecOperand(MI, OpNo, O);
108  }
109 }
110 
111 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
112  const MCSubtargetInfo &STI,
113  raw_ostream &O) {
114  uint16_t Imm = MI->getOperand(OpNo).getImm();
115  if (Imm != 0) {
116  O << " offset:";
117  printU16ImmDecOperand(MI, OpNo, O);
118  }
119 }
120 
121 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
122  const MCSubtargetInfo &STI,
123  raw_ostream &O) {
124  if (MI->getOperand(OpNo).getImm()) {
125  O << " offset0:";
126  printU8ImmDecOperand(MI, OpNo, O);
127  }
128 }
129 
130 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
131  const MCSubtargetInfo &STI,
132  raw_ostream &O) {
133  if (MI->getOperand(OpNo).getImm()) {
134  O << " offset1:";
135  printU8ImmDecOperand(MI, OpNo, O);
136  }
137 }
138 
139 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
140  const MCSubtargetInfo &STI,
141  raw_ostream &O) {
142  printU32ImmOperand(MI, OpNo, STI, O);
143 }
144 
145 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
146  const MCSubtargetInfo &STI,
147  raw_ostream &O) {
148  printU32ImmOperand(MI, OpNo, STI, O);
149 }
150 
151 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
152  const MCSubtargetInfo &STI,
153  raw_ostream &O) {
154  printU32ImmOperand(MI, OpNo, STI, O);
155 }
156 
157 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
158  const MCSubtargetInfo &STI, raw_ostream &O) {
159  printNamedBit(MI, OpNo, O, "gds");
160 }
161 
162 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
163  const MCSubtargetInfo &STI, raw_ostream &O) {
164  printNamedBit(MI, OpNo, O, "glc");
165 }
166 
167 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
168  const MCSubtargetInfo &STI, raw_ostream &O) {
169  printNamedBit(MI, OpNo, O, "slc");
170 }
171 
172 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
173  const MCSubtargetInfo &STI, raw_ostream &O) {
174  printNamedBit(MI, OpNo, O, "tfe");
175 }
176 
177 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
178  const MCSubtargetInfo &STI, raw_ostream &O) {
179  if (MI->getOperand(OpNo).getImm()) {
180  O << " dmask:";
181  printU16ImmOperand(MI, OpNo, STI, O);
182  }
183 }
184 
185 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
186  const MCSubtargetInfo &STI, raw_ostream &O) {
187  printNamedBit(MI, OpNo, O, "unorm");
188 }
189 
190 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
191  const MCSubtargetInfo &STI, raw_ostream &O) {
192  printNamedBit(MI, OpNo, O, "da");
193 }
194 
195 void AMDGPUInstPrinter::printR128(const MCInst *MI, unsigned OpNo,
196  const MCSubtargetInfo &STI, raw_ostream &O) {
197  printNamedBit(MI, OpNo, O, "r128");
198 }
199 
200 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
201  const MCSubtargetInfo &STI, raw_ostream &O) {
202  printNamedBit(MI, OpNo, O, "lwe");
203 }
204 
205 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
206  const MCSubtargetInfo &STI,
207  raw_ostream &O) {
208  if (MI->getOperand(OpNo).getImm())
209  O << " compr";
210 }
211 
212 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
213  const MCSubtargetInfo &STI,
214  raw_ostream &O) {
215  if (MI->getOperand(OpNo).getImm())
216  O << " vm";
217 }
218 
220  const MCRegisterInfo &MRI) {
221  switch (RegNo) {
222  case AMDGPU::VCC:
223  O << "vcc";
224  return;
225  case AMDGPU::SCC:
226  O << "scc";
227  return;
228  case AMDGPU::EXEC:
229  O << "exec";
230  return;
231  case AMDGPU::M0:
232  O << "m0";
233  return;
234  case AMDGPU::FLAT_SCR:
235  O << "flat_scratch";
236  return;
237  case AMDGPU::VCC_LO:
238  O << "vcc_lo";
239  return;
240  case AMDGPU::VCC_HI:
241  O << "vcc_hi";
242  return;
243  case AMDGPU::TBA_LO:
244  O << "tba_lo";
245  return;
246  case AMDGPU::TBA_HI:
247  O << "tba_hi";
248  return;
249  case AMDGPU::TMA_LO:
250  O << "tma_lo";
251  return;
252  case AMDGPU::TMA_HI:
253  O << "tma_hi";
254  return;
255  case AMDGPU::EXEC_LO:
256  O << "exec_lo";
257  return;
258  case AMDGPU::EXEC_HI:
259  O << "exec_hi";
260  return;
261  case AMDGPU::FLAT_SCR_LO:
262  O << "flat_scratch_lo";
263  return;
264  case AMDGPU::FLAT_SCR_HI:
265  O << "flat_scratch_hi";
266  return;
267  default:
268  break;
269  }
270 
271  // The low 8 bits of the encoding value is the register index, for both VGPRs
272  // and SGPRs.
273  unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1);
274 
275  unsigned NumRegs;
276  if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) {
277  O << 'v';
278  NumRegs = 1;
279  } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) {
280  O << 's';
281  NumRegs = 1;
282  } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) {
283  O <<'v';
284  NumRegs = 2;
285  } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) {
286  O << 's';
287  NumRegs = 2;
288  } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) {
289  O << 'v';
290  NumRegs = 4;
291  } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) {
292  O << 's';
293  NumRegs = 4;
294  } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) {
295  O << 'v';
296  NumRegs = 3;
297  } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) {
298  O << 'v';
299  NumRegs = 8;
300  } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(RegNo)) {
301  O << 's';
302  NumRegs = 8;
303  } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) {
304  O << 'v';
305  NumRegs = 16;
306  } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(RegNo)) {
307  O << 's';
308  NumRegs = 16;
309  } else if (MRI.getRegClass(AMDGPU::TTMP_64RegClassID).contains(RegNo)) {
310  O << "ttmp";
311  NumRegs = 2;
312  // Trap temps start at offset 112. TODO: Get this from tablegen.
313  RegIdx -= 112;
314  } else if (MRI.getRegClass(AMDGPU::TTMP_128RegClassID).contains(RegNo)) {
315  O << "ttmp";
316  NumRegs = 4;
317  // Trap temps start at offset 112. TODO: Get this from tablegen.
318  RegIdx -= 112;
319  } else {
320  O << getRegisterName(RegNo);
321  return;
322  }
323 
324  if (NumRegs == 1) {
325  O << RegIdx;
326  return;
327  }
328 
329  O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
330 }
331 
332 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
333  const MCSubtargetInfo &STI, raw_ostream &O) {
334  if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
335  O << "_e64 ";
336  else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
337  O << "_dpp ";
338  else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
339  O << "_sdwa ";
340  else
341  O << "_e32 ";
342 
343  printOperand(MI, OpNo, STI, O);
344 }
345 
346 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
347  const MCSubtargetInfo &STI,
348  raw_ostream &O) {
349  int16_t SImm = static_cast<int16_t>(Imm);
350  if (SImm >= -16 && SImm <= 64) {
351  O << SImm;
352  return;
353  }
354 
355  if (Imm == 0x3C00)
356  O<< "1.0";
357  else if (Imm == 0xBC00)
358  O<< "-1.0";
359  else if (Imm == 0x3800)
360  O<< "0.5";
361  else if (Imm == 0xB800)
362  O<< "-0.5";
363  else if (Imm == 0x4000)
364  O<< "2.0";
365  else if (Imm == 0xC000)
366  O<< "-2.0";
367  else if (Imm == 0x4400)
368  O<< "4.0";
369  else if (Imm == 0xC400)
370  O<< "-4.0";
371  else if (Imm == 0x3118) {
372  assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]);
373  O << "0.15915494";
374  } else
375  O << formatHex(static_cast<uint64_t>(Imm));
376 }
377 
378 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
379  const MCSubtargetInfo &STI,
380  raw_ostream &O) {
381  int32_t SImm = static_cast<int32_t>(Imm);
382  if (SImm >= -16 && SImm <= 64) {
383  O << SImm;
384  return;
385  }
386 
387  if (Imm == FloatToBits(0.0f))
388  O << "0.0";
389  else if (Imm == FloatToBits(1.0f))
390  O << "1.0";
391  else if (Imm == FloatToBits(-1.0f))
392  O << "-1.0";
393  else if (Imm == FloatToBits(0.5f))
394  O << "0.5";
395  else if (Imm == FloatToBits(-0.5f))
396  O << "-0.5";
397  else if (Imm == FloatToBits(2.0f))
398  O << "2.0";
399  else if (Imm == FloatToBits(-2.0f))
400  O << "-2.0";
401  else if (Imm == FloatToBits(4.0f))
402  O << "4.0";
403  else if (Imm == FloatToBits(-4.0f))
404  O << "-4.0";
405  else if (Imm == 0x3e22f983 &&
406  STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
407  O << "0.15915494";
408  else
409  O << formatHex(static_cast<uint64_t>(Imm));
410 }
411 
412 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
413  const MCSubtargetInfo &STI,
414  raw_ostream &O) {
415  int64_t SImm = static_cast<int64_t>(Imm);
416  if (SImm >= -16 && SImm <= 64) {
417  O << SImm;
418  return;
419  }
420 
421  if (Imm == DoubleToBits(0.0))
422  O << "0.0";
423  else if (Imm == DoubleToBits(1.0))
424  O << "1.0";
425  else if (Imm == DoubleToBits(-1.0))
426  O << "-1.0";
427  else if (Imm == DoubleToBits(0.5))
428  O << "0.5";
429  else if (Imm == DoubleToBits(-0.5))
430  O << "-0.5";
431  else if (Imm == DoubleToBits(2.0))
432  O << "2.0";
433  else if (Imm == DoubleToBits(-2.0))
434  O << "-2.0";
435  else if (Imm == DoubleToBits(4.0))
436  O << "4.0";
437  else if (Imm == DoubleToBits(-4.0))
438  O << "-4.0";
439  else if (Imm == 0x3fc45f306dc9c882 &&
440  STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
441  O << "0.15915494";
442  else {
443  assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882);
444 
445  // In rare situations, we will have a 32-bit literal in a 64-bit
446  // operand. This is technically allowed for the encoding of s_mov_b64.
447  O << formatHex(static_cast<uint64_t>(Imm));
448  }
449 }
450 
451 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
452  const MCSubtargetInfo &STI,
453  raw_ostream &O) {
454  if (OpNo >= MI->getNumOperands()) {
455  O << "/*Missing OP" << OpNo << "*/";
456  return;
457  }
458 
459  const MCOperand &Op = MI->getOperand(OpNo);
460  if (Op.isReg()) {
461  switch (Op.getReg()) {
462  // This is the default predicate state, so we don't need to print it.
463  case AMDGPU::PRED_SEL_OFF:
464  break;
465 
466  default:
467  printRegOperand(Op.getReg(), O, MRI);
468  break;
469  }
470  } else if (Op.isImm()) {
471  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
472  switch (Desc.OpInfo[OpNo].OperandType) {
478  printImmediate32(Op.getImm(), STI, O);
479  break;
484  printImmediate64(Op.getImm(), STI, O);
485  break;
490  printImmediate16(Op.getImm(), STI, O);
491  break;
493  case MCOI::OPERAND_PCREL:
494  O << formatDec(Op.getImm());
495  break;
497  // FIXME: This should be removed and handled somewhere else. Seems to come
498  // from a disassembler bug.
499  O << "/*invalid immediate*/";
500  break;
501  default:
502  // We hit this for the immediate instruction bits that don't yet have a
503  // custom printer.
504  llvm_unreachable("unexpected immediate operand type");
505  }
506  } else if (Op.isFPImm()) {
507  // We special case 0.0 because otherwise it will be printed as an integer.
508  if (Op.getFPImm() == 0.0)
509  O << "0.0";
510  else {
511  const MCInstrDesc &Desc = MII.get(MI->getOpcode());
512  int RCID = Desc.OpInfo[OpNo].RegClass;
513  unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
514  if (RCBits == 32)
515  printImmediate32(FloatToBits(Op.getFPImm()), STI, O);
516  else if (RCBits == 64)
517  printImmediate64(DoubleToBits(Op.getFPImm()), STI, O);
518  else
519  llvm_unreachable("Invalid register class size");
520  }
521  } else if (Op.isExpr()) {
522  const MCExpr *Exp = Op.getExpr();
523  Exp->print(O, &MAI);
524  } else {
525  O << "/*INV_OP*/";
526  }
527 }
528 
529 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
530  unsigned OpNo,
531  const MCSubtargetInfo &STI,
532  raw_ostream &O) {
533  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
534  if (InputModifiers & SISrcMods::NEG)
535  O << '-';
536  if (InputModifiers & SISrcMods::ABS)
537  O << '|';
538  printOperand(MI, OpNo + 1, STI, O);
539  if (InputModifiers & SISrcMods::ABS)
540  O << '|';
541 }
542 
543 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
544  unsigned OpNo,
545  const MCSubtargetInfo &STI,
546  raw_ostream &O) {
547  unsigned InputModifiers = MI->getOperand(OpNo).getImm();
548  if (InputModifiers & SISrcMods::SEXT)
549  O << "sext(";
550  printOperand(MI, OpNo + 1, STI, O);
551  if (InputModifiers & SISrcMods::SEXT)
552  O << ')';
553 }
554 
555 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
556  const MCSubtargetInfo &STI,
557  raw_ostream &O) {
558  unsigned Imm = MI->getOperand(OpNo).getImm();
559  if (Imm <= 0x0ff) {
560  O << " quad_perm:[";
561  O << formatDec(Imm & 0x3) << ',';
562  O << formatDec((Imm & 0xc) >> 2) << ',';
563  O << formatDec((Imm & 0x30) >> 4) << ',';
564  O << formatDec((Imm & 0xc0) >> 6) << ']';
565  } else if ((Imm >= 0x101) && (Imm <= 0x10f)) {
566  O << " row_shl:";
567  printU4ImmDecOperand(MI, OpNo, O);
568  } else if ((Imm >= 0x111) && (Imm <= 0x11f)) {
569  O << " row_shr:";
570  printU4ImmDecOperand(MI, OpNo, O);
571  } else if ((Imm >= 0x121) && (Imm <= 0x12f)) {
572  O << " row_ror:";
573  printU4ImmDecOperand(MI, OpNo, O);
574  } else if (Imm == 0x130) {
575  O << " wave_shl:1";
576  } else if (Imm == 0x134) {
577  O << " wave_rol:1";
578  } else if (Imm == 0x138) {
579  O << " wave_shr:1";
580  } else if (Imm == 0x13c) {
581  O << " wave_ror:1";
582  } else if (Imm == 0x140) {
583  O << " row_mirror";
584  } else if (Imm == 0x141) {
585  O << " row_half_mirror";
586  } else if (Imm == 0x142) {
587  O << " row_bcast:15";
588  } else if (Imm == 0x143) {
589  O << " row_bcast:31";
590  } else {
591  llvm_unreachable("Invalid dpp_ctrl value");
592  }
593 }
594 
595 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
596  const MCSubtargetInfo &STI,
597  raw_ostream &O) {
598  O << " row_mask:";
599  printU4ImmOperand(MI, OpNo, STI, O);
600 }
601 
602 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
603  const MCSubtargetInfo &STI,
604  raw_ostream &O) {
605  O << " bank_mask:";
606  printU4ImmOperand(MI, OpNo, STI, O);
607 }
608 
609 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
610  const MCSubtargetInfo &STI,
611  raw_ostream &O) {
612  unsigned Imm = MI->getOperand(OpNo).getImm();
613  if (Imm) {
614  O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
615  }
616 }
617 
618 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
619  raw_ostream &O) {
620  using namespace llvm::AMDGPU::SDWA;
621 
622  unsigned Imm = MI->getOperand(OpNo).getImm();
623  switch (Imm) {
624  case SdwaSel::BYTE_0: O << "BYTE_0"; break;
625  case SdwaSel::BYTE_1: O << "BYTE_1"; break;
626  case SdwaSel::BYTE_2: O << "BYTE_2"; break;
627  case SdwaSel::BYTE_3: O << "BYTE_3"; break;
628  case SdwaSel::WORD_0: O << "WORD_0"; break;
629  case SdwaSel::WORD_1: O << "WORD_1"; break;
630  case SdwaSel::DWORD: O << "DWORD"; break;
631  default: llvm_unreachable("Invalid SDWA data select operand");
632  }
633 }
634 
635 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
636  const MCSubtargetInfo &STI,
637  raw_ostream &O) {
638  O << "dst_sel:";
639  printSDWASel(MI, OpNo, O);
640 }
641 
642 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
643  const MCSubtargetInfo &STI,
644  raw_ostream &O) {
645  O << "src0_sel:";
646  printSDWASel(MI, OpNo, O);
647 }
648 
649 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
650  const MCSubtargetInfo &STI,
651  raw_ostream &O) {
652  O << "src1_sel:";
653  printSDWASel(MI, OpNo, O);
654 }
655 
656 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
657  const MCSubtargetInfo &STI,
658  raw_ostream &O) {
659  using namespace llvm::AMDGPU::SDWA;
660 
661  O << "dst_unused:";
662  unsigned Imm = MI->getOperand(OpNo).getImm();
663  switch (Imm) {
664  case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
665  case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
666  case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
667  default: llvm_unreachable("Invalid SDWA dest_unused operand");
668  }
669 }
670 
671 template <unsigned N>
672 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
673  const MCSubtargetInfo &STI,
674  raw_ostream &O) {
675  int EnIdx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::en);
676  unsigned En = MI->getOperand(EnIdx).getImm();
677 
678  // FIXME: What do we do with compr? The meaning of en changes depending on if
679  // compr is set.
680 
681  if (En & (1 << N))
682  printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
683  else
684  O << "off";
685 }
686 
687 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
688  const MCSubtargetInfo &STI,
689  raw_ostream &O) {
690  printExpSrcN<0>(MI, OpNo, STI, O);
691 }
692 
693 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
694  const MCSubtargetInfo &STI,
695  raw_ostream &O) {
696  printExpSrcN<1>(MI, OpNo, STI, O);
697 }
698 
699 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
700  const MCSubtargetInfo &STI,
701  raw_ostream &O) {
702  printExpSrcN<2>(MI, OpNo, STI, O);
703 }
704 
705 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
706  const MCSubtargetInfo &STI,
707  raw_ostream &O) {
708  printExpSrcN<3>(MI, OpNo, STI, O);
709 }
710 
711 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
712  const MCSubtargetInfo &STI,
713  raw_ostream &O) {
714  // This is really a 6 bit field.
715  uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
716 
717  if (Tgt <= 7)
718  O << " mrt" << Tgt;
719  else if (Tgt == 8)
720  O << " mrtz";
721  else if (Tgt == 9)
722  O << " null";
723  else if (Tgt >= 12 && Tgt <= 15)
724  O << " pos" << Tgt - 12;
725  else if (Tgt >= 32 && Tgt <= 63)
726  O << " param" << Tgt - 32;
727  else {
728  // Reserved values 10, 11
729  O << " invalid_target_" << Tgt;
730  }
731 }
732 
733 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
734  const MCSubtargetInfo &STI,
735  raw_ostream &O) {
736  unsigned Imm = MI->getOperand(OpNum).getImm();
737  switch (Imm) {
738  case 0:
739  O << "p10";
740  break;
741  case 1:
742  O << "p20";
743  break;
744  case 2:
745  O << "p0";
746  break;
747  default:
748  O << "invalid_param_" << Imm;
749  }
750 }
751 
752 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
753  const MCSubtargetInfo &STI,
754  raw_ostream &O) {
755  unsigned Attr = MI->getOperand(OpNum).getImm();
756  O << "attr" << Attr;
757 }
758 
759 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
760  const MCSubtargetInfo &STI,
761  raw_ostream &O) {
762  unsigned Chan = MI->getOperand(OpNum).getImm();
763  O << '.' << "xyzw"[Chan & 0x3];
764 }
765 
766 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
767  const MCSubtargetInfo &STI,
768  raw_ostream &O) {
769  unsigned Val = MI->getOperand(OpNo).getImm();
770  if (Val == 0) {
771  O << " 0";
772  return;
773  }
774 
775  if (Val & VGPRIndexMode::DST_ENABLE)
776  O << " dst";
777 
778  if (Val & VGPRIndexMode::SRC0_ENABLE)
779  O << " src0";
780 
781  if (Val & VGPRIndexMode::SRC1_ENABLE)
782  O << " src1";
783 
784  if (Val & VGPRIndexMode::SRC2_ENABLE)
785  O << " src2";
786 }
787 
788 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
789  const MCSubtargetInfo &STI,
790  raw_ostream &O) {
791  printOperand(MI, OpNo, STI, O);
792  O << ", ";
793  printOperand(MI, OpNo + 1, STI, O);
794 }
795 
796 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
798  StringRef Default) {
799  const MCOperand &Op = MI->getOperand(OpNo);
800  assert(Op.isImm());
801  if (Op.getImm() == 1) {
802  O << Asm;
803  } else {
804  O << Default;
805  }
806 }
807 
808 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
809  raw_ostream &O, char Asm) {
810  const MCOperand &Op = MI->getOperand(OpNo);
811  assert(Op.isImm());
812  if (Op.getImm() == 1)
813  O << Asm;
814 }
815 
816 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
817  const MCSubtargetInfo &STI, raw_ostream &O) {
818  printIfSet(MI, OpNo, O, '|');
819 }
820 
821 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
822  const MCSubtargetInfo &STI, raw_ostream &O) {
823  printIfSet(MI, OpNo, O, "_SAT");
824 }
825 
826 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
827  const MCSubtargetInfo &STI,
828  raw_ostream &O) {
829  if (MI->getOperand(OpNo).getImm())
830  O << " clamp";
831 }
832 
833 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
834  const MCSubtargetInfo &STI,
835  raw_ostream &O) {
836  int Imm = MI->getOperand(OpNo).getImm();
837  if (Imm == SIOutMods::MUL2)
838  O << " mul:2";
839  else if (Imm == SIOutMods::MUL4)
840  O << " mul:4";
841  else if (Imm == SIOutMods::DIV2)
842  O << " div:2";
843 }
844 
845 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
846  const MCSubtargetInfo &STI,
847  raw_ostream &O) {
848  const MCOperand &Op = MI->getOperand(OpNo);
849  assert(Op.isImm() || Op.isExpr());
850  if (Op.isImm()) {
851  int64_t Imm = Op.getImm();
852  O << Imm << '(' << BitsToFloat(Imm) << ')';
853  }
854  if (Op.isExpr()) {
855  Op.getExpr()->print(O << '@', &MAI);
856  }
857 }
858 
859 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
860  const MCSubtargetInfo &STI, raw_ostream &O) {
861  printIfSet(MI, OpNo, O, "*", " ");
862 }
863 
864 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
865  const MCSubtargetInfo &STI, raw_ostream &O) {
866  printIfSet(MI, OpNo, O, '-');
867 }
868 
869 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
870  const MCSubtargetInfo &STI, raw_ostream &O) {
871  switch (MI->getOperand(OpNo).getImm()) {
872  default: break;
873  case 1:
874  O << " * 2.0";
875  break;
876  case 2:
877  O << " * 4.0";
878  break;
879  case 3:
880  O << " / 2.0";
881  break;
882  }
883 }
884 
885 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
886  const MCSubtargetInfo &STI, raw_ostream &O) {
887  printIfSet(MI, OpNo, O, '+');
888 }
889 
890 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
891  const MCSubtargetInfo &STI,
892  raw_ostream &O) {
893  printIfSet(MI, OpNo, O, "ExecMask,");
894 }
895 
896 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
897  const MCSubtargetInfo &STI,
898  raw_ostream &O) {
899  printIfSet(MI, OpNo, O, "Pred,");
900 }
901 
902 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
903  const MCSubtargetInfo &STI, raw_ostream &O) {
904  const MCOperand &Op = MI->getOperand(OpNo);
905  if (Op.getImm() == 0) {
906  O << " (MASKED)";
907  }
908 }
909 
910 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
911  raw_ostream &O) {
912  const char * chans = "XYZW";
913  int sel = MI->getOperand(OpNo).getImm();
914 
915  int chan = sel & 3;
916  sel >>= 2;
917 
918  if (sel >= 512) {
919  sel -= 512;
920  int cb = sel >> 12;
921  sel &= 4095;
922  O << cb << '[' << sel << ']';
923  } else if (sel >= 448) {
924  sel -= 448;
925  O << sel;
926  } else if (sel >= 0){
927  O << sel;
928  }
929 
930  if (sel >= 0)
931  O << '.' << chans[chan];
932 }
933 
934 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
935  const MCSubtargetInfo &STI,
936  raw_ostream &O) {
937  int BankSwizzle = MI->getOperand(OpNo).getImm();
938  switch (BankSwizzle) {
939  case 1:
940  O << "BS:VEC_021/SCL_122";
941  break;
942  case 2:
943  O << "BS:VEC_120/SCL_212";
944  break;
945  case 3:
946  O << "BS:VEC_102/SCL_221";
947  break;
948  case 4:
949  O << "BS:VEC_201";
950  break;
951  case 5:
952  O << "BS:VEC_210";
953  break;
954  default:
955  break;
956  }
957 }
958 
959 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
960  const MCSubtargetInfo &STI, raw_ostream &O) {
961  unsigned Sel = MI->getOperand(OpNo).getImm();
962  switch (Sel) {
963  case 0:
964  O << 'X';
965  break;
966  case 1:
967  O << 'Y';
968  break;
969  case 2:
970  O << 'Z';
971  break;
972  case 3:
973  O << 'W';
974  break;
975  case 4:
976  O << '0';
977  break;
978  case 5:
979  O << '1';
980  break;
981  case 7:
982  O << '_';
983  break;
984  default:
985  break;
986  }
987 }
988 
989 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
990  const MCSubtargetInfo &STI, raw_ostream &O) {
991  unsigned CT = MI->getOperand(OpNo).getImm();
992  switch (CT) {
993  case 0:
994  O << 'U';
995  break;
996  case 1:
997  O << 'N';
998  break;
999  default:
1000  break;
1001  }
1002 }
1003 
1004 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
1005  const MCSubtargetInfo &STI, raw_ostream &O) {
1006  int KCacheMode = MI->getOperand(OpNo).getImm();
1007  if (KCacheMode > 0) {
1008  int KCacheBank = MI->getOperand(OpNo - 2).getImm();
1009  O << "CB" << KCacheBank << ':';
1010  int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
1011  int LineSize = (KCacheMode == 1) ? 16 : 32;
1012  O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
1013  }
1014 }
1015 
1016 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1017  const MCSubtargetInfo &STI,
1018  raw_ostream &O) {
1019  using namespace llvm::AMDGPU::SendMsg;
1020 
1021  const unsigned SImm16 = MI->getOperand(OpNo).getImm();
1022  const unsigned Id = SImm16 & ID_MASK_;
1023  do {
1024  if (Id == ID_INTERRUPT) {
1025  if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0.
1026  break;
1027  O << "sendmsg(" << IdSymbolic[Id] << ')';
1028  return;
1029  }
1030  if (Id == ID_GS || Id == ID_GS_DONE) {
1031  if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0.
1032  break;
1033  const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_;
1034  const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
1035  if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only.
1036  break;
1037  if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits.
1038  break;
1039  O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs];
1040  if (OpGs != OP_GS_NOP) { O << ", " << StreamId; }
1041  O << ')';
1042  return;
1043  }
1044  if (Id == ID_SYSMSG) {
1045  if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0.
1046  break;
1047  const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_;
1048  if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown.
1049  break;
1050  O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')';
1051  return;
1052  }
1053  } while (false);
1054  O << SImm16; // Unknown simm16 code.
1055 }
1056 
1057 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1058  const MCSubtargetInfo &STI,
1059  raw_ostream &O) {
1061 
1062  unsigned SImm16 = MI->getOperand(OpNo).getImm();
1063  unsigned Vmcnt, Expcnt, Lgkmcnt;
1064  decodeWaitcnt(IV, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1065 
1066  bool NeedSpace = false;
1067 
1068  if (Vmcnt != getVmcntBitMask(IV)) {
1069  O << "vmcnt(" << Vmcnt << ')';
1070  NeedSpace = true;
1071  }
1072 
1073  if (Expcnt != getExpcntBitMask(IV)) {
1074  if (NeedSpace)
1075  O << ' ';
1076  O << "expcnt(" << Expcnt << ')';
1077  NeedSpace = true;
1078  }
1079 
1080  if (Lgkmcnt != getLgkmcntBitMask(IV)) {
1081  if (NeedSpace)
1082  O << ' ';
1083  O << "lgkmcnt(" << Lgkmcnt << ')';
1084  }
1085 }
1086 
1087 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1088  const MCSubtargetInfo &STI, raw_ostream &O) {
1089  using namespace llvm::AMDGPU::Hwreg;
1090 
1091  unsigned SImm16 = MI->getOperand(OpNo).getImm();
1092  const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_;
1093  const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_;
1094  const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1;
1095 
1096  O << "hwreg(";
1097  if (ID_SYMBOLIC_FIRST_ <= Id && Id < ID_SYMBOLIC_LAST_) {
1098  O << IdSymbolic[Id];
1099  } else {
1100  O << Id;
1101  }
1102  if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) {
1103  O << ", " << Offset << ", " << Width;
1104  }
1105  O << ')';
1106 }
1107 
1108 #include "AMDGPUGenAsmWriter.inc"
unsigned getExpcntBitMask(IsaVersion Version)
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:315
double getFPImm() const
Definition: MCInst.h:83
bool isReg() const
Definition: MCInst.h:56
unsigned getVmcntBitMask(IsaVersion Version)
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:163
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
float BitsToFloat(uint32_t Bits)
BitsToFloat - This function takes a 32-bit integer and returns the bit equivalent float...
Definition: MathExtras.h:558
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:271
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
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:34
uint8_t OperandType
Information about the type of the operand.
Definition: MCInstrDesc.h:82
static std::string getRegisterName(const TargetRegisterInfo *TRI, unsigned Reg)
Definition: MIParser.cpp:785
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:63
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
uint32_t FloatToBits(float Float)
FloatToBits - This function takes a float and returns the bit equivalent 32-bit integer.
Definition: MathExtras.h:580
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isImm() const
Definition: MCInst.h:57
const MCExpr * getExpr() const
Definition: MCInst.h:93
unsigned const MachineRegisterInfo * MRI
IsaVersion getIsaVersion(const FeatureBitset &Features)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
const char *const IdSymbolic[]
bool isFPImm() const
Definition: MCInst.h:58
bool isExpr() const
Definition: MCInst.h:59
const char *const IdSymbolic[]
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Operands with register or inline constant.
Definition: SIDefines.h:99
unsigned getLgkmcntBitMask(IsaVersion Version)
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
void decodeWaitcnt(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...
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
uint64_t DoubleToBits(double Double)
DoubleToBits - This function takes a double and returns the bit equivalent 64-bit integer...
Definition: MathExtras.h:569
unsigned getOpcode() const
Definition: MCInst.h:159
const char *const OpSysSymbolic[]
int64_t getImm() const
Definition: MCInst.h:74
const char *const OpGsSymbolic[]
Provides AMDGPU specific target descriptions.
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:76
unsigned getNumOperands() const
Definition: MCInst.h:166
#define N
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
MCSubtargetInfo - Generic base class for all target subtargets.
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:312
Operands with register or 32-bit immediate.
Definition: SIDefines.h:91
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:33
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:174
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:164