xref: /llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/R600InstPrinter.cpp (revision be187369a03bf2df8bdbc76ecd381377b3bb6074)
1 //===-- R600InstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 // \file
8 //===----------------------------------------------------------------------===//
9 
10 #include "R600InstPrinter.h"
11 #include "AMDGPUInstPrinter.h"
12 #include "R600MCTargetDesc.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCInstrInfo.h"
16 #include "llvm/MC/MCSubtargetInfo.h"
17 
18 using namespace llvm;
19 
20 void R600InstPrinter::printInst(const MCInst *MI, uint64_t Address,
21                                 StringRef Annot, const MCSubtargetInfo &STI,
22                                 raw_ostream &O) {
23   printInstruction(MI, Address, O);
24   printAnnotation(O, Annot);
25 }
26 
27 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
28                                raw_ostream &O) {
29   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
30 }
31 
32 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
33                                        raw_ostream &O) {
34   int BankSwizzle = MI->getOperand(OpNo).getImm();
35   switch (BankSwizzle) {
36   case 1:
37     O << "BS:VEC_021/SCL_122";
38     break;
39   case 2:
40     O << "BS:VEC_120/SCL_212";
41     break;
42   case 3:
43     O << "BS:VEC_102/SCL_221";
44     break;
45   case 4:
46     O << "BS:VEC_201";
47     break;
48   case 5:
49     O << "BS:VEC_210";
50     break;
51   default:
52     break;
53   }
54 }
55 
56 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
57                                  raw_ostream &O) {
58   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
59 }
60 
61 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
62   unsigned CT = MI->getOperand(OpNo).getImm();
63   switch (CT) {
64   case 0:
65     O << 'U';
66     break;
67   case 1:
68     O << 'N';
69     break;
70   default:
71     break;
72   }
73 }
74 
75 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
76                                   raw_ostream &O) {
77   int KCacheMode = MI->getOperand(OpNo).getImm();
78   if (KCacheMode > 0) {
79     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
80     O << "CB" << KCacheBank << ':';
81     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
82     int LineSize = (KCacheMode == 1) ? 16 : 32;
83     O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
84   }
85 }
86 
87 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
88                                 raw_ostream &O) {
89   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
90 }
91 
92 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
93                                    raw_ostream &O) {
94   const MCOperand &Op = MI->getOperand(OpNo);
95   assert(Op.isImm() || Op.isExpr());
96   if (Op.isImm()) {
97     int64_t Imm = Op.getImm();
98     O << Imm << '(' << llvm::bit_cast<float>(static_cast<uint32_t>(Imm)) << ')';
99   }
100   if (Op.isExpr()) {
101     Op.getExpr()->print(O << '@', &MAI);
102   }
103 }
104 
105 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
106                                raw_ostream &O) {
107   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
108 }
109 
110 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
111                                 raw_ostream &O) {
112   switch (MI->getOperand(OpNo).getImm()) {
113   default:
114     break;
115   case 1:
116     O << " * 2.0";
117     break;
118   case 2:
119     O << " * 4.0";
120     break;
121   case 3:
122     O << " / 2.0";
123     break;
124   }
125 }
126 
127 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
128                                       raw_ostream &O) {
129   printOperand(MI, OpNo, O);
130   O << ", ";
131   printOperand(MI, OpNo + 1, O);
132 }
133 
134 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
135                                    raw_ostream &O) {
136   if (OpNo >= MI->getNumOperands()) {
137     O << "/*Missing OP" << OpNo << "*/";
138     return;
139   }
140 
141   const MCOperand &Op = MI->getOperand(OpNo);
142   if (Op.isReg()) {
143     switch (Op.getReg().id()) {
144     // This is the default predicate state, so we don't need to print it.
145     case R600::PRED_SEL_OFF:
146       break;
147 
148     default:
149       O << getRegisterName(Op.getReg());
150       break;
151     }
152   } else if (Op.isImm()) {
153     O << Op.getImm();
154   } else if (Op.isDFPImm()) {
155     // We special case 0.0 because otherwise it will be printed as an integer.
156     if (Op.getDFPImm() == 0.0)
157       O << "0.0";
158     else {
159       O << bit_cast<double>(Op.getDFPImm());
160     }
161   } else if (Op.isExpr()) {
162     const MCExpr *Exp = Op.getExpr();
163     Exp->print(O, &MAI);
164   } else {
165     O << "/*INV_OP*/";
166   }
167 }
168 
169 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
170                                raw_ostream &O) {
171   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
172 }
173 
174 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
175                                 raw_ostream &O) {
176   unsigned Sel = MI->getOperand(OpNo).getImm();
177   switch (Sel) {
178   case 0:
179     O << 'X';
180     break;
181   case 1:
182     O << 'Y';
183     break;
184   case 2:
185     O << 'Z';
186     break;
187   case 3:
188     O << 'W';
189     break;
190   case 4:
191     O << '0';
192     break;
193   case 5:
194     O << '1';
195     break;
196   case 7:
197     O << '_';
198     break;
199   default:
200     break;
201   }
202 }
203 
204 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
205                                           raw_ostream &O) {
206   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
207 }
208 
209 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
210                                       raw_ostream &O) {
211   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
212 }
213 
214 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
215                                  raw_ostream &O) {
216   const MCOperand &Op = MI->getOperand(OpNo);
217   if (Op.getImm() == 0) {
218     O << " (MASKED)";
219   }
220 }
221 
222 #include "R600GenAsmWriter.inc"
223