source: icGREP/icgrep-devel/llvm-3.6.1.src/lib/Target/R600/InstPrinter/AMDGPUInstPrinter.cpp @ 4664

Last change on this file since 4664 was 4664, checked in by cameron, 4 years ago

Upgrade LLVM to 3.6.1

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