xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/R600InstPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 #include "llvm/Support/CommandLine.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     Op.getExpr()->print(O << '@', &MAI);
103   }
104 }
105 
printNeg(const MCInst * MI,unsigned OpNo,raw_ostream & O)106 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
107                                raw_ostream &O) {
108   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
109 }
110 
printOMOD(const MCInst * MI,unsigned OpNo,raw_ostream & O)111 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
112                                 raw_ostream &O) {
113   switch (MI->getOperand(OpNo).getImm()) {
114   default:
115     break;
116   case 1:
117     O << " * 2.0";
118     break;
119   case 2:
120     O << " * 4.0";
121     break;
122   case 3:
123     O << " / 2.0";
124     break;
125   }
126 }
127 
printMemOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)128 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
129                                       raw_ostream &O) {
130   printOperand(MI, OpNo, O);
131   O << ", ";
132   printOperand(MI, OpNo + 1, O);
133 }
134 
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)135 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
136                                    raw_ostream &O) {
137   if (OpNo >= MI->getNumOperands()) {
138     O << "/*Missing OP" << OpNo << "*/";
139     return;
140   }
141 
142   const MCOperand &Op = MI->getOperand(OpNo);
143   if (Op.isReg()) {
144     switch (Op.getReg()) {
145     // This is the default predicate state, so we don't need to print it.
146     case R600::PRED_SEL_OFF:
147       break;
148 
149     default:
150       O << getRegisterName(Op.getReg());
151       break;
152     }
153   } else if (Op.isImm()) {
154     O << Op.getImm();
155   } else if (Op.isDFPImm()) {
156     // We special case 0.0 because otherwise it will be printed as an integer.
157     if (Op.getDFPImm() == 0.0)
158       O << "0.0";
159     else {
160       O << bit_cast<double>(Op.getDFPImm());
161     }
162   } else if (Op.isExpr()) {
163     const MCExpr *Exp = Op.getExpr();
164     Exp->print(O, &MAI);
165   } else {
166     O << "/*INV_OP*/";
167   }
168 }
169 
printRel(const MCInst * MI,unsigned OpNo,raw_ostream & O)170 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
171                                raw_ostream &O) {
172   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
173 }
174 
printRSel(const MCInst * MI,unsigned OpNo,raw_ostream & O)175 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
176                                 raw_ostream &O) {
177   unsigned Sel = MI->getOperand(OpNo).getImm();
178   switch (Sel) {
179   case 0:
180     O << 'X';
181     break;
182   case 1:
183     O << 'Y';
184     break;
185   case 2:
186     O << 'Z';
187     break;
188   case 3:
189     O << 'W';
190     break;
191   case 4:
192     O << '0';
193     break;
194   case 5:
195     O << '1';
196     break;
197   case 7:
198     O << '_';
199     break;
200   default:
201     break;
202   }
203 }
204 
printUpdateExecMask(const MCInst * MI,unsigned OpNo,raw_ostream & O)205 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
206                                           raw_ostream &O) {
207   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
208 }
209 
printUpdatePred(const MCInst * MI,unsigned OpNo,raw_ostream & O)210 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
211                                       raw_ostream &O) {
212   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
213 }
214 
printWrite(const MCInst * MI,unsigned OpNo,raw_ostream & O)215 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
216                                  raw_ostream &O) {
217   const MCOperand &Op = MI->getOperand(OpNo);
218   if (Op.getImm() == 0) {
219     O << " (MASKED)";
220   }
221 }
222 
223 #include "R600GenAsmWriter.inc"
224