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