AMDGPUInstPrinter.cpp revision 249259
1249259Sdim//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim// \file
9249259Sdim//===----------------------------------------------------------------------===//
10249259Sdim
11249259Sdim#include "AMDGPUInstPrinter.h"
12249259Sdim#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
13249259Sdim#include "llvm/MC/MCInst.h"
14249259Sdim#include "llvm/MC/MCExpr.h"
15249259Sdim
16249259Sdimusing namespace llvm;
17249259Sdim
18249259Sdimvoid AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
19249259Sdim                             StringRef Annot) {
20249259Sdim  printInstruction(MI, OS);
21249259Sdim
22249259Sdim  printAnnotation(OS, Annot);
23249259Sdim}
24249259Sdim
25249259Sdimvoid AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
26249259Sdim                                     raw_ostream &O) {
27249259Sdim
28249259Sdim  const MCOperand &Op = MI->getOperand(OpNo);
29249259Sdim  if (Op.isReg()) {
30249259Sdim    switch (Op.getReg()) {
31249259Sdim    // This is the default predicate state, so we don't need to print it.
32249259Sdim    case AMDGPU::PRED_SEL_OFF: break;
33249259Sdim    default: O << getRegisterName(Op.getReg()); break;
34249259Sdim    }
35249259Sdim  } else if (Op.isImm()) {
36249259Sdim    O << Op.getImm();
37249259Sdim  } else if (Op.isFPImm()) {
38249259Sdim    O << Op.getFPImm();
39249259Sdim  } else if (Op.isExpr()) {
40249259Sdim    const MCExpr *Exp = Op.getExpr();
41249259Sdim    Exp->print(O);
42249259Sdim  } else {
43249259Sdim    assert(!"unknown operand type in printOperand");
44249259Sdim  }
45249259Sdim}
46249259Sdim
47249259Sdimvoid AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
48249259Sdim                                        raw_ostream &O) {
49249259Sdim  unsigned Imm = MI->getOperand(OpNum).getImm();
50249259Sdim
51249259Sdim  if (Imm == 2) {
52249259Sdim    O << "P0";
53249259Sdim  } else if (Imm == 1) {
54249259Sdim    O << "P20";
55249259Sdim  } else if (Imm == 0) {
56249259Sdim    O << "P10";
57249259Sdim  } else {
58249259Sdim    assert(!"Invalid interpolation parameter slot");
59249259Sdim  }
60249259Sdim}
61249259Sdim
62249259Sdimvoid AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
63249259Sdim                                        raw_ostream &O) {
64249259Sdim  printOperand(MI, OpNo, O);
65249259Sdim  O  << ", ";
66249259Sdim  printOperand(MI, OpNo + 1, O);
67249259Sdim}
68249259Sdim
69249259Sdimvoid AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
70249259Sdim                                    raw_ostream &O, StringRef Asm) {
71249259Sdim  const MCOperand &Op = MI->getOperand(OpNo);
72249259Sdim  assert(Op.isImm());
73249259Sdim  if (Op.getImm() == 1) {
74249259Sdim    O << Asm;
75249259Sdim  }
76249259Sdim}
77249259Sdim
78249259Sdimvoid AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
79249259Sdim                                 raw_ostream &O) {
80249259Sdim  printIfSet(MI, OpNo, O, "|");
81249259Sdim}
82249259Sdim
83249259Sdimvoid AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
84249259Sdim                                   raw_ostream &O) {
85249259Sdim  printIfSet(MI, OpNo, O, "_SAT");
86249259Sdim}
87249259Sdim
88249259Sdimvoid AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
89249259Sdim                                     raw_ostream &O) {
90249259Sdim  union Literal {
91249259Sdim    float f;
92249259Sdim    int32_t i;
93249259Sdim  } L;
94249259Sdim
95249259Sdim  L.i = MI->getOperand(OpNo).getImm();
96249259Sdim  O << L.i << "(" << L.f << ")";
97249259Sdim}
98249259Sdim
99249259Sdimvoid AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
100249259Sdim                                  raw_ostream &O) {
101249259Sdim  printIfSet(MI, OpNo, O, " *");
102249259Sdim}
103249259Sdim
104249259Sdimvoid AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
105249259Sdim                                 raw_ostream &O) {
106249259Sdim  printIfSet(MI, OpNo, O, "-");
107249259Sdim}
108249259Sdim
109249259Sdimvoid AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
110249259Sdim                                  raw_ostream &O) {
111249259Sdim  switch (MI->getOperand(OpNo).getImm()) {
112249259Sdim  default: break;
113249259Sdim  case 1:
114249259Sdim    O << " * 2.0";
115249259Sdim    break;
116249259Sdim  case 2:
117249259Sdim    O << " * 4.0";
118249259Sdim    break;
119249259Sdim  case 3:
120249259Sdim    O << " / 2.0";
121249259Sdim    break;
122249259Sdim  }
123249259Sdim}
124249259Sdim
125249259Sdimvoid AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
126249259Sdim                                 raw_ostream &O) {
127249259Sdim  printIfSet(MI, OpNo, O, "+");
128249259Sdim}
129249259Sdim
130249259Sdimvoid AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
131249259Sdim                                            raw_ostream &O) {
132249259Sdim  printIfSet(MI, OpNo, O, "ExecMask,");
133249259Sdim}
134249259Sdim
135249259Sdimvoid AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
136249259Sdim                                        raw_ostream &O) {
137249259Sdim  printIfSet(MI, OpNo, O, "Pred,");
138249259Sdim}
139249259Sdim
140249259Sdimvoid AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
141249259Sdim                                       raw_ostream &O) {
142249259Sdim  const MCOperand &Op = MI->getOperand(OpNo);
143249259Sdim  if (Op.getImm() == 0) {
144249259Sdim    O << " (MASKED)";
145249259Sdim  }
146249259Sdim}
147249259Sdim
148249259Sdimvoid AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
149249259Sdim                                  raw_ostream &O) {
150249259Sdim  const char * chans = "XYZW";
151249259Sdim  int sel = MI->getOperand(OpNo).getImm();
152249259Sdim
153249259Sdim  int chan = sel & 3;
154249259Sdim  sel >>= 2;
155249259Sdim
156249259Sdim  if (sel >= 512) {
157249259Sdim    sel -= 512;
158249259Sdim    int cb = sel >> 12;
159249259Sdim    sel &= 4095;
160249259Sdim    O << cb << "[" << sel << "]";
161249259Sdim  } else if (sel >= 448) {
162249259Sdim    sel -= 448;
163249259Sdim    O << sel;
164249259Sdim  } else if (sel >= 0){
165249259Sdim    O << sel;
166249259Sdim  }
167249259Sdim
168249259Sdim  if (sel >= 0)
169249259Sdim    O << "." << chans[chan];
170249259Sdim}
171249259Sdim
172249259Sdim#include "AMDGPUGenAsmWriter.inc"
173