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