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