LLVM 20.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) {
25 printAnnotation(O, Annot);
26}
27
28void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
29 raw_ostream &O) {
30 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');
31}
32
33void 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
57void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
58 raw_ostream &O) {
59 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");
60}
61
62void 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
76void 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
88void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,
89 raw_ostream &O) {
90 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");
91}
92
93void 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
106void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
107 raw_ostream &O) {
108 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');
109}
110
111void 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
128void 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
135void 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
170void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,
171 raw_ostream &O) {
172 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');
173}
174
175void 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
206 raw_ostream &O) {
207 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");
208}
209
210void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
211 raw_ostream &O) {
212 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");
213}
214
215void 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"
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:34
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