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