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