xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/R600InstPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===-- R600InstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric // \file
8349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
9349cc55cSDimitry Andric 
10349cc55cSDimitry Andric #include "R600InstPrinter.h"
11349cc55cSDimitry Andric #include "AMDGPUInstPrinter.h"
12349cc55cSDimitry Andric #include "R600MCTargetDesc.h"
13349cc55cSDimitry Andric #include "llvm/MC/MCExpr.h"
14349cc55cSDimitry Andric #include "llvm/MC/MCInst.h"
15349cc55cSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
16349cc55cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
17349cc55cSDimitry Andric #include "llvm/Support/CommandLine.h"
18349cc55cSDimitry Andric 
19349cc55cSDimitry Andric using namespace llvm;
20349cc55cSDimitry Andric 
21349cc55cSDimitry Andric void R600InstPrinter::printInst(const MCInst *MI, uint64_t Address,
22349cc55cSDimitry Andric                                 StringRef Annot, const MCSubtargetInfo &STI,
23349cc55cSDimitry Andric                                 raw_ostream &O) {
24349cc55cSDimitry Andric   printInstruction(MI, Address, O);
25349cc55cSDimitry Andric   printAnnotation(O, Annot);
26349cc55cSDimitry Andric }
27349cc55cSDimitry Andric 
28349cc55cSDimitry Andric void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
29349cc55cSDimitry Andric                                raw_ostream &O) {
30349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
31349cc55cSDimitry Andric }
32349cc55cSDimitry Andric 
33349cc55cSDimitry Andric void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
34349cc55cSDimitry Andric                                        raw_ostream &O) {
35349cc55cSDimitry Andric   int BankSwizzle = MI->getOperand(OpNo).getImm();
36349cc55cSDimitry Andric   switch (BankSwizzle) {
37349cc55cSDimitry Andric   case 1:
38349cc55cSDimitry Andric     O << "BS:VEC_021/SCL_122";
39349cc55cSDimitry Andric     break;
40349cc55cSDimitry Andric   case 2:
41349cc55cSDimitry Andric     O << "BS:VEC_120/SCL_212";
42349cc55cSDimitry Andric     break;
43349cc55cSDimitry Andric   case 3:
44349cc55cSDimitry Andric     O << "BS:VEC_102/SCL_221";
45349cc55cSDimitry Andric     break;
46349cc55cSDimitry Andric   case 4:
47349cc55cSDimitry Andric     O << "BS:VEC_201";
48349cc55cSDimitry Andric     break;
49349cc55cSDimitry Andric   case 5:
50349cc55cSDimitry Andric     O << "BS:VEC_210";
51349cc55cSDimitry Andric     break;
52349cc55cSDimitry Andric   default:
53349cc55cSDimitry Andric     break;
54349cc55cSDimitry Andric   }
55349cc55cSDimitry Andric }
56349cc55cSDimitry Andric 
57349cc55cSDimitry Andric void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
58349cc55cSDimitry Andric                                  raw_ostream &O) {
59349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
60349cc55cSDimitry Andric }
61349cc55cSDimitry Andric 
62349cc55cSDimitry Andric void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
63349cc55cSDimitry Andric   unsigned CT = MI->getOperand(OpNo).getImm();
64349cc55cSDimitry Andric   switch (CT) {
65349cc55cSDimitry Andric   case 0:
66349cc55cSDimitry Andric     O << 'U';
67349cc55cSDimitry Andric     break;
68349cc55cSDimitry Andric   case 1:
69349cc55cSDimitry Andric     O << 'N';
70349cc55cSDimitry Andric     break;
71349cc55cSDimitry Andric   default:
72349cc55cSDimitry Andric     break;
73349cc55cSDimitry Andric   }
74349cc55cSDimitry Andric }
75349cc55cSDimitry Andric 
76349cc55cSDimitry Andric void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
77349cc55cSDimitry Andric                                   raw_ostream &O) {
78349cc55cSDimitry Andric   int KCacheMode = MI->getOperand(OpNo).getImm();
79349cc55cSDimitry Andric   if (KCacheMode > 0) {
80349cc55cSDimitry Andric     int KCacheBank = MI->getOperand(OpNo - 2).getImm();
81349cc55cSDimitry Andric     O << "CB" << KCacheBank << ':';
82349cc55cSDimitry Andric     int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
83349cc55cSDimitry Andric     int LineSize = (KCacheMode == 1) ? 16 : 32;
84349cc55cSDimitry Andric     O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
85349cc55cSDimitry Andric   }
86349cc55cSDimitry Andric }
87349cc55cSDimitry Andric 
88349cc55cSDimitry Andric void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
89349cc55cSDimitry Andric                                 raw_ostream &O) {
90349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
91349cc55cSDimitry Andric }
92349cc55cSDimitry Andric 
93349cc55cSDimitry Andric void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
94349cc55cSDimitry Andric                                    raw_ostream &O) {
95349cc55cSDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
96349cc55cSDimitry Andric   assert(Op.isImm() || Op.isExpr());
97349cc55cSDimitry Andric   if (Op.isImm()) {
98349cc55cSDimitry Andric     int64_t Imm = Op.getImm();
99*06c3fb27SDimitry Andric     O << Imm << '(' << llvm::bit_cast<float>(static_cast<uint32_t>(Imm)) << ')';
100349cc55cSDimitry Andric   }
101349cc55cSDimitry Andric   if (Op.isExpr()) {
102349cc55cSDimitry Andric     Op.getExpr()->print(O << '@', &MAI);
103349cc55cSDimitry Andric   }
104349cc55cSDimitry Andric }
105349cc55cSDimitry Andric 
106349cc55cSDimitry Andric void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
107349cc55cSDimitry Andric                                raw_ostream &O) {
108349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
109349cc55cSDimitry Andric }
110349cc55cSDimitry Andric 
111349cc55cSDimitry Andric void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
112349cc55cSDimitry Andric                                 raw_ostream &O) {
113349cc55cSDimitry Andric   switch (MI->getOperand(OpNo).getImm()) {
114349cc55cSDimitry Andric   default:
115349cc55cSDimitry Andric     break;
116349cc55cSDimitry Andric   case 1:
117349cc55cSDimitry Andric     O << " * 2.0";
118349cc55cSDimitry Andric     break;
119349cc55cSDimitry Andric   case 2:
120349cc55cSDimitry Andric     O << " * 4.0";
121349cc55cSDimitry Andric     break;
122349cc55cSDimitry Andric   case 3:
123349cc55cSDimitry Andric     O << " / 2.0";
124349cc55cSDimitry Andric     break;
125349cc55cSDimitry Andric   }
126349cc55cSDimitry Andric }
127349cc55cSDimitry Andric 
128349cc55cSDimitry Andric void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
129349cc55cSDimitry Andric                                       raw_ostream &O) {
130349cc55cSDimitry Andric   printOperand(MI, OpNo, O);
131349cc55cSDimitry Andric   O << ", ";
132349cc55cSDimitry Andric   printOperand(MI, OpNo + 1, O);
133349cc55cSDimitry Andric }
134349cc55cSDimitry Andric 
135349cc55cSDimitry Andric void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
136349cc55cSDimitry Andric                                    raw_ostream &O) {
137349cc55cSDimitry Andric   if (OpNo >= MI->getNumOperands()) {
138349cc55cSDimitry Andric     O << "/*Missing OP" << OpNo << "*/";
139349cc55cSDimitry Andric     return;
140349cc55cSDimitry Andric   }
141349cc55cSDimitry Andric 
142349cc55cSDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
143349cc55cSDimitry Andric   if (Op.isReg()) {
144349cc55cSDimitry Andric     switch (Op.getReg()) {
145349cc55cSDimitry Andric     // This is the default predicate state, so we don't need to print it.
146349cc55cSDimitry Andric     case R600::PRED_SEL_OFF:
147349cc55cSDimitry Andric       break;
148349cc55cSDimitry Andric 
149349cc55cSDimitry Andric     default:
150349cc55cSDimitry Andric       O << getRegisterName(Op.getReg());
151349cc55cSDimitry Andric       break;
152349cc55cSDimitry Andric     }
153349cc55cSDimitry Andric   } else if (Op.isImm()) {
154349cc55cSDimitry Andric     O << Op.getImm();
155349cc55cSDimitry Andric   } else if (Op.isDFPImm()) {
156349cc55cSDimitry Andric     // We special case 0.0 because otherwise it will be printed as an integer.
157349cc55cSDimitry Andric     if (Op.getDFPImm() == 0.0)
158349cc55cSDimitry Andric       O << "0.0";
159349cc55cSDimitry Andric     else {
160349cc55cSDimitry Andric       O << bit_cast<double>(Op.getDFPImm());
161349cc55cSDimitry Andric     }
162349cc55cSDimitry Andric   } else if (Op.isExpr()) {
163349cc55cSDimitry Andric     const MCExpr *Exp = Op.getExpr();
164349cc55cSDimitry Andric     Exp->print(O, &MAI);
165349cc55cSDimitry Andric   } else {
166349cc55cSDimitry Andric     O << "/*INV_OP*/";
167349cc55cSDimitry Andric   }
168349cc55cSDimitry Andric }
169349cc55cSDimitry Andric 
170349cc55cSDimitry Andric void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
171349cc55cSDimitry Andric                                raw_ostream &O) {
172349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
173349cc55cSDimitry Andric }
174349cc55cSDimitry Andric 
175349cc55cSDimitry Andric void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
176349cc55cSDimitry Andric                                 raw_ostream &O) {
177349cc55cSDimitry Andric   unsigned Sel = MI->getOperand(OpNo).getImm();
178349cc55cSDimitry Andric   switch (Sel) {
179349cc55cSDimitry Andric   case 0:
180349cc55cSDimitry Andric     O << 'X';
181349cc55cSDimitry Andric     break;
182349cc55cSDimitry Andric   case 1:
183349cc55cSDimitry Andric     O << 'Y';
184349cc55cSDimitry Andric     break;
185349cc55cSDimitry Andric   case 2:
186349cc55cSDimitry Andric     O << 'Z';
187349cc55cSDimitry Andric     break;
188349cc55cSDimitry Andric   case 3:
189349cc55cSDimitry Andric     O << 'W';
190349cc55cSDimitry Andric     break;
191349cc55cSDimitry Andric   case 4:
192349cc55cSDimitry Andric     O << '0';
193349cc55cSDimitry Andric     break;
194349cc55cSDimitry Andric   case 5:
195349cc55cSDimitry Andric     O << '1';
196349cc55cSDimitry Andric     break;
197349cc55cSDimitry Andric   case 7:
198349cc55cSDimitry Andric     O << '_';
199349cc55cSDimitry Andric     break;
200349cc55cSDimitry Andric   default:
201349cc55cSDimitry Andric     break;
202349cc55cSDimitry Andric   }
203349cc55cSDimitry Andric }
204349cc55cSDimitry Andric 
205349cc55cSDimitry Andric void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
206349cc55cSDimitry Andric                                           raw_ostream &O) {
207349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
208349cc55cSDimitry Andric }
209349cc55cSDimitry Andric 
210349cc55cSDimitry Andric void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
211349cc55cSDimitry Andric                                       raw_ostream &O) {
212349cc55cSDimitry Andric   AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
213349cc55cSDimitry Andric }
214349cc55cSDimitry Andric 
215349cc55cSDimitry Andric void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
216349cc55cSDimitry Andric                                  raw_ostream &O) {
217349cc55cSDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
218349cc55cSDimitry Andric   if (Op.getImm() == 0) {
219349cc55cSDimitry Andric     O << " (MASKED)";
220349cc55cSDimitry Andric   }
221349cc55cSDimitry Andric }
222349cc55cSDimitry Andric 
223349cc55cSDimitry Andric #include "R600GenAsmWriter.inc"
224