AMDGPUInstPrinter.cpp revision 249423
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 "llvm/MC/MCInst.h"
14#include "llvm/MC/MCExpr.h"
15
16using namespace llvm;
17
18void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
19                             StringRef Annot) {
20  printInstruction(MI, OS);
21
22  printAnnotation(OS, Annot);
23}
24
25void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
26                                     raw_ostream &O) {
27
28  const MCOperand &Op = MI->getOperand(OpNo);
29  if (Op.isReg()) {
30    switch (Op.getReg()) {
31    // This is the default predicate state, so we don't need to print it.
32    case AMDGPU::PRED_SEL_OFF: break;
33    default: O << getRegisterName(Op.getReg()); break;
34    }
35  } else if (Op.isImm()) {
36    O << Op.getImm();
37  } else if (Op.isFPImm()) {
38    O << Op.getFPImm();
39  } else if (Op.isExpr()) {
40    const MCExpr *Exp = Op.getExpr();
41    Exp->print(O);
42  } else {
43    assert(!"unknown operand type in printOperand");
44  }
45}
46
47void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
48                                        raw_ostream &O) {
49  unsigned Imm = MI->getOperand(OpNum).getImm();
50
51  if (Imm == 2) {
52    O << "P0";
53  } else if (Imm == 1) {
54    O << "P20";
55  } else if (Imm == 0) {
56    O << "P10";
57  } else {
58    assert(!"Invalid interpolation parameter slot");
59  }
60}
61
62void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
63                                        raw_ostream &O) {
64  printOperand(MI, OpNo, O);
65  O  << ", ";
66  printOperand(MI, OpNo + 1, O);
67}
68
69void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
70                                    raw_ostream &O, StringRef Asm) {
71  const MCOperand &Op = MI->getOperand(OpNo);
72  assert(Op.isImm());
73  if (Op.getImm() == 1) {
74    O << Asm;
75  }
76}
77
78void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
79                                 raw_ostream &O) {
80  printIfSet(MI, OpNo, O, "|");
81}
82
83void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
84                                   raw_ostream &O) {
85  printIfSet(MI, OpNo, O, "_SAT");
86}
87
88void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
89                                     raw_ostream &O) {
90  union Literal {
91    float f;
92    int32_t i;
93  } L;
94
95  L.i = MI->getOperand(OpNo).getImm();
96  O << L.i << "(" << L.f << ")";
97}
98
99void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
100                                  raw_ostream &O) {
101  printIfSet(MI, OpNo, O, " *");
102}
103
104void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
105                                 raw_ostream &O) {
106  printIfSet(MI, OpNo, O, "-");
107}
108
109void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
110                                  raw_ostream &O) {
111  switch (MI->getOperand(OpNo).getImm()) {
112  default: break;
113  case 1:
114    O << " * 2.0";
115    break;
116  case 2:
117    O << " * 4.0";
118    break;
119  case 3:
120    O << " / 2.0";
121    break;
122  }
123}
124
125void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
126                                 raw_ostream &O) {
127  printIfSet(MI, OpNo, O, "+");
128}
129
130void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
131                                            raw_ostream &O) {
132  printIfSet(MI, OpNo, O, "ExecMask,");
133}
134
135void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
136                                        raw_ostream &O) {
137  printIfSet(MI, OpNo, O, "Pred,");
138}
139
140void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
141                                       raw_ostream &O) {
142  const MCOperand &Op = MI->getOperand(OpNo);
143  if (Op.getImm() == 0) {
144    O << " (MASKED)";
145  }
146}
147
148void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
149                                  raw_ostream &O) {
150  const char * chans = "XYZW";
151  int sel = MI->getOperand(OpNo).getImm();
152
153  int chan = sel & 3;
154  sel >>= 2;
155
156  if (sel >= 512) {
157    sel -= 512;
158    int cb = sel >> 12;
159    sel &= 4095;
160    O << cb << "[" << sel << "]";
161  } else if (sel >= 448) {
162    sel -= 448;
163    O << sel;
164  } else if (sel >= 0){
165    O << sel;
166  }
167
168  if (sel >= 0)
169    O << "." << chans[chan];
170}
171
172#include "AMDGPUGenAsmWriter.inc"
173