]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
MFV r308265: Update tzdata to 2016i.
[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 "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCInst.h"
16 #include "llvm/MC/MCInstrInfo.h"
17 #include "llvm/MC/MCRegisterInfo.h"
18 #include "llvm/Support/MathExtras.h"
19 #include "llvm/Support/raw_ostream.h"
20
21 using namespace llvm;
22
23 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
24                                   StringRef Annot, const MCSubtargetInfo &STI) {
25   OS.flush();
26   printInstruction(MI, OS);
27
28   printAnnotation(OS, Annot);
29 }
30
31 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
32                                            raw_ostream &O) {
33   O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
34 }
35
36 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
37                                            raw_ostream &O) {
38   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffff);
39 }
40
41 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
42                                            raw_ostream &O) {
43   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
44 }
45
46 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
47                                              raw_ostream &O) {
48   O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
49 }
50
51 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
52                                               raw_ostream &O) {
53   O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
54 }
55
56 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
57                                    raw_ostream &O) {
58   if (MI->getOperand(OpNo).getImm())
59     O << " offen";
60 }
61
62 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
63                                    raw_ostream &O) {
64   if (MI->getOperand(OpNo).getImm())
65     O << " idxen";
66 }
67
68 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
69                                     raw_ostream &O) {
70   if (MI->getOperand(OpNo).getImm())
71     O << " addr64";
72 }
73
74 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
75                                         raw_ostream &O) {
76   if (MI->getOperand(OpNo).getImm()) {
77     O << " offset:";
78     printU16ImmDecOperand(MI, OpNo, O);
79   }
80 }
81
82 void AMDGPUInstPrinter::printDSOffset(const MCInst *MI, unsigned OpNo,
83                                       raw_ostream &O) {
84   uint16_t Imm = MI->getOperand(OpNo).getImm();
85   if (Imm != 0) {
86     O << " offset:";
87     printU16ImmDecOperand(MI, OpNo, O);
88   }
89 }
90
91 void AMDGPUInstPrinter::printDSOffset0(const MCInst *MI, unsigned OpNo,
92                                         raw_ostream &O) {
93   if (MI->getOperand(OpNo).getImm()) {
94     O << " offset0:";
95     printU8ImmDecOperand(MI, OpNo, O);
96   }
97 }
98
99 void AMDGPUInstPrinter::printDSOffset1(const MCInst *MI, unsigned OpNo,
100                                         raw_ostream &O) {
101   if (MI->getOperand(OpNo).getImm()) {
102     O << " offset1:";
103     printU8ImmDecOperand(MI, OpNo, O);
104   }
105 }
106
107 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
108                                  raw_ostream &O) {
109   if (MI->getOperand(OpNo).getImm())
110     O << " gds";
111 }
112
113 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
114                                  raw_ostream &O) {
115   if (MI->getOperand(OpNo).getImm())
116     O << " glc";
117 }
118
119 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
120                                  raw_ostream &O) {
121   if (MI->getOperand(OpNo).getImm())
122     O << " slc";
123 }
124
125 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
126                                  raw_ostream &O) {
127   if (MI->getOperand(OpNo).getImm())
128     O << " tfe";
129 }
130
131 void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O,
132                                         const MCRegisterInfo &MRI) {
133   switch (reg) {
134   case AMDGPU::VCC:
135     O << "vcc";
136     return;
137   case AMDGPU::SCC:
138     O << "scc";
139     return;
140   case AMDGPU::EXEC:
141     O << "exec";
142     return;
143   case AMDGPU::M0:
144     O << "m0";
145     return;
146   case AMDGPU::FLAT_SCR:
147     O << "flat_scratch";
148     return;
149   case AMDGPU::VCC_LO:
150     O << "vcc_lo";
151     return;
152   case AMDGPU::VCC_HI:
153     O << "vcc_hi";
154     return;
155   case AMDGPU::EXEC_LO:
156     O << "exec_lo";
157     return;
158   case AMDGPU::EXEC_HI:
159     O << "exec_hi";
160     return;
161   case AMDGPU::FLAT_SCR_LO:
162     O << "flat_scratch_lo";
163     return;
164   case AMDGPU::FLAT_SCR_HI:
165     O << "flat_scratch_hi";
166     return;
167   default:
168     break;
169   }
170
171   char Type;
172   unsigned NumRegs;
173
174   if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) {
175     Type = 'v';
176     NumRegs = 1;
177   } else  if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) {
178     Type = 's';
179     NumRegs = 1;
180   } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) {
181     Type = 'v';
182     NumRegs = 2;
183   } else  if (MRI.getRegClass(AMDGPU::SReg_64RegClassID).contains(reg)) {
184     Type = 's';
185     NumRegs = 2;
186   } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) {
187     Type = 'v';
188     NumRegs = 4;
189   } else  if (MRI.getRegClass(AMDGPU::SReg_128RegClassID).contains(reg)) {
190     Type = 's';
191     NumRegs = 4;
192   } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) {
193     Type = 'v';
194     NumRegs = 3;
195   } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) {
196     Type = 'v';
197     NumRegs = 8;
198   } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) {
199     Type = 's';
200     NumRegs = 8;
201   } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) {
202     Type = 'v';
203     NumRegs = 16;
204   } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) {
205     Type = 's';
206     NumRegs = 16;
207   } else {
208     O << getRegisterName(reg);
209     return;
210   }
211
212   // The low 8 bits of the encoding value is the register index, for both VGPRs
213   // and SGPRs.
214   unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1);
215   if (NumRegs == 1) {
216     O << Type << RegIdx;
217     return;
218   }
219
220   O << Type << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
221 }
222
223 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
224                                     raw_ostream &O) {
225   if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
226     O << "_e64 ";
227   else
228     O << "_e32 ";
229
230   printOperand(MI, OpNo, O);
231 }
232
233 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, raw_ostream &O) {
234   int32_t SImm = static_cast<int32_t>(Imm);
235   if (SImm >= -16 && SImm <= 64) {
236     O << SImm;
237     return;
238   }
239
240   if (Imm == FloatToBits(0.0f))
241     O << "0.0";
242   else if (Imm == FloatToBits(1.0f))
243     O << "1.0";
244   else if (Imm == FloatToBits(-1.0f))
245     O << "-1.0";
246   else if (Imm == FloatToBits(0.5f))
247     O << "0.5";
248   else if (Imm == FloatToBits(-0.5f))
249     O << "-0.5";
250   else if (Imm == FloatToBits(2.0f))
251     O << "2.0";
252   else if (Imm == FloatToBits(-2.0f))
253     O << "-2.0";
254   else if (Imm == FloatToBits(4.0f))
255     O << "4.0";
256   else if (Imm == FloatToBits(-4.0f))
257     O << "-4.0";
258   else
259     O << formatHex(static_cast<uint64_t>(Imm));
260 }
261
262 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) {
263   int64_t SImm = static_cast<int64_t>(Imm);
264   if (SImm >= -16 && SImm <= 64) {
265     O << SImm;
266     return;
267   }
268
269   if (Imm == DoubleToBits(0.0))
270     O << "0.0";
271   else if (Imm == DoubleToBits(1.0))
272     O << "1.0";
273   else if (Imm == DoubleToBits(-1.0))
274     O << "-1.0";
275   else if (Imm == DoubleToBits(0.5))
276     O << "0.5";
277   else if (Imm == DoubleToBits(-0.5))
278     O << "-0.5";
279   else if (Imm == DoubleToBits(2.0))
280     O << "2.0";
281   else if (Imm == DoubleToBits(-2.0))
282     O << "-2.0";
283   else if (Imm == DoubleToBits(4.0))
284     O << "4.0";
285   else if (Imm == DoubleToBits(-4.0))
286     O << "-4.0";
287   else {
288     assert(isUInt<32>(Imm));
289
290     // In rare situations, we will have a 32-bit literal in a 64-bit
291     // operand. This is technically allowed for the encoding of s_mov_b64.
292     O << formatHex(static_cast<uint64_t>(Imm));
293   }
294 }
295
296 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
297                                      raw_ostream &O) {
298
299   const MCOperand &Op = MI->getOperand(OpNo);
300   if (Op.isReg()) {
301     switch (Op.getReg()) {
302     // This is the default predicate state, so we don't need to print it.
303     case AMDGPU::PRED_SEL_OFF:
304       break;
305
306     default:
307       printRegOperand(Op.getReg(), O, MRI);
308       break;
309     }
310   } else if (Op.isImm()) {
311     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
312     int RCID = Desc.OpInfo[OpNo].RegClass;
313     if (RCID != -1) {
314       const MCRegisterClass &ImmRC = MRI.getRegClass(RCID);
315       if (ImmRC.getSize() == 4)
316         printImmediate32(Op.getImm(), O);
317       else if (ImmRC.getSize() == 8)
318         printImmediate64(Op.getImm(), O);
319       else
320         llvm_unreachable("Invalid register class size");
321     } else if (Desc.OpInfo[OpNo].OperandType == MCOI::OPERAND_IMMEDIATE) {
322       printImmediate32(Op.getImm(), O);
323     } else {
324       // We hit this for the immediate instruction bits that don't yet have a
325       // custom printer.
326       // TODO: Eventually this should be unnecessary.
327       O << formatDec(Op.getImm());
328     }
329   } else if (Op.isFPImm()) {
330     // We special case 0.0 because otherwise it will be printed as an integer.
331     if (Op.getFPImm() == 0.0)
332       O << "0.0";
333     else {
334       const MCInstrDesc &Desc = MII.get(MI->getOpcode());
335       const MCRegisterClass &ImmRC = MRI.getRegClass(Desc.OpInfo[OpNo].RegClass);
336
337       if (ImmRC.getSize() == 4)
338         printImmediate32(FloatToBits(Op.getFPImm()), O);
339       else if (ImmRC.getSize() == 8)
340         printImmediate64(DoubleToBits(Op.getFPImm()), O);
341       else
342         llvm_unreachable("Invalid register class size");
343     }
344   } else if (Op.isExpr()) {
345     const MCExpr *Exp = Op.getExpr();
346     Exp->print(O, &MAI);
347   } else {
348     llvm_unreachable("unknown operand type in printOperand");
349   }
350 }
351
352 void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
353                                             raw_ostream &O) {
354   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
355   if (InputModifiers & SISrcMods::NEG)
356     O << '-';
357   if (InputModifiers & SISrcMods::ABS)
358     O << '|';
359   printOperand(MI, OpNo + 1, O);
360   if (InputModifiers & SISrcMods::ABS)
361     O << '|';
362 }
363
364 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
365                                         raw_ostream &O) {
366   unsigned Imm = MI->getOperand(OpNum).getImm();
367
368   if (Imm == 2) {
369     O << "P0";
370   } else if (Imm == 1) {
371     O << "P20";
372   } else if (Imm == 0) {
373     O << "P10";
374   } else {
375     llvm_unreachable("Invalid interpolation parameter slot");
376   }
377 }
378
379 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
380                                         raw_ostream &O) {
381   printOperand(MI, OpNo, O);
382   O  << ", ";
383   printOperand(MI, OpNo + 1, O);
384 }
385
386 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
387                                    raw_ostream &O, StringRef Asm,
388                                    StringRef Default) {
389   const MCOperand &Op = MI->getOperand(OpNo);
390   assert(Op.isImm());
391   if (Op.getImm() == 1) {
392     O << Asm;
393   } else {
394     O << Default;
395   }
396 }
397
398 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
399                                  raw_ostream &O) {
400   printIfSet(MI, OpNo, O, "|");
401 }
402
403 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
404                                    raw_ostream &O) {
405   printIfSet(MI, OpNo, O, "_SAT");
406 }
407
408 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
409                                      raw_ostream &O) {
410   if (MI->getOperand(OpNo).getImm())
411     O << " clamp";
412 }
413
414 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
415                                      raw_ostream &O) {
416   int Imm = MI->getOperand(OpNo).getImm();
417   if (Imm == SIOutMods::MUL2)
418     O << " mul:2";
419   else if (Imm == SIOutMods::MUL4)
420     O << " mul:4";
421   else if (Imm == SIOutMods::DIV2)
422     O << " div:2";
423 }
424
425 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
426                                      raw_ostream &O) {
427   int32_t Imm = MI->getOperand(OpNo).getImm();
428   O << Imm << '(' << BitsToFloat(Imm) << ')';
429 }
430
431 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
432                                   raw_ostream &O) {
433   printIfSet(MI, OpNo, O, "*", " ");
434 }
435
436 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
437                                  raw_ostream &O) {
438   printIfSet(MI, OpNo, O, "-");
439 }
440
441 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
442                                   raw_ostream &O) {
443   switch (MI->getOperand(OpNo).getImm()) {
444   default: break;
445   case 1:
446     O << " * 2.0";
447     break;
448   case 2:
449     O << " * 4.0";
450     break;
451   case 3:
452     O << " / 2.0";
453     break;
454   }
455 }
456
457 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
458                                  raw_ostream &O) {
459   printIfSet(MI, OpNo, O, "+");
460 }
461
462 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
463                                             raw_ostream &O) {
464   printIfSet(MI, OpNo, O, "ExecMask,");
465 }
466
467 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
468                                         raw_ostream &O) {
469   printIfSet(MI, OpNo, O, "Pred,");
470 }
471
472 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
473                                        raw_ostream &O) {
474   const MCOperand &Op = MI->getOperand(OpNo);
475   if (Op.getImm() == 0) {
476     O << " (MASKED)";
477   }
478 }
479
480 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
481                                   raw_ostream &O) {
482   const char * chans = "XYZW";
483   int sel = MI->getOperand(OpNo).getImm();
484
485   int chan = sel & 3;
486   sel >>= 2;
487
488   if (sel >= 512) {
489     sel -= 512;
490     int cb = sel >> 12;
491     sel &= 4095;
492     O << cb << '[' << sel << ']';
493   } else if (sel >= 448) {
494     sel -= 448;
495     O << sel;
496   } else if (sel >= 0){
497     O << sel;
498   }
499
500   if (sel >= 0)
501     O << '.' << chans[chan];
502 }
503
504 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
505                                          raw_ostream &O) {
506   int BankSwizzle = MI->getOperand(OpNo).getImm();
507   switch (BankSwizzle) {
508   case 1:
509     O << "BS:VEC_021/SCL_122";
510     break;
511   case 2:
512     O << "BS:VEC_120/SCL_212";
513     break;
514   case 3:
515     O << "BS:VEC_102/SCL_221";
516     break;
517   case 4:
518     O << "BS:VEC_201";
519     break;
520   case 5:
521     O << "BS:VEC_210";
522     break;
523   default:
524     break;
525   }
526   return;
527 }
528
529 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
530                                   raw_ostream &O) {
531   unsigned Sel = MI->getOperand(OpNo).getImm();
532   switch (Sel) {
533   case 0:
534     O << 'X';
535     break;
536   case 1:
537     O << 'Y';
538     break;
539   case 2:
540     O << 'Z';
541     break;
542   case 3:
543     O << 'W';
544     break;
545   case 4:
546     O << '0';
547     break;
548   case 5:
549     O << '1';
550     break;
551   case 7:
552     O << '_';
553     break;
554   default:
555     break;
556   }
557 }
558
559 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
560                                   raw_ostream &O) {
561   unsigned CT = MI->getOperand(OpNo).getImm();
562   switch (CT) {
563   case 0:
564     O << 'U';
565     break;
566   case 1:
567     O << 'N';
568     break;
569   default:
570     break;
571   }
572 }
573
574 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
575                                     raw_ostream &O) {
576   int KCacheMode = MI->getOperand(OpNo).getImm();
577   if (KCacheMode > 0) {
578     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
579     O << "CB" << KCacheBank << ':';
580     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
581     int LineSize = (KCacheMode == 1) ? 16 : 32;
582     O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
583   }
584 }
585
586 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
587                                      raw_ostream &O) {
588   unsigned SImm16 = MI->getOperand(OpNo).getImm();
589   unsigned Msg = SImm16 & 0xF;
590   if (Msg == 2 || Msg == 3) {
591     unsigned Op = (SImm16 >> 4) & 0xF;
592     if (Msg == 3)
593       O << "Gs_done(";
594     else
595       O << "Gs(";
596     if (Op == 0) {
597       O << "nop";
598     } else {
599       unsigned Stream = (SImm16 >> 8) & 0x3;
600       if (Op == 1)
601         O << "cut";
602       else if (Op == 2)
603         O << "emit";
604       else if (Op == 3)
605         O << "emit-cut";
606       O << " stream " << Stream;
607     }
608     O << "), [m0] ";
609   } else if (Msg == 1)
610     O << "interrupt ";
611   else if (Msg == 15)
612     O << "system ";
613   else
614     O << "unknown(" << Msg << ") ";
615 }
616
617 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
618                                       raw_ostream &O) {
619   // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
620   // SIInsertWaits.cpp bits usage does not match ISA docs description but it
621   // works so it might be a misprint in docs.
622   unsigned SImm16 = MI->getOperand(OpNo).getImm();
623   unsigned Vmcnt = SImm16 & 0xF;
624   unsigned Expcnt = (SImm16 >> 4) & 0xF;
625   unsigned Lgkmcnt = (SImm16 >> 8) & 0xF;
626
627   bool NeedSpace = false;
628
629   if (Vmcnt != 0xF) {
630     O << "vmcnt(" << Vmcnt << ')';
631     NeedSpace = true;
632   }
633
634   if (Expcnt != 0x7) {
635     if (NeedSpace)
636       O << ' ';
637     O << "expcnt(" << Expcnt << ')';
638     NeedSpace = true;
639   }
640
641   if (Lgkmcnt != 0x7) {
642     if (NeedSpace)
643       O << ' ';
644     O << "lgkmcnt(" << Lgkmcnt << ')';
645   }
646 }
647
648 #include "AMDGPUGenAsmWriter.inc"