LLVM 19.0.0git
R600InstPrinter.cpp
Go to the documentation of this file.
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"
18
19using namespace llvm;
20
22 StringRef Annot, const MCSubtargetInfo &STI,
23 raw_ostream &O) {
24 O.flush();
26 printAnnotation(O, Annot);
27}
28
29void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
30 raw_ostream &O) {
31 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
32}
33
34void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
35 raw_ostream &O) {
36 int BankSwizzle = MI->getOperand(OpNo).getImm();
37 switch (BankSwizzle) {
38 case 1:
39 O << "BS:VEC_021/SCL_122";
40 break;
41 case 2:
42 O << "BS:VEC_120/SCL_212";
43 break;
44 case 3:
45 O << "BS:VEC_102/SCL_221";
46 break;
47 case 4:
48 O << "BS:VEC_201";
49 break;
50 case 5:
51 O << "BS:VEC_210";
52 break;
53 default:
54 break;
55 }
56}
57
58void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
59 raw_ostream &O) {
60 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
61}
62
63void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
64 unsigned CT = MI->getOperand(OpNo).getImm();
65 switch (CT) {
66 case 0:
67 O << 'U';
68 break;
69 case 1:
70 O << 'N';
71 break;
72 default:
73 break;
74 }
75}
76
77void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
78 raw_ostream &O) {
79 int KCacheMode = MI->getOperand(OpNo).getImm();
80 if (KCacheMode > 0) {
81 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
82 O << "CB" << KCacheBank << ':';
83 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
84 int LineSize = (KCacheMode == 1) ? 16 : 32;
85 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
86 }
87}
88
89void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
90 raw_ostream &O) {
91 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
92}
93
94void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
95 raw_ostream &O) {
96 const MCOperand &Op = MI->getOperand(OpNo);
97 assert(Op.isImm() || Op.isExpr());
98 if (Op.isImm()) {
99 int64_t Imm = Op.getImm();
100 O << Imm << '(' << llvm::bit_cast<float>(static_cast<uint32_t>(Imm)) << ')';
101 }
102 if (Op.isExpr()) {
103 Op.getExpr()->print(O << '@', &MAI);
104 }
105}
106
107void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
108 raw_ostream &O) {
109 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
110}
111
112void 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
129void 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
136void 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()) {
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 Exp->print(O, &MAI);
166 } else {
167 O << "/*INV_OP*/";
168 }
169}
170
171void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
172 raw_ostream &O) {
173 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
174}
175
176void 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
207 raw_ostream &O) {
208 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
209}
210
211void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
212 raw_ostream &O) {
213 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
214}
215
216void 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"
IRTranslator LLVM IR MI
Provides R600 specific target descriptions.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O, StringRef Asm, StringRef Default="")
This class represents an Operation in the Expression.
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:51
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
Generic base class for all target subtargets.
static const char * getRegisterName(MCRegister Reg)
void printAbs(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printClamp(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printUpdateExecMask(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printRel(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printRSel(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printNeg(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printOMOD(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printUpdatePred(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printLiteral(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
void printWrite(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
void printMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printLast(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printKCache(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printBankSwizzle(const MCInst *MI, unsigned OpNo, raw_ostream &O)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18