1c0bd7bd4SRichard Trieu //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
2c0bd7bd4SRichard Trieu //
3c0bd7bd4SRichard Trieu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c0bd7bd4SRichard Trieu // See https://llvm.org/LICENSE.txt for license information.
5c0bd7bd4SRichard Trieu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c0bd7bd4SRichard Trieu //
7c0bd7bd4SRichard Trieu // \file
8c0bd7bd4SRichard Trieu //===----------------------------------------------------------------------===//
9c0bd7bd4SRichard Trieu
10c0bd7bd4SRichard Trieu #include "AMDGPUInstPrinter.h"
11c0bd7bd4SRichard Trieu #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
12c0bd7bd4SRichard Trieu #include "SIDefines.h"
13a8d9d507SStanislav Mekhanoshin #include "SIRegisterInfo.h"
14c0bd7bd4SRichard Trieu #include "Utils/AMDGPUAsmUtils.h"
15c0bd7bd4SRichard Trieu #include "Utils/AMDGPUBaseInfo.h"
16c0bd7bd4SRichard Trieu #include "llvm/MC/MCExpr.h"
17c0bd7bd4SRichard Trieu #include "llvm/MC/MCInst.h"
18c0bd7bd4SRichard Trieu #include "llvm/MC/MCInstrDesc.h"
19c0bd7bd4SRichard Trieu #include "llvm/MC/MCInstrInfo.h"
20c0bd7bd4SRichard Trieu #include "llvm/MC/MCSubtargetInfo.h"
21b05b69e0SSimon Pilgrim #include "llvm/Support/CommandLine.h"
226a87e9b0Sdfukalov #include "llvm/Support/TargetParser.h"
23c0bd7bd4SRichard Trieu
24c0bd7bd4SRichard Trieu using namespace llvm;
25c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU;
26c0bd7bd4SRichard Trieu
2754d6dfe9SStanislav Mekhanoshin static cl::opt<bool> Keep16BitSuffixes(
2854d6dfe9SStanislav Mekhanoshin "amdgpu-keep-16-bit-reg-suffixes",
2954d6dfe9SStanislav Mekhanoshin cl::desc("Keep .l and .h suffixes in asm for debugging purposes"),
3054d6dfe9SStanislav Mekhanoshin cl::init(false),
3154d6dfe9SStanislav Mekhanoshin cl::ReallyHidden);
3254d6dfe9SStanislav Mekhanoshin
printRegName(raw_ostream & OS,unsigned RegNo) const33481b1c83SScott Linder void AMDGPUInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
3468f163dfSScott Linder // FIXME: The current implementation of
3568f163dfSScott Linder // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
3668f163dfSScott Linder // as an integer or we provide a name which represents a physical register.
3768f163dfSScott Linder // For CFI instructions we really want to emit a name for the DWARF register
3868f163dfSScott Linder // instead, because there may be multiple DWARF registers corresponding to a
3968f163dfSScott Linder // single physical register. One case where this problem manifests is with
4068f163dfSScott Linder // wave32/wave64 where using the physical register name is ambiguous: if we
4168f163dfSScott Linder // write e.g. `.cfi_undefined v0` we lose information about the wavefront
4268f163dfSScott Linder // size which we need to encode the register in the final DWARF. Ideally we
4368f163dfSScott Linder // would extend MC to support parsing DWARF register names so we could do
4468f163dfSScott Linder // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
4568f163dfSScott Linder // non-pretty DWARF register names in assembly text.
4668f163dfSScott Linder OS << RegNo;
47481b1c83SScott Linder }
48481b1c83SScott Linder
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)49aa708763SFangrui Song void AMDGPUInstPrinter::printInst(const MCInst *MI, uint64_t Address,
50aa708763SFangrui Song StringRef Annot, const MCSubtargetInfo &STI,
51aa708763SFangrui Song raw_ostream &OS) {
52c0bd7bd4SRichard Trieu OS.flush();
533d87d0b9SFangrui Song printInstruction(MI, Address, STI, OS);
54c0bd7bd4SRichard Trieu printAnnotation(OS, Annot);
55c0bd7bd4SRichard Trieu }
56c0bd7bd4SRichard Trieu
printU4ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)57c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
58c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
59c0bd7bd4SRichard Trieu raw_ostream &O) {
60c0bd7bd4SRichard Trieu O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
61c0bd7bd4SRichard Trieu }
62c0bd7bd4SRichard Trieu
printU8ImmOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)63c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
64c0bd7bd4SRichard Trieu raw_ostream &O) {
65c0bd7bd4SRichard Trieu O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
66c0bd7bd4SRichard Trieu }
67c0bd7bd4SRichard Trieu
printU16ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)68c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
69c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
70c0bd7bd4SRichard Trieu raw_ostream &O) {
71c0bd7bd4SRichard Trieu // It's possible to end up with a 32-bit literal used with a 16-bit operand
72c0bd7bd4SRichard Trieu // with ignored high bits. Print as 32-bit anyway in that case.
73c0bd7bd4SRichard Trieu int64_t Imm = MI->getOperand(OpNo).getImm();
74c0bd7bd4SRichard Trieu if (isInt<16>(Imm) || isUInt<16>(Imm))
75c0bd7bd4SRichard Trieu O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
76c0bd7bd4SRichard Trieu else
77c0bd7bd4SRichard Trieu printU32ImmOperand(MI, OpNo, STI, O);
78c0bd7bd4SRichard Trieu }
79c0bd7bd4SRichard Trieu
printU4ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)80c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
81c0bd7bd4SRichard Trieu raw_ostream &O) {
82c0bd7bd4SRichard Trieu O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
83c0bd7bd4SRichard Trieu }
84c0bd7bd4SRichard Trieu
printU8ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)85c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
86c0bd7bd4SRichard Trieu raw_ostream &O) {
87c0bd7bd4SRichard Trieu O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
88c0bd7bd4SRichard Trieu }
89c0bd7bd4SRichard Trieu
printU16ImmDecOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)90c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
91c0bd7bd4SRichard Trieu raw_ostream &O) {
92c0bd7bd4SRichard Trieu O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
93c0bd7bd4SRichard Trieu }
94c0bd7bd4SRichard Trieu
printU32ImmOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)95c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
96c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
97c0bd7bd4SRichard Trieu raw_ostream &O) {
98c0bd7bd4SRichard Trieu O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
99c0bd7bd4SRichard Trieu }
100c0bd7bd4SRichard Trieu
printNamedBit(const MCInst * MI,unsigned OpNo,raw_ostream & O,StringRef BitName)101c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
102c0bd7bd4SRichard Trieu raw_ostream &O, StringRef BitName) {
103c0bd7bd4SRichard Trieu if (MI->getOperand(OpNo).getImm()) {
104c0bd7bd4SRichard Trieu O << ' ' << BitName;
105c0bd7bd4SRichard Trieu }
106c0bd7bd4SRichard Trieu }
107c0bd7bd4SRichard Trieu
printOffen(const MCInst * MI,unsigned OpNo,raw_ostream & O)108c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
109c0bd7bd4SRichard Trieu raw_ostream &O) {
110c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "offen");
111c0bd7bd4SRichard Trieu }
112c0bd7bd4SRichard Trieu
printIdxen(const MCInst * MI,unsigned OpNo,raw_ostream & O)113c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
114c0bd7bd4SRichard Trieu raw_ostream &O) {
115c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "idxen");
116c0bd7bd4SRichard Trieu }
117c0bd7bd4SRichard Trieu
printAddr64(const MCInst * MI,unsigned OpNo,raw_ostream & O)118c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
119c0bd7bd4SRichard Trieu raw_ostream &O) {
120c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "addr64");
121c0bd7bd4SRichard Trieu }
122c0bd7bd4SRichard Trieu
printOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)123c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
124c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
125c0bd7bd4SRichard Trieu raw_ostream &O) {
126c0bd7bd4SRichard Trieu uint16_t Imm = MI->getOperand(OpNo).getImm();
127c0bd7bd4SRichard Trieu if (Imm != 0) {
1289cee87d7SJay Foad O << " offset:";
129c0bd7bd4SRichard Trieu printU16ImmDecOperand(MI, OpNo, O);
130c0bd7bd4SRichard Trieu }
131c0bd7bd4SRichard Trieu }
132c0bd7bd4SRichard Trieu
printFlatOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1332eff0318SDmitry Preobrazhensky void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
134c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
135c0bd7bd4SRichard Trieu raw_ostream &O) {
136c0bd7bd4SRichard Trieu uint16_t Imm = MI->getOperand(OpNo).getImm();
137c0bd7bd4SRichard Trieu if (Imm != 0) {
1389cee87d7SJay Foad O << " offset:";
1392eff0318SDmitry Preobrazhensky
1402eff0318SDmitry Preobrazhensky const MCInstrDesc &Desc = MII.get(MI->getOpcode());
141c9d6fe6fSStanislav Mekhanoshin bool IsFlatSeg = !(Desc.TSFlags &
14236138db1SSebastian Neubauer (SIInstrFlags::FlatGlobal | SIInstrFlags::FlatScratch));
1432eff0318SDmitry Preobrazhensky
1442eff0318SDmitry Preobrazhensky if (IsFlatSeg) { // Unsigned offset
1452eff0318SDmitry Preobrazhensky printU16ImmDecOperand(MI, OpNo, O);
1462eff0318SDmitry Preobrazhensky } else { // Signed offset
147835e09c4SJoe Nash if (AMDGPU::isGFX10(STI)) {
1482eff0318SDmitry Preobrazhensky O << formatDec(SignExtend32<12>(MI->getOperand(OpNo).getImm()));
1492eff0318SDmitry Preobrazhensky } else {
1502eff0318SDmitry Preobrazhensky O << formatDec(SignExtend32<13>(MI->getOperand(OpNo).getImm()));
1512eff0318SDmitry Preobrazhensky }
1522eff0318SDmitry Preobrazhensky }
153c0bd7bd4SRichard Trieu }
154c0bd7bd4SRichard Trieu }
155c0bd7bd4SRichard Trieu
printOffset0(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)156c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
157c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
158c0bd7bd4SRichard Trieu raw_ostream &O) {
159c0bd7bd4SRichard Trieu if (MI->getOperand(OpNo).getImm()) {
160c0bd7bd4SRichard Trieu O << " offset0:";
161c0bd7bd4SRichard Trieu printU8ImmDecOperand(MI, OpNo, O);
162c0bd7bd4SRichard Trieu }
163c0bd7bd4SRichard Trieu }
164c0bd7bd4SRichard Trieu
printOffset1(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)165c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
166c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
167c0bd7bd4SRichard Trieu raw_ostream &O) {
168c0bd7bd4SRichard Trieu if (MI->getOperand(OpNo).getImm()) {
169c0bd7bd4SRichard Trieu O << " offset1:";
170c0bd7bd4SRichard Trieu printU8ImmDecOperand(MI, OpNo, O);
171c0bd7bd4SRichard Trieu }
172c0bd7bd4SRichard Trieu }
173c0bd7bd4SRichard Trieu
printSMRDOffset8(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)174c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
175c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
176c0bd7bd4SRichard Trieu raw_ostream &O) {
177c0bd7bd4SRichard Trieu printU32ImmOperand(MI, OpNo, STI, O);
178c0bd7bd4SRichard Trieu }
179c0bd7bd4SRichard Trieu
printSMEMOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1805998baccSDmitry Preobrazhensky void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
181c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
182c0bd7bd4SRichard Trieu raw_ostream &O) {
1835998baccSDmitry Preobrazhensky O << formatHex(MI->getOperand(OpNo).getImm());
184c0bd7bd4SRichard Trieu }
185c0bd7bd4SRichard Trieu
printSMEMOffsetMod(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)18688f04bdbSIvan Kosarev void AMDGPUInstPrinter::printSMEMOffsetMod(const MCInst *MI, unsigned OpNo,
18788f04bdbSIvan Kosarev const MCSubtargetInfo &STI,
18888f04bdbSIvan Kosarev raw_ostream &O) {
18988f04bdbSIvan Kosarev O << " offset:";
19088f04bdbSIvan Kosarev printSMEMOffset(MI, OpNo, STI, O);
19188f04bdbSIvan Kosarev }
19288f04bdbSIvan Kosarev
printSMRDLiteralOffset(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)193c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
194c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
195c0bd7bd4SRichard Trieu raw_ostream &O) {
196c0bd7bd4SRichard Trieu printU32ImmOperand(MI, OpNo, STI, O);
197c0bd7bd4SRichard Trieu }
198c0bd7bd4SRichard Trieu
printGDS(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)199c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
200c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
201c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "gds");
202c0bd7bd4SRichard Trieu }
203c0bd7bd4SRichard Trieu
printCPol(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)2043bffb1cdSStanislav Mekhanoshin void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
205c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
2063bffb1cdSStanislav Mekhanoshin auto Imm = MI->getOperand(OpNo).getImm();
2073bffb1cdSStanislav Mekhanoshin if (Imm & CPol::GLC)
2088992b50eSStanislav Mekhanoshin O << ((AMDGPU::isGFX940(STI) &&
2098992b50eSStanislav Mekhanoshin !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
2108992b50eSStanislav Mekhanoshin : " glc");
2113bffb1cdSStanislav Mekhanoshin if (Imm & CPol::SLC)
2128992b50eSStanislav Mekhanoshin O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
2133bffb1cdSStanislav Mekhanoshin if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
2143bffb1cdSStanislav Mekhanoshin O << " dlc";
2153bffb1cdSStanislav Mekhanoshin if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
2168992b50eSStanislav Mekhanoshin O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
2173bffb1cdSStanislav Mekhanoshin if (Imm & ~CPol::ALL)
2183bffb1cdSStanislav Mekhanoshin O << " /* unexpected cache policy bit */";
219c0bd7bd4SRichard Trieu }
220c0bd7bd4SRichard Trieu
printSWZ(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)221265e94e6SPiotr Sobczak void AMDGPUInstPrinter::printSWZ(const MCInst *MI, unsigned OpNo,
222265e94e6SPiotr Sobczak const MCSubtargetInfo &STI, raw_ostream &O) {
223265e94e6SPiotr Sobczak }
224265e94e6SPiotr Sobczak
printTFE(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)225c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
226c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
227c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "tfe");
228c0bd7bd4SRichard Trieu }
229c0bd7bd4SRichard Trieu
printDMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)230c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
231c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
232c0bd7bd4SRichard Trieu if (MI->getOperand(OpNo).getImm()) {
233c0bd7bd4SRichard Trieu O << " dmask:";
234c0bd7bd4SRichard Trieu printU16ImmOperand(MI, OpNo, STI, O);
235c0bd7bd4SRichard Trieu }
236c0bd7bd4SRichard Trieu }
237c0bd7bd4SRichard Trieu
printDim(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)238c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
239c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
240c0bd7bd4SRichard Trieu unsigned Dim = MI->getOperand(OpNo).getImm();
241c0bd7bd4SRichard Trieu O << " dim:SQ_RSRC_IMG_";
242c0bd7bd4SRichard Trieu
243c0bd7bd4SRichard Trieu const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
244c0bd7bd4SRichard Trieu if (DimInfo)
245c0bd7bd4SRichard Trieu O << DimInfo->AsmSuffix;
246c0bd7bd4SRichard Trieu else
247c0bd7bd4SRichard Trieu O << Dim;
248c0bd7bd4SRichard Trieu }
249c0bd7bd4SRichard Trieu
printUNorm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)250c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
251c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
252c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "unorm");
253c0bd7bd4SRichard Trieu }
254c0bd7bd4SRichard Trieu
printDA(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)255c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
256c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
257c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "da");
258c0bd7bd4SRichard Trieu }
259c0bd7bd4SRichard Trieu
printR128A16(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)260c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
261c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
262c0bd7bd4SRichard Trieu if (STI.hasFeature(AMDGPU::FeatureR128A16))
263c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "a16");
264c0bd7bd4SRichard Trieu else
265c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "r128");
266c0bd7bd4SRichard Trieu }
267c0bd7bd4SRichard Trieu
printGFX10A16(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)26887568691SSebastian Neubauer void AMDGPUInstPrinter::printGFX10A16(const MCInst *MI, unsigned OpNo,
26987568691SSebastian Neubauer const MCSubtargetInfo &STI, raw_ostream &O) {
27087568691SSebastian Neubauer printNamedBit(MI, OpNo, O, "a16");
27187568691SSebastian Neubauer }
27287568691SSebastian Neubauer
printLWE(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)273c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
274c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
275c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "lwe");
276c0bd7bd4SRichard Trieu }
277c0bd7bd4SRichard Trieu
printD16(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)278c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo,
279c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
280c0bd7bd4SRichard Trieu printNamedBit(MI, OpNo, O, "d16");
281c0bd7bd4SRichard Trieu }
282c0bd7bd4SRichard Trieu
printExpCompr(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)283c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo,
284c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
285c0bd7bd4SRichard Trieu raw_ostream &O) {
2860ca41247SJay Foad printNamedBit(MI, OpNo, O, "compr");
287c0bd7bd4SRichard Trieu }
288c0bd7bd4SRichard Trieu
printExpVM(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)289c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo,
290c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
291c0bd7bd4SRichard Trieu raw_ostream &O) {
2920ca41247SJay Foad printNamedBit(MI, OpNo, O, "vm");
293c0bd7bd4SRichard Trieu }
294c0bd7bd4SRichard Trieu
printFORMAT(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)295c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
296c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
297c0bd7bd4SRichard Trieu raw_ostream &O) {
2986b894892SDmitry Preobrazhensky }
2996b894892SDmitry Preobrazhensky
printSymbolicFormat(const MCInst * MI,const MCSubtargetInfo & STI,raw_ostream & O)3006b894892SDmitry Preobrazhensky void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
3016b894892SDmitry Preobrazhensky const MCSubtargetInfo &STI,
3026b894892SDmitry Preobrazhensky raw_ostream &O) {
303e122eba1SDmitry Preobrazhensky using namespace llvm::AMDGPU::MTBUFFormat;
304e122eba1SDmitry Preobrazhensky
3056b894892SDmitry Preobrazhensky int OpNo =
3066b894892SDmitry Preobrazhensky AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
3076b894892SDmitry Preobrazhensky assert(OpNo != -1);
3086b894892SDmitry Preobrazhensky
309e122eba1SDmitry Preobrazhensky unsigned Val = MI->getOperand(OpNo).getImm();
3104f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
311e122eba1SDmitry Preobrazhensky if (Val == UFMT_DEFAULT)
312e122eba1SDmitry Preobrazhensky return;
313c7025940SJoe Nash if (isValidUnifiedFormat(Val, STI)) {
314c7025940SJoe Nash O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
3156b894892SDmitry Preobrazhensky } else {
316c0bd7bd4SRichard Trieu O << " format:" << Val;
3176b894892SDmitry Preobrazhensky }
318e122eba1SDmitry Preobrazhensky } else {
319e122eba1SDmitry Preobrazhensky if (Val == DFMT_NFMT_DEFAULT)
320e122eba1SDmitry Preobrazhensky return;
3216b894892SDmitry Preobrazhensky if (isValidDfmtNfmt(Val, STI)) {
322e122eba1SDmitry Preobrazhensky unsigned Dfmt;
323e122eba1SDmitry Preobrazhensky unsigned Nfmt;
324e122eba1SDmitry Preobrazhensky decodeDfmtNfmt(Val, Dfmt, Nfmt);
3256b894892SDmitry Preobrazhensky O << " format:[";
3266b894892SDmitry Preobrazhensky if (Dfmt != DFMT_DEFAULT) {
3276b894892SDmitry Preobrazhensky O << getDfmtName(Dfmt);
3286b894892SDmitry Preobrazhensky if (Nfmt != NFMT_DEFAULT) {
329e122eba1SDmitry Preobrazhensky O << ',';
330c0bd7bd4SRichard Trieu }
3316b894892SDmitry Preobrazhensky }
3326b894892SDmitry Preobrazhensky if (Nfmt != NFMT_DEFAULT) {
3336b894892SDmitry Preobrazhensky O << getNfmtName(Nfmt, STI);
3346b894892SDmitry Preobrazhensky }
3356b894892SDmitry Preobrazhensky O << ']';
3366b894892SDmitry Preobrazhensky } else {
3376b894892SDmitry Preobrazhensky O << " format:" << Val;
3386b894892SDmitry Preobrazhensky }
3396b894892SDmitry Preobrazhensky }
3406b894892SDmitry Preobrazhensky }
341c0bd7bd4SRichard Trieu
printRegOperand(unsigned RegNo,raw_ostream & O,const MCRegisterInfo & MRI)342c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
343c0bd7bd4SRichard Trieu const MCRegisterInfo &MRI) {
3447872d76aSStanislav Mekhanoshin #if !defined(NDEBUG)
345c0bd7bd4SRichard Trieu switch (RegNo) {
346c0bd7bd4SRichard Trieu case AMDGPU::FP_REG:
347c0bd7bd4SRichard Trieu case AMDGPU::SP_REG:
348c0bd7bd4SRichard Trieu case AMDGPU::PRIVATE_RSRC_REG:
349c0bd7bd4SRichard Trieu llvm_unreachable("pseudo-register should not ever be emitted");
3509111f35fSDmitry Preobrazhensky case AMDGPU::SCC:
3519111f35fSDmitry Preobrazhensky llvm_unreachable("pseudo scc should not ever be emitted");
352c0bd7bd4SRichard Trieu default:
353c0bd7bd4SRichard Trieu break;
354c0bd7bd4SRichard Trieu }
3557872d76aSStanislav Mekhanoshin #endif
356c0bd7bd4SRichard Trieu
35754d6dfe9SStanislav Mekhanoshin StringRef RegName(getRegisterName(RegNo));
35854d6dfe9SStanislav Mekhanoshin if (!Keep16BitSuffixes)
35954d6dfe9SStanislav Mekhanoshin if (!RegName.consume_back(".l"))
36054d6dfe9SStanislav Mekhanoshin RegName.consume_back(".h");
36154d6dfe9SStanislav Mekhanoshin
36254d6dfe9SStanislav Mekhanoshin O << RegName;
363c0bd7bd4SRichard Trieu }
364c0bd7bd4SRichard Trieu
printVOPDst(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)365c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
366e243ead6SJoe Nash const MCSubtargetInfo &STI, raw_ostream &O) {
3670f5ebbccSDmitry Preobrazhensky auto Opcode = MI->getOpcode();
3680f5ebbccSDmitry Preobrazhensky auto Flags = MII.get(Opcode).TSFlags;
369c0bd7bd4SRichard Trieu if (OpNo == 0) {
370e243ead6SJoe Nash if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
371e243ead6SJoe Nash O << "_e64_dpp";
372e243ead6SJoe Nash else if (Flags & SIInstrFlags::VOP3) {
3730f5ebbccSDmitry Preobrazhensky if (!getVOP3IsSingle(Opcode))
374c0bd7bd4SRichard Trieu O << "_e64";
375e243ead6SJoe Nash } else if (Flags & SIInstrFlags::DPP)
376c0bd7bd4SRichard Trieu O << "_dpp";
377e243ead6SJoe Nash else if (Flags & SIInstrFlags::SDWA)
378c0bd7bd4SRichard Trieu O << "_sdwa";
379e243ead6SJoe Nash else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
380e243ead6SJoe Nash ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
381c0bd7bd4SRichard Trieu O << "_e32";
3820f5ebbccSDmitry Preobrazhensky O << " ";
3830f5ebbccSDmitry Preobrazhensky }
384c0bd7bd4SRichard Trieu
385be1082c6SJoe Nash printRegularOperand(MI, OpNo, STI, O);
386c0bd7bd4SRichard Trieu
3878bcc9bb5SStanislav Mekhanoshin // Print default vcc/vcc_lo operand.
3880f5ebbccSDmitry Preobrazhensky switch (Opcode) {
389c0bd7bd4SRichard Trieu default: break;
390c0bd7bd4SRichard Trieu
391c0bd7bd4SRichard Trieu case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
392c0bd7bd4SRichard Trieu case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
393c0bd7bd4SRichard Trieu case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
394c0bd7bd4SRichard Trieu case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
395c0bd7bd4SRichard Trieu case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
396c0bd7bd4SRichard Trieu case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
397245b5ba3SStanislav Mekhanoshin case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
398245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
399245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
400245b5ba3SStanislav Mekhanoshin case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
401245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
402245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
403086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
404086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
405086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
406086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
407086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
408086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
409086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
410086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
411086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
412086a9c10SJoe Nash printDefaultVccOperand(false, STI, O);
413c0bd7bd4SRichard Trieu break;
414c0bd7bd4SRichard Trieu }
415c0bd7bd4SRichard Trieu }
416c0bd7bd4SRichard Trieu
printVINTRPDst(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)417c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
418c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
419c0bd7bd4SRichard Trieu if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
420c0bd7bd4SRichard Trieu O << " ";
421c0bd7bd4SRichard Trieu else
422c0bd7bd4SRichard Trieu O << "_e32 ";
423c0bd7bd4SRichard Trieu
424be1082c6SJoe Nash printRegularOperand(MI, OpNo, STI, O);
425c0bd7bd4SRichard Trieu }
426c0bd7bd4SRichard Trieu
printImmediateInt16(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)4275f5f566bSMatt Arsenault void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
4285f5f566bSMatt Arsenault const MCSubtargetInfo &STI,
4295f5f566bSMatt Arsenault raw_ostream &O) {
4305f5f566bSMatt Arsenault int16_t SImm = static_cast<int16_t>(Imm);
4310b8fd77aSDmitry Preobrazhensky if (isInlinableIntLiteral(SImm)) {
4325f5f566bSMatt Arsenault O << SImm;
4330b8fd77aSDmitry Preobrazhensky } else {
4340b8fd77aSDmitry Preobrazhensky uint64_t Imm16 = static_cast<uint16_t>(Imm);
4350b8fd77aSDmitry Preobrazhensky O << formatHex(Imm16);
4360b8fd77aSDmitry Preobrazhensky }
4375f5f566bSMatt Arsenault }
4385f5f566bSMatt Arsenault
printImmediate16(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)439c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printImmediate16(uint32_t Imm,
440c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
441c0bd7bd4SRichard Trieu raw_ostream &O) {
442c0bd7bd4SRichard Trieu int16_t SImm = static_cast<int16_t>(Imm);
4435f5f566bSMatt Arsenault if (isInlinableIntLiteral(SImm)) {
444c0bd7bd4SRichard Trieu O << SImm;
445c0bd7bd4SRichard Trieu return;
446c0bd7bd4SRichard Trieu }
447c0bd7bd4SRichard Trieu
448c0bd7bd4SRichard Trieu if (Imm == 0x3C00)
449c0bd7bd4SRichard Trieu O<< "1.0";
450c0bd7bd4SRichard Trieu else if (Imm == 0xBC00)
451c0bd7bd4SRichard Trieu O<< "-1.0";
452c0bd7bd4SRichard Trieu else if (Imm == 0x3800)
453c0bd7bd4SRichard Trieu O<< "0.5";
454c0bd7bd4SRichard Trieu else if (Imm == 0xB800)
455c0bd7bd4SRichard Trieu O<< "-0.5";
456c0bd7bd4SRichard Trieu else if (Imm == 0x4000)
457c0bd7bd4SRichard Trieu O<< "2.0";
458c0bd7bd4SRichard Trieu else if (Imm == 0xC000)
459c0bd7bd4SRichard Trieu O<< "-2.0";
460c0bd7bd4SRichard Trieu else if (Imm == 0x4400)
461c0bd7bd4SRichard Trieu O<< "4.0";
462c0bd7bd4SRichard Trieu else if (Imm == 0xC400)
463c0bd7bd4SRichard Trieu O<< "-4.0";
4646f437117SMatt Arsenault else if (Imm == 0x3118 &&
4656f437117SMatt Arsenault STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) {
466c0bd7bd4SRichard Trieu O << "0.15915494";
4670b8fd77aSDmitry Preobrazhensky } else {
4680b8fd77aSDmitry Preobrazhensky uint64_t Imm16 = static_cast<uint16_t>(Imm);
4690b8fd77aSDmitry Preobrazhensky O << formatHex(Imm16);
4700b8fd77aSDmitry Preobrazhensky }
471c0bd7bd4SRichard Trieu }
472c0bd7bd4SRichard Trieu
printImmediateV216(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)473c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm,
474c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
475c0bd7bd4SRichard Trieu raw_ostream &O) {
476c0bd7bd4SRichard Trieu uint16_t Lo16 = static_cast<uint16_t>(Imm);
477c0bd7bd4SRichard Trieu printImmediate16(Lo16, STI, O);
478c0bd7bd4SRichard Trieu }
479c0bd7bd4SRichard Trieu
printImmediate32(uint32_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)480c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
481c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
482c0bd7bd4SRichard Trieu raw_ostream &O) {
483c0bd7bd4SRichard Trieu int32_t SImm = static_cast<int32_t>(Imm);
484c0bd7bd4SRichard Trieu if (SImm >= -16 && SImm <= 64) {
485c0bd7bd4SRichard Trieu O << SImm;
486c0bd7bd4SRichard Trieu return;
487c0bd7bd4SRichard Trieu }
488c0bd7bd4SRichard Trieu
489c0bd7bd4SRichard Trieu if (Imm == FloatToBits(0.0f))
490c0bd7bd4SRichard Trieu O << "0.0";
491c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(1.0f))
492c0bd7bd4SRichard Trieu O << "1.0";
493c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(-1.0f))
494c0bd7bd4SRichard Trieu O << "-1.0";
495c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(0.5f))
496c0bd7bd4SRichard Trieu O << "0.5";
497c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(-0.5f))
498c0bd7bd4SRichard Trieu O << "-0.5";
499c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(2.0f))
500c0bd7bd4SRichard Trieu O << "2.0";
501c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(-2.0f))
502c0bd7bd4SRichard Trieu O << "-2.0";
503c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(4.0f))
504c0bd7bd4SRichard Trieu O << "4.0";
505c0bd7bd4SRichard Trieu else if (Imm == FloatToBits(-4.0f))
506c0bd7bd4SRichard Trieu O << "-4.0";
507c0bd7bd4SRichard Trieu else if (Imm == 0x3e22f983 &&
508c0bd7bd4SRichard Trieu STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
509c0bd7bd4SRichard Trieu O << "0.15915494";
510c0bd7bd4SRichard Trieu else
511c0bd7bd4SRichard Trieu O << formatHex(static_cast<uint64_t>(Imm));
512c0bd7bd4SRichard Trieu }
513c0bd7bd4SRichard Trieu
printImmediate64(uint64_t Imm,const MCSubtargetInfo & STI,raw_ostream & O)514c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
515c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
516c0bd7bd4SRichard Trieu raw_ostream &O) {
517c0bd7bd4SRichard Trieu int64_t SImm = static_cast<int64_t>(Imm);
518c0bd7bd4SRichard Trieu if (SImm >= -16 && SImm <= 64) {
519c0bd7bd4SRichard Trieu O << SImm;
520c0bd7bd4SRichard Trieu return;
521c0bd7bd4SRichard Trieu }
522c0bd7bd4SRichard Trieu
523c0bd7bd4SRichard Trieu if (Imm == DoubleToBits(0.0))
524c0bd7bd4SRichard Trieu O << "0.0";
525c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(1.0))
526c0bd7bd4SRichard Trieu O << "1.0";
527c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(-1.0))
528c0bd7bd4SRichard Trieu O << "-1.0";
529c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(0.5))
530c0bd7bd4SRichard Trieu O << "0.5";
531c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(-0.5))
532c0bd7bd4SRichard Trieu O << "-0.5";
533c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(2.0))
534c0bd7bd4SRichard Trieu O << "2.0";
535c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(-2.0))
536c0bd7bd4SRichard Trieu O << "-2.0";
537c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(4.0))
538c0bd7bd4SRichard Trieu O << "4.0";
539c0bd7bd4SRichard Trieu else if (Imm == DoubleToBits(-4.0))
540c0bd7bd4SRichard Trieu O << "-4.0";
541c0bd7bd4SRichard Trieu else if (Imm == 0x3fc45f306dc9c882 &&
542c0bd7bd4SRichard Trieu STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm])
543c0bd7bd4SRichard Trieu O << "0.15915494309189532";
544c0bd7bd4SRichard Trieu else {
54577e63b25SJay Foad assert(isUInt<32>(Imm) || isInt<32>(Imm));
546c0bd7bd4SRichard Trieu
547c0bd7bd4SRichard Trieu // In rare situations, we will have a 32-bit literal in a 64-bit
548c0bd7bd4SRichard Trieu // operand. This is technically allowed for the encoding of s_mov_b64.
549c0bd7bd4SRichard Trieu O << formatHex(static_cast<uint64_t>(Imm));
550c0bd7bd4SRichard Trieu }
551c0bd7bd4SRichard Trieu }
552c0bd7bd4SRichard Trieu
printBLGP(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)55350d7f464SStanislav Mekhanoshin void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
55450d7f464SStanislav Mekhanoshin const MCSubtargetInfo &STI,
55550d7f464SStanislav Mekhanoshin raw_ostream &O) {
55650d7f464SStanislav Mekhanoshin unsigned Imm = MI->getOperand(OpNo).getImm();
55750d7f464SStanislav Mekhanoshin if (!Imm)
55850d7f464SStanislav Mekhanoshin return;
55950d7f464SStanislav Mekhanoshin
5600a79e1f3SStanislav Mekhanoshin if (AMDGPU::isGFX940(STI)) {
5610a79e1f3SStanislav Mekhanoshin switch (MI->getOpcode()) {
5620a79e1f3SStanislav Mekhanoshin case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5630a79e1f3SStanislav Mekhanoshin case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5640a79e1f3SStanislav Mekhanoshin case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5650a79e1f3SStanislav Mekhanoshin case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5660a79e1f3SStanislav Mekhanoshin O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
5670a79e1f3SStanislav Mekhanoshin << ((Imm >> 2) & 1) << ']';
5680a79e1f3SStanislav Mekhanoshin return;
5690a79e1f3SStanislav Mekhanoshin }
5700a79e1f3SStanislav Mekhanoshin }
5710a79e1f3SStanislav Mekhanoshin
57250d7f464SStanislav Mekhanoshin O << " blgp:" << Imm;
57350d7f464SStanislav Mekhanoshin }
57450d7f464SStanislav Mekhanoshin
printCBSZ(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)57550d7f464SStanislav Mekhanoshin void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
57650d7f464SStanislav Mekhanoshin const MCSubtargetInfo &STI,
57750d7f464SStanislav Mekhanoshin raw_ostream &O) {
57850d7f464SStanislav Mekhanoshin unsigned Imm = MI->getOperand(OpNo).getImm();
57950d7f464SStanislav Mekhanoshin if (!Imm)
58050d7f464SStanislav Mekhanoshin return;
58150d7f464SStanislav Mekhanoshin
58250d7f464SStanislav Mekhanoshin O << " cbsz:" << Imm;
58350d7f464SStanislav Mekhanoshin }
58450d7f464SStanislav Mekhanoshin
printABID(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)58550d7f464SStanislav Mekhanoshin void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
58650d7f464SStanislav Mekhanoshin const MCSubtargetInfo &STI,
58750d7f464SStanislav Mekhanoshin raw_ostream &O) {
58850d7f464SStanislav Mekhanoshin unsigned Imm = MI->getOperand(OpNo).getImm();
58950d7f464SStanislav Mekhanoshin if (!Imm)
59050d7f464SStanislav Mekhanoshin return;
59150d7f464SStanislav Mekhanoshin
59250d7f464SStanislav Mekhanoshin O << " abid:" << Imm;
59350d7f464SStanislav Mekhanoshin }
59450d7f464SStanislav Mekhanoshin
printDefaultVccOperand(bool FirstOperand,const MCSubtargetInfo & STI,raw_ostream & O)595086a9c10SJoe Nash void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
596c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
597c0bd7bd4SRichard Trieu raw_ostream &O) {
598086a9c10SJoe Nash if (!FirstOperand)
599c0bd7bd4SRichard Trieu O << ", ";
600086a9c10SJoe Nash printRegOperand(STI.getFeatureBits()[AMDGPU::FeatureWavefrontSize64]
601086a9c10SJoe Nash ? AMDGPU::VCC
602086a9c10SJoe Nash : AMDGPU::VCC_LO,
603086a9c10SJoe Nash O, MRI);
604086a9c10SJoe Nash if (FirstOperand)
605c0bd7bd4SRichard Trieu O << ", ";
606c0bd7bd4SRichard Trieu }
607c0bd7bd4SRichard Trieu
printWaitVDST(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)608729467acSJoe Nash void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
609729467acSJoe Nash const MCSubtargetInfo &STI,
610729467acSJoe Nash raw_ostream &O) {
611729467acSJoe Nash uint8_t Imm = MI->getOperand(OpNo).getImm();
612729467acSJoe Nash if (Imm != 0) {
613729467acSJoe Nash O << " wait_vdst:";
614729467acSJoe Nash printU4ImmDecOperand(MI, OpNo, O);
615729467acSJoe Nash }
616729467acSJoe Nash }
617729467acSJoe Nash
printWaitEXP(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)618ef1ea5acSJoe Nash void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
619ef1ea5acSJoe Nash const MCSubtargetInfo &STI,
620ef1ea5acSJoe Nash raw_ostream &O) {
621ef1ea5acSJoe Nash uint8_t Imm = MI->getOperand(OpNo).getImm();
622ef1ea5acSJoe Nash if (Imm != 0) {
623ef1ea5acSJoe Nash O << " wait_exp:";
624ef1ea5acSJoe Nash printU4ImmDecOperand(MI, OpNo, O);
625ef1ea5acSJoe Nash }
626ef1ea5acSJoe Nash }
627ef1ea5acSJoe Nash
needsImpliedVcc(const MCInstrDesc & Desc,unsigned OpNo) const628be1082c6SJoe Nash bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
629be1082c6SJoe Nash unsigned OpNo) const {
630*b28bb8ccSJoe Nash return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
631be1082c6SJoe Nash (Desc.TSFlags & SIInstrFlags::VOPC) &&
632be1082c6SJoe Nash (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
633be1082c6SJoe Nash Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
634be1082c6SJoe Nash }
635be1082c6SJoe Nash
636ef1ea5acSJoe Nash // Print default vcc/vcc_lo operand of VOPC.
printOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)637c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
638c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
639c0bd7bd4SRichard Trieu raw_ostream &O) {
640be1082c6SJoe Nash unsigned Opc = MI->getOpcode();
641be1082c6SJoe Nash const MCInstrDesc &Desc = MII.get(Opc);
642be1082c6SJoe Nash int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
643be1082c6SJoe Nash // 0, 1 and 2 are the first printed operands in different cases
644be1082c6SJoe Nash // If there are printed modifiers, printOperandAndFPInputMods or
645be1082c6SJoe Nash // printOperandAndIntInputMods will be called instead
646be1082c6SJoe Nash if ((OpNo == 0 ||
647*b28bb8ccSJoe Nash (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
648be1082c6SJoe Nash (Desc.TSFlags & SIInstrFlags::VOPC) &&
649c0bd7bd4SRichard Trieu (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
650c0bd7bd4SRichard Trieu Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
651086a9c10SJoe Nash printDefaultVccOperand(true, STI, O);
652c0bd7bd4SRichard Trieu
653be1082c6SJoe Nash printRegularOperand(MI, OpNo, STI, O);
654be1082c6SJoe Nash }
655be1082c6SJoe Nash
656be1082c6SJoe Nash // Print operands after vcc or modifier handling.
printRegularOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)657be1082c6SJoe Nash void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
658be1082c6SJoe Nash const MCSubtargetInfo &STI,
659be1082c6SJoe Nash raw_ostream &O) {
660be1082c6SJoe Nash const MCInstrDesc &Desc = MII.get(MI->getOpcode());
661be1082c6SJoe Nash
662c0bd7bd4SRichard Trieu if (OpNo >= MI->getNumOperands()) {
663c0bd7bd4SRichard Trieu O << "/*Missing OP" << OpNo << "*/";
664c0bd7bd4SRichard Trieu return;
665c0bd7bd4SRichard Trieu }
666c0bd7bd4SRichard Trieu
667c0bd7bd4SRichard Trieu const MCOperand &Op = MI->getOperand(OpNo);
668c0bd7bd4SRichard Trieu if (Op.isReg()) {
669c0bd7bd4SRichard Trieu printRegOperand(Op.getReg(), O, MRI);
670c0bd7bd4SRichard Trieu } else if (Op.isImm()) {
6715f5f566bSMatt Arsenault const uint8_t OpTy = Desc.OpInfo[OpNo].OperandType;
6725f5f566bSMatt Arsenault switch (OpTy) {
673c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_INT32:
674c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_FP32:
675b4b7e605SJoe Nash case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
676c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_INT32:
677c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_FP32:
67850d7f464SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
67950d7f464SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
680a8d9d507SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_IMM_V2INT32:
681a8d9d507SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_IMM_V2FP32:
682a8d9d507SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
683a8d9d507SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
684c0bd7bd4SRichard Trieu case MCOI::OPERAND_IMMEDIATE:
685c0bd7bd4SRichard Trieu printImmediate32(Op.getImm(), STI, O);
686c0bd7bd4SRichard Trieu break;
687c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_INT64:
688c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_FP64:
689c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_INT64:
690c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_FP64:
691a8d9d507SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
692c0bd7bd4SRichard Trieu printImmediate64(Op.getImm(), STI, O);
693c0bd7bd4SRichard Trieu break;
694c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_INT16:
69550d7f464SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
696c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_INT16:
6975f5f566bSMatt Arsenault printImmediateInt16(Op.getImm(), STI, O);
6985f5f566bSMatt Arsenault break;
6995f5f566bSMatt Arsenault case AMDGPU::OPERAND_REG_INLINE_C_FP16:
7005f5f566bSMatt Arsenault case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
701c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_FP16:
702b4b7e605SJoe Nash case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
703c0bd7bd4SRichard Trieu printImmediate16(Op.getImm(), STI, O);
704c0bd7bd4SRichard Trieu break;
705c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_V2INT16:
706c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_IMM_V2FP16:
707c0bd7bd4SRichard Trieu if (!isUInt<16>(Op.getImm()) &&
708c0bd7bd4SRichard Trieu STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
709c0bd7bd4SRichard Trieu printImmediate32(Op.getImm(), STI, O);
710c0bd7bd4SRichard Trieu break;
711c0bd7bd4SRichard Trieu }
7125f5f566bSMatt Arsenault
7135f5f566bSMatt Arsenault // Deal with 16-bit FP inline immediates not working.
7145f5f566bSMatt Arsenault if (OpTy == AMDGPU::OPERAND_REG_IMM_V2FP16) {
7155f5f566bSMatt Arsenault printImmediate16(static_cast<uint16_t>(Op.getImm()), STI, O);
7165f5f566bSMatt Arsenault break;
7175f5f566bSMatt Arsenault }
718c0bd7bd4SRichard Trieu LLVM_FALLTHROUGH;
719c0bd7bd4SRichard Trieu case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
72050d7f464SStanislav Mekhanoshin case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
7215f5f566bSMatt Arsenault printImmediateInt16(static_cast<uint16_t>(Op.getImm()), STI, O);
7225f5f566bSMatt Arsenault break;
7235f5f566bSMatt Arsenault case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
7245f5f566bSMatt Arsenault case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
725c0bd7bd4SRichard Trieu printImmediateV216(Op.getImm(), STI, O);
726c0bd7bd4SRichard Trieu break;
727c0bd7bd4SRichard Trieu case MCOI::OPERAND_UNKNOWN:
728c0bd7bd4SRichard Trieu case MCOI::OPERAND_PCREL:
729c0bd7bd4SRichard Trieu O << formatDec(Op.getImm());
730c0bd7bd4SRichard Trieu break;
731c0bd7bd4SRichard Trieu case MCOI::OPERAND_REGISTER:
732c0bd7bd4SRichard Trieu // FIXME: This should be removed and handled somewhere else. Seems to come
733c0bd7bd4SRichard Trieu // from a disassembler bug.
734c0bd7bd4SRichard Trieu O << "/*invalid immediate*/";
735c0bd7bd4SRichard Trieu break;
736c0bd7bd4SRichard Trieu default:
737c0bd7bd4SRichard Trieu // We hit this for the immediate instruction bits that don't yet have a
738c0bd7bd4SRichard Trieu // custom printer.
739c0bd7bd4SRichard Trieu llvm_unreachable("unexpected immediate operand type");
740c0bd7bd4SRichard Trieu }
741698c6b0aSDan Gohman } else if (Op.isDFPImm()) {
742698c6b0aSDan Gohman double Value = bit_cast<double>(Op.getDFPImm());
743c0bd7bd4SRichard Trieu // We special case 0.0 because otherwise it will be printed as an integer.
744698c6b0aSDan Gohman if (Value == 0.0)
745c0bd7bd4SRichard Trieu O << "0.0";
746c0bd7bd4SRichard Trieu else {
747c0bd7bd4SRichard Trieu const MCInstrDesc &Desc = MII.get(MI->getOpcode());
748c0bd7bd4SRichard Trieu int RCID = Desc.OpInfo[OpNo].RegClass;
749c0bd7bd4SRichard Trieu unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
750c0bd7bd4SRichard Trieu if (RCBits == 32)
751698c6b0aSDan Gohman printImmediate32(FloatToBits(Value), STI, O);
752c0bd7bd4SRichard Trieu else if (RCBits == 64)
753698c6b0aSDan Gohman printImmediate64(DoubleToBits(Value), STI, O);
754c0bd7bd4SRichard Trieu else
755c0bd7bd4SRichard Trieu llvm_unreachable("Invalid register class size");
756c0bd7bd4SRichard Trieu }
757c0bd7bd4SRichard Trieu } else if (Op.isExpr()) {
758c0bd7bd4SRichard Trieu const MCExpr *Exp = Op.getExpr();
759c0bd7bd4SRichard Trieu Exp->print(O, &MAI);
760c0bd7bd4SRichard Trieu } else {
761c0bd7bd4SRichard Trieu O << "/*INV_OP*/";
762c0bd7bd4SRichard Trieu }
763c0bd7bd4SRichard Trieu
7648bcc9bb5SStanislav Mekhanoshin // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
765c0bd7bd4SRichard Trieu switch (MI->getOpcode()) {
766c0bd7bd4SRichard Trieu default: break;
767c0bd7bd4SRichard Trieu
768c0bd7bd4SRichard Trieu case AMDGPU::V_CNDMASK_B32_e32_gfx10:
769c0bd7bd4SRichard Trieu case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
770c0bd7bd4SRichard Trieu case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
771c0bd7bd4SRichard Trieu case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
7726c7d7eebSDmitry Preobrazhensky case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
773245b5ba3SStanislav Mekhanoshin case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
774245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
775245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
7766c7d7eebSDmitry Preobrazhensky case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
777245b5ba3SStanislav Mekhanoshin case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
778245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
779245b5ba3SStanislav Mekhanoshin case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
780086a9c10SJoe Nash case AMDGPU::V_CNDMASK_B32_e32_gfx11:
781086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
782086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
783086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
784086a9c10SJoe Nash case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
785086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
786086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
787086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
788086a9c10SJoe Nash case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
789086a9c10SJoe Nash case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
790086a9c10SJoe Nash case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
791086a9c10SJoe Nash case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
792c0bd7bd4SRichard Trieu
793c0bd7bd4SRichard Trieu case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
794c0bd7bd4SRichard Trieu case AMDGPU::V_CNDMASK_B32_e32_vi:
795c0bd7bd4SRichard Trieu if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
796c0bd7bd4SRichard Trieu AMDGPU::OpName::src1))
797086a9c10SJoe Nash printDefaultVccOperand(OpNo == 0, STI, O);
798c0bd7bd4SRichard Trieu break;
799c0bd7bd4SRichard Trieu }
8006b894892SDmitry Preobrazhensky
8016b894892SDmitry Preobrazhensky if (Desc.TSFlags & SIInstrFlags::MTBUF) {
8026b894892SDmitry Preobrazhensky int SOffsetIdx =
8036b894892SDmitry Preobrazhensky AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
8046b894892SDmitry Preobrazhensky assert(SOffsetIdx != -1);
8056b894892SDmitry Preobrazhensky if ((int)OpNo == SOffsetIdx)
8066b894892SDmitry Preobrazhensky printSymbolicFormat(MI, STI, O);
8076b894892SDmitry Preobrazhensky }
808c0bd7bd4SRichard Trieu }
809c0bd7bd4SRichard Trieu
printOperandAndFPInputMods(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)810c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
811c0bd7bd4SRichard Trieu unsigned OpNo,
812c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
813c0bd7bd4SRichard Trieu raw_ostream &O) {
814be1082c6SJoe Nash const MCInstrDesc &Desc = MII.get(MI->getOpcode());
815be1082c6SJoe Nash if (needsImpliedVcc(Desc, OpNo))
816be1082c6SJoe Nash printDefaultVccOperand(true, STI, O);
817be1082c6SJoe Nash
818c0bd7bd4SRichard Trieu unsigned InputModifiers = MI->getOperand(OpNo).getImm();
819c0bd7bd4SRichard Trieu
820c0bd7bd4SRichard Trieu // Use 'neg(...)' instead of '-' to avoid ambiguity.
821c0bd7bd4SRichard Trieu // This is important for integer literals because
822c0bd7bd4SRichard Trieu // -1 is not the same value as neg(1).
823c0bd7bd4SRichard Trieu bool NegMnemo = false;
824c0bd7bd4SRichard Trieu
825c0bd7bd4SRichard Trieu if (InputModifiers & SISrcMods::NEG) {
826c0bd7bd4SRichard Trieu if (OpNo + 1 < MI->getNumOperands() &&
827c0bd7bd4SRichard Trieu (InputModifiers & SISrcMods::ABS) == 0) {
828c0bd7bd4SRichard Trieu const MCOperand &Op = MI->getOperand(OpNo + 1);
829698c6b0aSDan Gohman NegMnemo = Op.isImm() || Op.isDFPImm();
830c0bd7bd4SRichard Trieu }
831c0bd7bd4SRichard Trieu if (NegMnemo) {
832c0bd7bd4SRichard Trieu O << "neg(";
833c0bd7bd4SRichard Trieu } else {
834c0bd7bd4SRichard Trieu O << '-';
835c0bd7bd4SRichard Trieu }
836c0bd7bd4SRichard Trieu }
837c0bd7bd4SRichard Trieu
838c0bd7bd4SRichard Trieu if (InputModifiers & SISrcMods::ABS)
839c0bd7bd4SRichard Trieu O << '|';
840be1082c6SJoe Nash printRegularOperand(MI, OpNo + 1, STI, O);
841c0bd7bd4SRichard Trieu if (InputModifiers & SISrcMods::ABS)
842c0bd7bd4SRichard Trieu O << '|';
843c0bd7bd4SRichard Trieu
844c0bd7bd4SRichard Trieu if (NegMnemo) {
845c0bd7bd4SRichard Trieu O << ')';
846c0bd7bd4SRichard Trieu }
847c0bd7bd4SRichard Trieu }
848c0bd7bd4SRichard Trieu
printOperandAndIntInputMods(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)849c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
850c0bd7bd4SRichard Trieu unsigned OpNo,
851c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
852c0bd7bd4SRichard Trieu raw_ostream &O) {
853be1082c6SJoe Nash const MCInstrDesc &Desc = MII.get(MI->getOpcode());
854be1082c6SJoe Nash if (needsImpliedVcc(Desc, OpNo))
855be1082c6SJoe Nash printDefaultVccOperand(true, STI, O);
856be1082c6SJoe Nash
857c0bd7bd4SRichard Trieu unsigned InputModifiers = MI->getOperand(OpNo).getImm();
858c0bd7bd4SRichard Trieu if (InputModifiers & SISrcMods::SEXT)
859c0bd7bd4SRichard Trieu O << "sext(";
860be1082c6SJoe Nash printRegularOperand(MI, OpNo + 1, STI, O);
861c0bd7bd4SRichard Trieu if (InputModifiers & SISrcMods::SEXT)
862c0bd7bd4SRichard Trieu O << ')';
863c0bd7bd4SRichard Trieu
8648bcc9bb5SStanislav Mekhanoshin // Print default vcc/vcc_lo operand of VOP2b.
865c0bd7bd4SRichard Trieu switch (MI->getOpcode()) {
866c0bd7bd4SRichard Trieu default: break;
867c0bd7bd4SRichard Trieu
8686c7d7eebSDmitry Preobrazhensky case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
869c0bd7bd4SRichard Trieu case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
870c0bd7bd4SRichard Trieu case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
871c0bd7bd4SRichard Trieu case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
872c0bd7bd4SRichard Trieu if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
873c0bd7bd4SRichard Trieu AMDGPU::OpName::src1))
874086a9c10SJoe Nash printDefaultVccOperand(OpNo == 0, STI, O);
875c0bd7bd4SRichard Trieu break;
876c0bd7bd4SRichard Trieu }
877c0bd7bd4SRichard Trieu }
878c0bd7bd4SRichard Trieu
printDPP8(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)879245b5ba3SStanislav Mekhanoshin void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
880245b5ba3SStanislav Mekhanoshin const MCSubtargetInfo &STI,
881245b5ba3SStanislav Mekhanoshin raw_ostream &O) {
8824f87d30aSJay Foad if (!AMDGPU::isGFX10Plus(STI))
883245b5ba3SStanislav Mekhanoshin llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
884245b5ba3SStanislav Mekhanoshin
885245b5ba3SStanislav Mekhanoshin unsigned Imm = MI->getOperand(OpNo).getImm();
886245b5ba3SStanislav Mekhanoshin O << "dpp8:[" << formatDec(Imm & 0x7);
887245b5ba3SStanislav Mekhanoshin for (size_t i = 1; i < 8; ++i) {
888245b5ba3SStanislav Mekhanoshin O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
889245b5ba3SStanislav Mekhanoshin }
890245b5ba3SStanislav Mekhanoshin O << ']';
891245b5ba3SStanislav Mekhanoshin }
892245b5ba3SStanislav Mekhanoshin
printDPPCtrl(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)893c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
894c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
895c0bd7bd4SRichard Trieu raw_ostream &O) {
896c0bd7bd4SRichard Trieu using namespace AMDGPU::DPP;
897c0bd7bd4SRichard Trieu
898c0bd7bd4SRichard Trieu unsigned Imm = MI->getOperand(OpNo).getImm();
899a8d9d507SStanislav Mekhanoshin const MCInstrDesc &Desc = MII.get(MI->getOpcode());
900a8d9d507SStanislav Mekhanoshin int Src0Idx = AMDGPU::getNamedOperandIdx(MI->getOpcode(),
901a8d9d507SStanislav Mekhanoshin AMDGPU::OpName::src0);
902a8d9d507SStanislav Mekhanoshin
90328f1d018SStanislav Mekhanoshin if (Src0Idx >= 0 &&
90428f1d018SStanislav Mekhanoshin Desc.OpInfo[Src0Idx].RegClass == AMDGPU::VReg_64RegClassID &&
905a8d9d507SStanislav Mekhanoshin !AMDGPU::isLegal64BitDPPControl(Imm)) {
906a8d9d507SStanislav Mekhanoshin O << " /* 64 bit dpp only supports row_newbcast */";
907a8d9d507SStanislav Mekhanoshin return;
908a8d9d507SStanislav Mekhanoshin } else if (Imm <= DppCtrl::QUAD_PERM_LAST) {
909c0bd7bd4SRichard Trieu O << "quad_perm:[";
910c0bd7bd4SRichard Trieu O << formatDec(Imm & 0x3) << ',';
911c0bd7bd4SRichard Trieu O << formatDec((Imm & 0xc) >> 2) << ',';
912c0bd7bd4SRichard Trieu O << formatDec((Imm & 0x30) >> 4) << ',';
913c0bd7bd4SRichard Trieu O << formatDec((Imm & 0xc0) >> 6) << ']';
914c0bd7bd4SRichard Trieu } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
915c0bd7bd4SRichard Trieu (Imm <= DppCtrl::ROW_SHL_LAST)) {
916c0bd7bd4SRichard Trieu O << "row_shl:";
917c0bd7bd4SRichard Trieu printU4ImmDecOperand(MI, OpNo, O);
918c0bd7bd4SRichard Trieu } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
919c0bd7bd4SRichard Trieu (Imm <= DppCtrl::ROW_SHR_LAST)) {
920c0bd7bd4SRichard Trieu O << "row_shr:";
921c0bd7bd4SRichard Trieu printU4ImmDecOperand(MI, OpNo, O);
922c0bd7bd4SRichard Trieu } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
923c0bd7bd4SRichard Trieu (Imm <= DppCtrl::ROW_ROR_LAST)) {
924c0bd7bd4SRichard Trieu O << "row_ror:";
925c0bd7bd4SRichard Trieu printU4ImmDecOperand(MI, OpNo, O);
926c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::WAVE_SHL1) {
9274f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
928245b5ba3SStanislav Mekhanoshin O << "/* wave_shl is not supported starting from GFX10 */";
929245b5ba3SStanislav Mekhanoshin return;
930245b5ba3SStanislav Mekhanoshin }
931c0bd7bd4SRichard Trieu O << "wave_shl:1";
932c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::WAVE_ROL1) {
9334f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
934245b5ba3SStanislav Mekhanoshin O << "/* wave_rol is not supported starting from GFX10 */";
935245b5ba3SStanislav Mekhanoshin return;
936245b5ba3SStanislav Mekhanoshin }
937c0bd7bd4SRichard Trieu O << "wave_rol:1";
938c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::WAVE_SHR1) {
9394f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
940245b5ba3SStanislav Mekhanoshin O << "/* wave_shr is not supported starting from GFX10 */";
941245b5ba3SStanislav Mekhanoshin return;
942245b5ba3SStanislav Mekhanoshin }
943c0bd7bd4SRichard Trieu O << "wave_shr:1";
944c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::WAVE_ROR1) {
9454f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
946245b5ba3SStanislav Mekhanoshin O << "/* wave_ror is not supported starting from GFX10 */";
947245b5ba3SStanislav Mekhanoshin return;
948245b5ba3SStanislav Mekhanoshin }
949c0bd7bd4SRichard Trieu O << "wave_ror:1";
950c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::ROW_MIRROR) {
951c0bd7bd4SRichard Trieu O << "row_mirror";
952c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
953c0bd7bd4SRichard Trieu O << "row_half_mirror";
954c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::BCAST15) {
9554f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
956245b5ba3SStanislav Mekhanoshin O << "/* row_bcast is not supported starting from GFX10 */";
957245b5ba3SStanislav Mekhanoshin return;
958245b5ba3SStanislav Mekhanoshin }
959c0bd7bd4SRichard Trieu O << "row_bcast:15";
960c0bd7bd4SRichard Trieu } else if (Imm == DppCtrl::BCAST31) {
9614f87d30aSJay Foad if (AMDGPU::isGFX10Plus(STI)) {
962245b5ba3SStanislav Mekhanoshin O << "/* row_bcast is not supported starting from GFX10 */";
963245b5ba3SStanislav Mekhanoshin return;
964245b5ba3SStanislav Mekhanoshin }
965c0bd7bd4SRichard Trieu O << "row_bcast:31";
966245b5ba3SStanislav Mekhanoshin } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
967245b5ba3SStanislav Mekhanoshin (Imm <= DppCtrl::ROW_SHARE_LAST)) {
968a8d9d507SStanislav Mekhanoshin if (AMDGPU::isGFX90A(STI)) {
969a8d9d507SStanislav Mekhanoshin O << "row_newbcast:";
970a8d9d507SStanislav Mekhanoshin } else if (AMDGPU::isGFX10Plus(STI)) {
971a8d9d507SStanislav Mekhanoshin O << "row_share:";
972a8d9d507SStanislav Mekhanoshin } else {
973a8d9d507SStanislav Mekhanoshin O << " /* row_newbcast/row_share is not supported on ASICs earlier "
974a8d9d507SStanislav Mekhanoshin "than GFX90A/GFX10 */";
975245b5ba3SStanislav Mekhanoshin return;
976245b5ba3SStanislav Mekhanoshin }
977245b5ba3SStanislav Mekhanoshin printU4ImmDecOperand(MI, OpNo, O);
978245b5ba3SStanislav Mekhanoshin } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
979245b5ba3SStanislav Mekhanoshin (Imm <= DppCtrl::ROW_XMASK_LAST)) {
9804f87d30aSJay Foad if (!AMDGPU::isGFX10Plus(STI)) {
981245b5ba3SStanislav Mekhanoshin O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
982245b5ba3SStanislav Mekhanoshin return;
983245b5ba3SStanislav Mekhanoshin }
984245b5ba3SStanislav Mekhanoshin O << "row_xmask:";
985245b5ba3SStanislav Mekhanoshin printU4ImmDecOperand(MI, OpNo, O);
986c0bd7bd4SRichard Trieu } else {
987c0bd7bd4SRichard Trieu O << "/* Invalid dpp_ctrl value */";
988c0bd7bd4SRichard Trieu }
989c0bd7bd4SRichard Trieu }
990c0bd7bd4SRichard Trieu
printRowMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)991c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
992c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
993c0bd7bd4SRichard Trieu raw_ostream &O) {
994c0bd7bd4SRichard Trieu O << " row_mask:";
995c0bd7bd4SRichard Trieu printU4ImmOperand(MI, OpNo, STI, O);
996c0bd7bd4SRichard Trieu }
997c0bd7bd4SRichard Trieu
printBankMask(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)998c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
999c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1000c0bd7bd4SRichard Trieu raw_ostream &O) {
1001c0bd7bd4SRichard Trieu O << " bank_mask:";
1002c0bd7bd4SRichard Trieu printU4ImmOperand(MI, OpNo, STI, O);
1003c0bd7bd4SRichard Trieu }
1004c0bd7bd4SRichard Trieu
printBoundCtrl(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1005c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
1006c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1007c0bd7bd4SRichard Trieu raw_ostream &O) {
1008c0bd7bd4SRichard Trieu unsigned Imm = MI->getOperand(OpNo).getImm();
1009c0bd7bd4SRichard Trieu if (Imm) {
101048135180SDmitry Preobrazhensky O << " bound_ctrl:1";
1011c0bd7bd4SRichard Trieu }
1012c0bd7bd4SRichard Trieu }
1013c0bd7bd4SRichard Trieu
printFI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1014245b5ba3SStanislav Mekhanoshin void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo,
1015245b5ba3SStanislav Mekhanoshin const MCSubtargetInfo &STI,
1016245b5ba3SStanislav Mekhanoshin raw_ostream &O) {
1017245b5ba3SStanislav Mekhanoshin using namespace llvm::AMDGPU::DPP;
1018245b5ba3SStanislav Mekhanoshin unsigned Imm = MI->getOperand(OpNo).getImm();
1019245b5ba3SStanislav Mekhanoshin if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
1020245b5ba3SStanislav Mekhanoshin O << " fi:1";
1021245b5ba3SStanislav Mekhanoshin }
1022245b5ba3SStanislav Mekhanoshin }
1023245b5ba3SStanislav Mekhanoshin
printSDWASel(const MCInst * MI,unsigned OpNo,raw_ostream & O)1024c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
1025c0bd7bd4SRichard Trieu raw_ostream &O) {
1026c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::SDWA;
1027c0bd7bd4SRichard Trieu
1028c0bd7bd4SRichard Trieu unsigned Imm = MI->getOperand(OpNo).getImm();
1029c0bd7bd4SRichard Trieu switch (Imm) {
1030c0bd7bd4SRichard Trieu case SdwaSel::BYTE_0: O << "BYTE_0"; break;
1031c0bd7bd4SRichard Trieu case SdwaSel::BYTE_1: O << "BYTE_1"; break;
1032c0bd7bd4SRichard Trieu case SdwaSel::BYTE_2: O << "BYTE_2"; break;
1033c0bd7bd4SRichard Trieu case SdwaSel::BYTE_3: O << "BYTE_3"; break;
1034c0bd7bd4SRichard Trieu case SdwaSel::WORD_0: O << "WORD_0"; break;
1035c0bd7bd4SRichard Trieu case SdwaSel::WORD_1: O << "WORD_1"; break;
1036c0bd7bd4SRichard Trieu case SdwaSel::DWORD: O << "DWORD"; break;
1037c0bd7bd4SRichard Trieu default: llvm_unreachable("Invalid SDWA data select operand");
1038c0bd7bd4SRichard Trieu }
1039c0bd7bd4SRichard Trieu }
1040c0bd7bd4SRichard Trieu
printSDWADstSel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1041c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
1042c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1043c0bd7bd4SRichard Trieu raw_ostream &O) {
1044c0bd7bd4SRichard Trieu O << "dst_sel:";
1045c0bd7bd4SRichard Trieu printSDWASel(MI, OpNo, O);
1046c0bd7bd4SRichard Trieu }
1047c0bd7bd4SRichard Trieu
printSDWASrc0Sel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1048c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
1049c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1050c0bd7bd4SRichard Trieu raw_ostream &O) {
1051c0bd7bd4SRichard Trieu O << "src0_sel:";
1052c0bd7bd4SRichard Trieu printSDWASel(MI, OpNo, O);
1053c0bd7bd4SRichard Trieu }
1054c0bd7bd4SRichard Trieu
printSDWASrc1Sel(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1055c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
1056c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1057c0bd7bd4SRichard Trieu raw_ostream &O) {
1058c0bd7bd4SRichard Trieu O << "src1_sel:";
1059c0bd7bd4SRichard Trieu printSDWASel(MI, OpNo, O);
1060c0bd7bd4SRichard Trieu }
1061c0bd7bd4SRichard Trieu
printSDWADstUnused(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1062c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
1063c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1064c0bd7bd4SRichard Trieu raw_ostream &O) {
1065c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::SDWA;
1066c0bd7bd4SRichard Trieu
1067c0bd7bd4SRichard Trieu O << "dst_unused:";
1068c0bd7bd4SRichard Trieu unsigned Imm = MI->getOperand(OpNo).getImm();
1069c0bd7bd4SRichard Trieu switch (Imm) {
1070c0bd7bd4SRichard Trieu case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
1071c0bd7bd4SRichard Trieu case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
1072c0bd7bd4SRichard Trieu case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
1073c0bd7bd4SRichard Trieu default: llvm_unreachable("Invalid SDWA dest_unused operand");
1074c0bd7bd4SRichard Trieu }
1075c0bd7bd4SRichard Trieu }
1076c0bd7bd4SRichard Trieu
printExpSrcN(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O,unsigned N)1077c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
107849dce855SJay Foad const MCSubtargetInfo &STI, raw_ostream &O,
107949dce855SJay Foad unsigned N) {
1080c0bd7bd4SRichard Trieu unsigned Opc = MI->getOpcode();
1081c0bd7bd4SRichard Trieu int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
1082c0bd7bd4SRichard Trieu unsigned En = MI->getOperand(EnIdx).getImm();
1083c0bd7bd4SRichard Trieu
1084c0bd7bd4SRichard Trieu int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
1085c0bd7bd4SRichard Trieu
1086c0bd7bd4SRichard Trieu // If compr is set, print as src0, src0, src1, src1
108749dce855SJay Foad if (MI->getOperand(ComprIdx).getImm())
108849dce855SJay Foad OpNo = OpNo - N + N / 2;
1089c0bd7bd4SRichard Trieu
1090c0bd7bd4SRichard Trieu if (En & (1 << N))
1091c0bd7bd4SRichard Trieu printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
1092c0bd7bd4SRichard Trieu else
1093c0bd7bd4SRichard Trieu O << "off";
1094c0bd7bd4SRichard Trieu }
1095c0bd7bd4SRichard Trieu
printExpSrc0(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1096c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
1097c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1098c0bd7bd4SRichard Trieu raw_ostream &O) {
109949dce855SJay Foad printExpSrcN(MI, OpNo, STI, O, 0);
1100c0bd7bd4SRichard Trieu }
1101c0bd7bd4SRichard Trieu
printExpSrc1(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1102c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
1103c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1104c0bd7bd4SRichard Trieu raw_ostream &O) {
110549dce855SJay Foad printExpSrcN(MI, OpNo, STI, O, 1);
1106c0bd7bd4SRichard Trieu }
1107c0bd7bd4SRichard Trieu
printExpSrc2(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1108c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
1109c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1110c0bd7bd4SRichard Trieu raw_ostream &O) {
111149dce855SJay Foad printExpSrcN(MI, OpNo, STI, O, 2);
1112c0bd7bd4SRichard Trieu }
1113c0bd7bd4SRichard Trieu
printExpSrc3(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1114c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
1115c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1116c0bd7bd4SRichard Trieu raw_ostream &O) {
111749dce855SJay Foad printExpSrcN(MI, OpNo, STI, O, 3);
1118c0bd7bd4SRichard Trieu }
1119c0bd7bd4SRichard Trieu
printExpTgt(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1120c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
1121c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1122c0bd7bd4SRichard Trieu raw_ostream &O) {
1123745064e3SDmitry Preobrazhensky using namespace llvm::AMDGPU::Exp;
1124c0bd7bd4SRichard Trieu
1125745064e3SDmitry Preobrazhensky // This is really a 6 bit field.
1126745064e3SDmitry Preobrazhensky unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1127745064e3SDmitry Preobrazhensky
1128745064e3SDmitry Preobrazhensky int Index;
1129745064e3SDmitry Preobrazhensky StringRef TgtName;
1130745064e3SDmitry Preobrazhensky if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1131745064e3SDmitry Preobrazhensky O << ' ' << TgtName;
1132745064e3SDmitry Preobrazhensky if (Index >= 0)
1133745064e3SDmitry Preobrazhensky O << Index;
1134745064e3SDmitry Preobrazhensky } else {
1135745064e3SDmitry Preobrazhensky O << " invalid_target_" << Id;
1136c0bd7bd4SRichard Trieu }
1137c0bd7bd4SRichard Trieu }
1138c0bd7bd4SRichard Trieu
allOpsDefaultValue(const int * Ops,int NumOps,int Mod,bool IsPacked,bool HasDstSel)1139c0bd7bd4SRichard Trieu static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
1140c0bd7bd4SRichard Trieu bool IsPacked, bool HasDstSel) {
1141c0bd7bd4SRichard Trieu int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
1142c0bd7bd4SRichard Trieu
1143c0bd7bd4SRichard Trieu for (int I = 0; I < NumOps; ++I) {
1144c0bd7bd4SRichard Trieu if (!!(Ops[I] & Mod) != DefaultValue)
1145c0bd7bd4SRichard Trieu return false;
1146c0bd7bd4SRichard Trieu }
1147c0bd7bd4SRichard Trieu
1148c0bd7bd4SRichard Trieu if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
1149c0bd7bd4SRichard Trieu return false;
1150c0bd7bd4SRichard Trieu
1151c0bd7bd4SRichard Trieu return true;
1152c0bd7bd4SRichard Trieu }
1153c0bd7bd4SRichard Trieu
printPackedModifier(const MCInst * MI,StringRef Name,unsigned Mod,raw_ostream & O)1154c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
1155c0bd7bd4SRichard Trieu StringRef Name,
1156c0bd7bd4SRichard Trieu unsigned Mod,
1157c0bd7bd4SRichard Trieu raw_ostream &O) {
1158c0bd7bd4SRichard Trieu unsigned Opc = MI->getOpcode();
1159c0bd7bd4SRichard Trieu int NumOps = 0;
1160c0bd7bd4SRichard Trieu int Ops[3];
1161c0bd7bd4SRichard Trieu
1162c0bd7bd4SRichard Trieu for (int OpName : { AMDGPU::OpName::src0_modifiers,
1163c0bd7bd4SRichard Trieu AMDGPU::OpName::src1_modifiers,
1164c0bd7bd4SRichard Trieu AMDGPU::OpName::src2_modifiers }) {
1165c0bd7bd4SRichard Trieu int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1166c0bd7bd4SRichard Trieu if (Idx == -1)
1167c0bd7bd4SRichard Trieu break;
1168c0bd7bd4SRichard Trieu
1169c0bd7bd4SRichard Trieu Ops[NumOps++] = MI->getOperand(Idx).getImm();
1170c0bd7bd4SRichard Trieu }
1171c0bd7bd4SRichard Trieu
1172c0bd7bd4SRichard Trieu const bool HasDstSel =
1173c0bd7bd4SRichard Trieu NumOps > 0 &&
1174c0bd7bd4SRichard Trieu Mod == SISrcMods::OP_SEL_0 &&
1175c0bd7bd4SRichard Trieu MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
1176c0bd7bd4SRichard Trieu
1177c0bd7bd4SRichard Trieu const bool IsPacked =
1178c0bd7bd4SRichard Trieu MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
1179c0bd7bd4SRichard Trieu
1180c0bd7bd4SRichard Trieu if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
1181c0bd7bd4SRichard Trieu return;
1182c0bd7bd4SRichard Trieu
1183c0bd7bd4SRichard Trieu O << Name;
1184c0bd7bd4SRichard Trieu for (int I = 0; I < NumOps; ++I) {
1185c0bd7bd4SRichard Trieu if (I != 0)
1186c0bd7bd4SRichard Trieu O << ',';
1187c0bd7bd4SRichard Trieu
1188c0bd7bd4SRichard Trieu O << !!(Ops[I] & Mod);
1189c0bd7bd4SRichard Trieu }
1190c0bd7bd4SRichard Trieu
1191c0bd7bd4SRichard Trieu if (HasDstSel) {
1192c0bd7bd4SRichard Trieu O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
1193c0bd7bd4SRichard Trieu }
1194c0bd7bd4SRichard Trieu
1195c0bd7bd4SRichard Trieu O << ']';
1196c0bd7bd4SRichard Trieu }
1197c0bd7bd4SRichard Trieu
printOpSel(const MCInst * MI,unsigned,const MCSubtargetInfo & STI,raw_ostream & O)1198c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
1199c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1200c0bd7bd4SRichard Trieu raw_ostream &O) {
12015f581c9fSStanislav Mekhanoshin unsigned Opc = MI->getOpcode();
12025f581c9fSStanislav Mekhanoshin if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
12035f581c9fSStanislav Mekhanoshin Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
12045f581c9fSStanislav Mekhanoshin auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
12055f581c9fSStanislav Mekhanoshin auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
12065f581c9fSStanislav Mekhanoshin unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
12075f581c9fSStanislav Mekhanoshin unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
12085f581c9fSStanislav Mekhanoshin if (FI || BC)
12095f581c9fSStanislav Mekhanoshin O << " op_sel:[" << FI << ',' << BC << ']';
12105f581c9fSStanislav Mekhanoshin return;
12115f581c9fSStanislav Mekhanoshin }
12125f581c9fSStanislav Mekhanoshin
1213c0bd7bd4SRichard Trieu printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
1214c0bd7bd4SRichard Trieu }
1215c0bd7bd4SRichard Trieu
printOpSelHi(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1216c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
1217c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1218c0bd7bd4SRichard Trieu raw_ostream &O) {
1219c0bd7bd4SRichard Trieu printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
1220c0bd7bd4SRichard Trieu }
1221c0bd7bd4SRichard Trieu
printNegLo(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1222c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
1223c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1224c0bd7bd4SRichard Trieu raw_ostream &O) {
1225c0bd7bd4SRichard Trieu printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
1226c0bd7bd4SRichard Trieu }
1227c0bd7bd4SRichard Trieu
printNegHi(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1228c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
1229c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1230c0bd7bd4SRichard Trieu raw_ostream &O) {
1231c0bd7bd4SRichard Trieu printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
1232c0bd7bd4SRichard Trieu }
1233c0bd7bd4SRichard Trieu
printInterpSlot(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1234c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
1235c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1236c0bd7bd4SRichard Trieu raw_ostream &O) {
1237c0bd7bd4SRichard Trieu unsigned Imm = MI->getOperand(OpNum).getImm();
1238c0bd7bd4SRichard Trieu switch (Imm) {
1239c0bd7bd4SRichard Trieu case 0:
1240c0bd7bd4SRichard Trieu O << "p10";
1241c0bd7bd4SRichard Trieu break;
1242c0bd7bd4SRichard Trieu case 1:
1243c0bd7bd4SRichard Trieu O << "p20";
1244c0bd7bd4SRichard Trieu break;
1245c0bd7bd4SRichard Trieu case 2:
1246c0bd7bd4SRichard Trieu O << "p0";
1247c0bd7bd4SRichard Trieu break;
1248c0bd7bd4SRichard Trieu default:
1249c0bd7bd4SRichard Trieu O << "invalid_param_" << Imm;
1250c0bd7bd4SRichard Trieu }
1251c0bd7bd4SRichard Trieu }
1252c0bd7bd4SRichard Trieu
printInterpAttr(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1253c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
1254c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1255c0bd7bd4SRichard Trieu raw_ostream &O) {
1256c0bd7bd4SRichard Trieu unsigned Attr = MI->getOperand(OpNum).getImm();
1257c0bd7bd4SRichard Trieu O << "attr" << Attr;
1258c0bd7bd4SRichard Trieu }
1259c0bd7bd4SRichard Trieu
printInterpAttrChan(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1260c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
1261c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1262c0bd7bd4SRichard Trieu raw_ostream &O) {
1263c0bd7bd4SRichard Trieu unsigned Chan = MI->getOperand(OpNum).getImm();
1264c0bd7bd4SRichard Trieu O << '.' << "xyzw"[Chan & 0x3];
1265c0bd7bd4SRichard Trieu }
1266c0bd7bd4SRichard Trieu
printVGPRIndexMode(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1267c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
1268c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1269c0bd7bd4SRichard Trieu raw_ostream &O) {
1270c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::VGPRIndexMode;
1271c0bd7bd4SRichard Trieu unsigned Val = MI->getOperand(OpNo).getImm();
1272c0bd7bd4SRichard Trieu
1273c0bd7bd4SRichard Trieu if ((Val & ~ENABLE_MASK) != 0) {
1274a442fad9SJay Foad O << formatHex(static_cast<uint64_t>(Val));
1275c0bd7bd4SRichard Trieu } else {
1276c0bd7bd4SRichard Trieu O << "gpr_idx(";
1277c0bd7bd4SRichard Trieu bool NeedComma = false;
1278c0bd7bd4SRichard Trieu for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
1279c0bd7bd4SRichard Trieu if (Val & (1 << ModeId)) {
1280c0bd7bd4SRichard Trieu if (NeedComma)
1281c0bd7bd4SRichard Trieu O << ',';
1282c0bd7bd4SRichard Trieu O << IdSymbolic[ModeId];
1283c0bd7bd4SRichard Trieu NeedComma = true;
1284c0bd7bd4SRichard Trieu }
1285c0bd7bd4SRichard Trieu }
1286c0bd7bd4SRichard Trieu O << ')';
1287c0bd7bd4SRichard Trieu }
1288c0bd7bd4SRichard Trieu }
1289c0bd7bd4SRichard Trieu
printMemOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1290c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
1291c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1292c0bd7bd4SRichard Trieu raw_ostream &O) {
1293be1082c6SJoe Nash printRegularOperand(MI, OpNo, STI, O);
1294c0bd7bd4SRichard Trieu O << ", ";
1295be1082c6SJoe Nash printRegularOperand(MI, OpNo + 1, STI, O);
1296c0bd7bd4SRichard Trieu }
1297c0bd7bd4SRichard Trieu
printIfSet(const MCInst * MI,unsigned OpNo,raw_ostream & O,StringRef Asm,StringRef Default)1298c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1299c0bd7bd4SRichard Trieu raw_ostream &O, StringRef Asm,
1300c0bd7bd4SRichard Trieu StringRef Default) {
1301c0bd7bd4SRichard Trieu const MCOperand &Op = MI->getOperand(OpNo);
1302c0bd7bd4SRichard Trieu assert(Op.isImm());
1303c0bd7bd4SRichard Trieu if (Op.getImm() == 1) {
1304c0bd7bd4SRichard Trieu O << Asm;
1305c0bd7bd4SRichard Trieu } else {
1306c0bd7bd4SRichard Trieu O << Default;
1307c0bd7bd4SRichard Trieu }
1308c0bd7bd4SRichard Trieu }
1309c0bd7bd4SRichard Trieu
printIfSet(const MCInst * MI,unsigned OpNo,raw_ostream & O,char Asm)1310c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
1311c0bd7bd4SRichard Trieu raw_ostream &O, char Asm) {
1312c0bd7bd4SRichard Trieu const MCOperand &Op = MI->getOperand(OpNo);
1313c0bd7bd4SRichard Trieu assert(Op.isImm());
1314c0bd7bd4SRichard Trieu if (Op.getImm() == 1)
1315c0bd7bd4SRichard Trieu O << Asm;
1316c0bd7bd4SRichard Trieu }
1317c0bd7bd4SRichard Trieu
printHigh(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1318c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo,
1319c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1320c0bd7bd4SRichard Trieu raw_ostream &O) {
13210ca41247SJay Foad printNamedBit(MI, OpNo, O, "high");
1322c0bd7bd4SRichard Trieu }
1323c0bd7bd4SRichard Trieu
printClampSI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1324c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
1325c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1326c0bd7bd4SRichard Trieu raw_ostream &O) {
13270ca41247SJay Foad printNamedBit(MI, OpNo, O, "clamp");
1328c0bd7bd4SRichard Trieu }
1329c0bd7bd4SRichard Trieu
printOModSI(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1330c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
1331c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1332c0bd7bd4SRichard Trieu raw_ostream &O) {
1333c0bd7bd4SRichard Trieu int Imm = MI->getOperand(OpNo).getImm();
1334c0bd7bd4SRichard Trieu if (Imm == SIOutMods::MUL2)
1335c0bd7bd4SRichard Trieu O << " mul:2";
1336c0bd7bd4SRichard Trieu else if (Imm == SIOutMods::MUL4)
1337c0bd7bd4SRichard Trieu O << " mul:4";
1338c0bd7bd4SRichard Trieu else if (Imm == SIOutMods::DIV2)
1339c0bd7bd4SRichard Trieu O << " div:2";
1340c0bd7bd4SRichard Trieu }
1341c0bd7bd4SRichard Trieu
printSendMsg(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1342c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
1343c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1344c0bd7bd4SRichard Trieu raw_ostream &O) {
1345c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::SendMsg;
1346c0bd7bd4SRichard Trieu
13471d572ce3SDmitry Preobrazhensky const unsigned Imm16 = MI->getOperand(OpNo).getImm();
13481d572ce3SDmitry Preobrazhensky
13491d572ce3SDmitry Preobrazhensky uint16_t MsgId;
13501d572ce3SDmitry Preobrazhensky uint16_t OpId;
13511d572ce3SDmitry Preobrazhensky uint16_t StreamId;
1352d21b9b49SJoe Nash decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
13531d572ce3SDmitry Preobrazhensky
13541d817a14SDmitry Preobrazhensky StringRef MsgName = getMsgName(MsgId, STI);
13551d817a14SDmitry Preobrazhensky
13561d817a14SDmitry Preobrazhensky if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
135767f06208SJay Foad isValidMsgStream(MsgId, OpId, StreamId, STI)) {
13581d817a14SDmitry Preobrazhensky O << "sendmsg(" << MsgName;
1359d21b9b49SJoe Nash if (msgRequiresOp(MsgId, STI)) {
1360d21b9b49SJoe Nash O << ", " << getMsgOpName(MsgId, OpId, STI);
1361d21b9b49SJoe Nash if (msgSupportsStream(MsgId, OpId, STI)) {
13621d572ce3SDmitry Preobrazhensky O << ", " << StreamId;
1363c0bd7bd4SRichard Trieu }
13641d572ce3SDmitry Preobrazhensky }
1365c0bd7bd4SRichard Trieu O << ')';
13661d572ce3SDmitry Preobrazhensky } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
13671d572ce3SDmitry Preobrazhensky O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
13681d572ce3SDmitry Preobrazhensky } else {
13691d572ce3SDmitry Preobrazhensky O << Imm16; // Unknown imm16 code.
1370c0bd7bd4SRichard Trieu }
1371c0bd7bd4SRichard Trieu }
1372c0bd7bd4SRichard Trieu
printSwizzleBitmask(const uint16_t AndMask,const uint16_t OrMask,const uint16_t XorMask,raw_ostream & O)1373c0bd7bd4SRichard Trieu static void printSwizzleBitmask(const uint16_t AndMask,
1374c0bd7bd4SRichard Trieu const uint16_t OrMask,
1375c0bd7bd4SRichard Trieu const uint16_t XorMask,
1376c0bd7bd4SRichard Trieu raw_ostream &O) {
1377c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::Swizzle;
1378c0bd7bd4SRichard Trieu
1379c0bd7bd4SRichard Trieu uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;
1380c0bd7bd4SRichard Trieu uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
1381c0bd7bd4SRichard Trieu
1382c0bd7bd4SRichard Trieu O << "\"";
1383c0bd7bd4SRichard Trieu
1384c0bd7bd4SRichard Trieu for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
1385c0bd7bd4SRichard Trieu uint16_t p0 = Probe0 & Mask;
1386c0bd7bd4SRichard Trieu uint16_t p1 = Probe1 & Mask;
1387c0bd7bd4SRichard Trieu
1388c0bd7bd4SRichard Trieu if (p0 == p1) {
1389c0bd7bd4SRichard Trieu if (p0 == 0) {
1390c0bd7bd4SRichard Trieu O << "0";
1391c0bd7bd4SRichard Trieu } else {
1392c0bd7bd4SRichard Trieu O << "1";
1393c0bd7bd4SRichard Trieu }
1394c0bd7bd4SRichard Trieu } else {
1395c0bd7bd4SRichard Trieu if (p0 == 0) {
1396c0bd7bd4SRichard Trieu O << "p";
1397c0bd7bd4SRichard Trieu } else {
1398c0bd7bd4SRichard Trieu O << "i";
1399c0bd7bd4SRichard Trieu }
1400c0bd7bd4SRichard Trieu }
1401c0bd7bd4SRichard Trieu }
1402c0bd7bd4SRichard Trieu
1403c0bd7bd4SRichard Trieu O << "\"";
1404c0bd7bd4SRichard Trieu }
1405c0bd7bd4SRichard Trieu
printSwizzle(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1406c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
1407c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1408c0bd7bd4SRichard Trieu raw_ostream &O) {
1409c0bd7bd4SRichard Trieu using namespace llvm::AMDGPU::Swizzle;
1410c0bd7bd4SRichard Trieu
1411c0bd7bd4SRichard Trieu uint16_t Imm = MI->getOperand(OpNo).getImm();
1412c0bd7bd4SRichard Trieu if (Imm == 0) {
1413c0bd7bd4SRichard Trieu return;
1414c0bd7bd4SRichard Trieu }
1415c0bd7bd4SRichard Trieu
1416c0bd7bd4SRichard Trieu O << " offset:";
1417c0bd7bd4SRichard Trieu
1418c0bd7bd4SRichard Trieu if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
1419c0bd7bd4SRichard Trieu
1420c0bd7bd4SRichard Trieu O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
1421c0bd7bd4SRichard Trieu for (unsigned I = 0; I < LANE_NUM; ++I) {
1422c0bd7bd4SRichard Trieu O << ",";
1423c0bd7bd4SRichard Trieu O << formatDec(Imm & LANE_MASK);
1424c0bd7bd4SRichard Trieu Imm >>= LANE_SHIFT;
1425c0bd7bd4SRichard Trieu }
1426c0bd7bd4SRichard Trieu O << ")";
1427c0bd7bd4SRichard Trieu
1428c0bd7bd4SRichard Trieu } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
1429c0bd7bd4SRichard Trieu
1430c0bd7bd4SRichard Trieu uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
1431c0bd7bd4SRichard Trieu uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;
1432c0bd7bd4SRichard Trieu uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
1433c0bd7bd4SRichard Trieu
1434c0bd7bd4SRichard Trieu if (AndMask == BITMASK_MAX &&
1435c0bd7bd4SRichard Trieu OrMask == 0 &&
1436c0bd7bd4SRichard Trieu countPopulation(XorMask) == 1) {
1437c0bd7bd4SRichard Trieu
1438c0bd7bd4SRichard Trieu O << "swizzle(" << IdSymbolic[ID_SWAP];
1439c0bd7bd4SRichard Trieu O << ",";
1440c0bd7bd4SRichard Trieu O << formatDec(XorMask);
1441c0bd7bd4SRichard Trieu O << ")";
1442c0bd7bd4SRichard Trieu
1443c0bd7bd4SRichard Trieu } else if (AndMask == BITMASK_MAX &&
1444c0bd7bd4SRichard Trieu OrMask == 0 && XorMask > 0 &&
1445c0bd7bd4SRichard Trieu isPowerOf2_64(XorMask + 1)) {
1446c0bd7bd4SRichard Trieu
1447c0bd7bd4SRichard Trieu O << "swizzle(" << IdSymbolic[ID_REVERSE];
1448c0bd7bd4SRichard Trieu O << ",";
1449c0bd7bd4SRichard Trieu O << formatDec(XorMask + 1);
1450c0bd7bd4SRichard Trieu O << ")";
1451c0bd7bd4SRichard Trieu
1452c0bd7bd4SRichard Trieu } else {
1453c0bd7bd4SRichard Trieu
1454c0bd7bd4SRichard Trieu uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
1455c0bd7bd4SRichard Trieu if (GroupSize > 1 &&
1456c0bd7bd4SRichard Trieu isPowerOf2_64(GroupSize) &&
1457c0bd7bd4SRichard Trieu OrMask < GroupSize &&
1458c0bd7bd4SRichard Trieu XorMask == 0) {
1459c0bd7bd4SRichard Trieu
1460c0bd7bd4SRichard Trieu O << "swizzle(" << IdSymbolic[ID_BROADCAST];
1461c0bd7bd4SRichard Trieu O << ",";
1462c0bd7bd4SRichard Trieu O << formatDec(GroupSize);
1463c0bd7bd4SRichard Trieu O << ",";
1464c0bd7bd4SRichard Trieu O << formatDec(OrMask);
1465c0bd7bd4SRichard Trieu O << ")";
1466c0bd7bd4SRichard Trieu
1467c0bd7bd4SRichard Trieu } else {
1468c0bd7bd4SRichard Trieu O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
1469c0bd7bd4SRichard Trieu O << ",";
1470c0bd7bd4SRichard Trieu printSwizzleBitmask(AndMask, OrMask, XorMask, O);
1471c0bd7bd4SRichard Trieu O << ")";
1472c0bd7bd4SRichard Trieu }
1473c0bd7bd4SRichard Trieu }
1474c0bd7bd4SRichard Trieu } else {
1475c0bd7bd4SRichard Trieu printU16ImmDecOperand(MI, OpNo, O);
1476c0bd7bd4SRichard Trieu }
1477c0bd7bd4SRichard Trieu }
1478c0bd7bd4SRichard Trieu
printWaitFlag(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1479c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
1480c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1481c0bd7bd4SRichard Trieu raw_ostream &O) {
1482c0bd7bd4SRichard Trieu AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
1483c0bd7bd4SRichard Trieu
1484c0bd7bd4SRichard Trieu unsigned SImm16 = MI->getOperand(OpNo).getImm();
1485c0bd7bd4SRichard Trieu unsigned Vmcnt, Expcnt, Lgkmcnt;
1486c0bd7bd4SRichard Trieu decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
1487c0bd7bd4SRichard Trieu
1488b5fb7e48SDmitry Preobrazhensky bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
1489b5fb7e48SDmitry Preobrazhensky bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
1490b5fb7e48SDmitry Preobrazhensky bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
1491b5fb7e48SDmitry Preobrazhensky bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
1492b5fb7e48SDmitry Preobrazhensky
1493c0bd7bd4SRichard Trieu bool NeedSpace = false;
1494c0bd7bd4SRichard Trieu
1495b5fb7e48SDmitry Preobrazhensky if (!IsDefaultVmcnt || PrintAll) {
1496c0bd7bd4SRichard Trieu O << "vmcnt(" << Vmcnt << ')';
1497c0bd7bd4SRichard Trieu NeedSpace = true;
1498c0bd7bd4SRichard Trieu }
1499c0bd7bd4SRichard Trieu
1500b5fb7e48SDmitry Preobrazhensky if (!IsDefaultExpcnt || PrintAll) {
1501c0bd7bd4SRichard Trieu if (NeedSpace)
1502c0bd7bd4SRichard Trieu O << ' ';
1503c0bd7bd4SRichard Trieu O << "expcnt(" << Expcnt << ')';
1504c0bd7bd4SRichard Trieu NeedSpace = true;
1505c0bd7bd4SRichard Trieu }
1506c0bd7bd4SRichard Trieu
1507b5fb7e48SDmitry Preobrazhensky if (!IsDefaultLgkmcnt || PrintAll) {
1508c0bd7bd4SRichard Trieu if (NeedSpace)
1509c0bd7bd4SRichard Trieu O << ' ';
1510c0bd7bd4SRichard Trieu O << "lgkmcnt(" << Lgkmcnt << ')';
1511c0bd7bd4SRichard Trieu }
1512c0bd7bd4SRichard Trieu }
1513c0bd7bd4SRichard Trieu
printDepCtr(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)15141f6aa903SDmitry Preobrazhensky void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
15151f6aa903SDmitry Preobrazhensky const MCSubtargetInfo &STI,
15161f6aa903SDmitry Preobrazhensky raw_ostream &O) {
15171f6aa903SDmitry Preobrazhensky using namespace llvm::AMDGPU::DepCtr;
15181f6aa903SDmitry Preobrazhensky
15191f6aa903SDmitry Preobrazhensky uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
15201f6aa903SDmitry Preobrazhensky
15211f6aa903SDmitry Preobrazhensky bool HasNonDefaultVal = false;
15221f6aa903SDmitry Preobrazhensky if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
15231f6aa903SDmitry Preobrazhensky int Id = 0;
15241f6aa903SDmitry Preobrazhensky StringRef Name;
15251f6aa903SDmitry Preobrazhensky unsigned Val;
15261f6aa903SDmitry Preobrazhensky bool IsDefault;
15271f6aa903SDmitry Preobrazhensky bool NeedSpace = false;
15281f6aa903SDmitry Preobrazhensky while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
15291f6aa903SDmitry Preobrazhensky if (!IsDefault || !HasNonDefaultVal) {
15301f6aa903SDmitry Preobrazhensky if (NeedSpace)
15311f6aa903SDmitry Preobrazhensky O << ' ';
15321f6aa903SDmitry Preobrazhensky O << Name << '(' << Val << ')';
15331f6aa903SDmitry Preobrazhensky NeedSpace = true;
15341f6aa903SDmitry Preobrazhensky }
15351f6aa903SDmitry Preobrazhensky }
15361f6aa903SDmitry Preobrazhensky } else {
15371f6aa903SDmitry Preobrazhensky O << formatHex(Imm16);
15381f6aa903SDmitry Preobrazhensky }
15391f6aa903SDmitry Preobrazhensky }
15401f6aa903SDmitry Preobrazhensky
printDelayFlag(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1541d21b9b49SJoe Nash void AMDGPUInstPrinter::printDelayFlag(const MCInst *MI, unsigned OpNo,
1542d21b9b49SJoe Nash const MCSubtargetInfo &STI,
1543d21b9b49SJoe Nash raw_ostream &O) {
1544d21b9b49SJoe Nash const char *BadInstId = "/* invalid instid value */";
1545d21b9b49SJoe Nash static const std::array<const char *, 12> InstIds = {
1546d21b9b49SJoe Nash "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",
1547d21b9b49SJoe Nash "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",
1548d21b9b49SJoe Nash "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
1549d21b9b49SJoe Nash "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};
1550d21b9b49SJoe Nash
1551d21b9b49SJoe Nash const char *BadInstSkip = "/* invalid instskip value */";
1552d21b9b49SJoe Nash static const std::array<const char *, 6> InstSkips = {
1553d21b9b49SJoe Nash "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
1554d21b9b49SJoe Nash
1555d21b9b49SJoe Nash unsigned SImm16 = MI->getOperand(OpNo).getImm();
1556d21b9b49SJoe Nash const char *Prefix = "";
1557d21b9b49SJoe Nash
1558d21b9b49SJoe Nash unsigned Value = SImm16 & 0xF;
1559d21b9b49SJoe Nash if (Value) {
1560d21b9b49SJoe Nash const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1561d21b9b49SJoe Nash O << Prefix << "instid0(" << Name << ')';
1562d21b9b49SJoe Nash Prefix = " | ";
1563d21b9b49SJoe Nash }
1564d21b9b49SJoe Nash
1565d21b9b49SJoe Nash Value = (SImm16 >> 4) & 7;
1566d21b9b49SJoe Nash if (Value) {
1567d21b9b49SJoe Nash const char *Name =
1568d21b9b49SJoe Nash Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
1569d21b9b49SJoe Nash O << Prefix << "instskip(" << Name << ')';
1570d21b9b49SJoe Nash Prefix = " | ";
1571d21b9b49SJoe Nash }
1572d21b9b49SJoe Nash
1573d21b9b49SJoe Nash Value = (SImm16 >> 7) & 0xF;
1574d21b9b49SJoe Nash if (Value) {
1575d21b9b49SJoe Nash const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
1576d21b9b49SJoe Nash O << Prefix << "instid1(" << Name << ')';
1577d21b9b49SJoe Nash Prefix = " | ";
1578d21b9b49SJoe Nash }
1579d21b9b49SJoe Nash
1580d21b9b49SJoe Nash if (!*Prefix)
1581d21b9b49SJoe Nash O << "0";
1582d21b9b49SJoe Nash }
1583d21b9b49SJoe Nash
printHwreg(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1584c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
1585c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI, raw_ostream &O) {
15861fca3b19SDmitry Preobrazhensky unsigned Id;
15871fca3b19SDmitry Preobrazhensky unsigned Offset;
15881fca3b19SDmitry Preobrazhensky unsigned Width;
1589c0bd7bd4SRichard Trieu
15901fca3b19SDmitry Preobrazhensky using namespace llvm::AMDGPU::Hwreg;
15911fca3b19SDmitry Preobrazhensky unsigned Val = MI->getOperand(OpNo).getImm();
15921fca3b19SDmitry Preobrazhensky decodeHwreg(Val, Id, Offset, Width);
15931fca3b19SDmitry Preobrazhensky StringRef HwRegName = getHwreg(Id, STI);
1594c0bd7bd4SRichard Trieu
1595c0bd7bd4SRichard Trieu O << "hwreg(";
15961fca3b19SDmitry Preobrazhensky if (!HwRegName.empty()) {
15971fca3b19SDmitry Preobrazhensky O << HwRegName;
1598c0bd7bd4SRichard Trieu } else {
1599c0bd7bd4SRichard Trieu O << Id;
1600c0bd7bd4SRichard Trieu }
16011fca3b19SDmitry Preobrazhensky if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) {
1602c0bd7bd4SRichard Trieu O << ", " << Offset << ", " << Width;
1603c0bd7bd4SRichard Trieu }
1604c0bd7bd4SRichard Trieu O << ')';
1605c0bd7bd4SRichard Trieu }
1606c0bd7bd4SRichard Trieu
printEndpgm(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)1607c0bd7bd4SRichard Trieu void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
1608c0bd7bd4SRichard Trieu const MCSubtargetInfo &STI,
1609c0bd7bd4SRichard Trieu raw_ostream &O) {
1610c0bd7bd4SRichard Trieu uint16_t Imm = MI->getOperand(OpNo).getImm();
1611c0bd7bd4SRichard Trieu if (Imm == 0) {
1612c0bd7bd4SRichard Trieu return;
1613c0bd7bd4SRichard Trieu }
1614c0bd7bd4SRichard Trieu
161574d67c20SMatt Arsenault O << ' ' << formatDec(Imm);
1616c0bd7bd4SRichard Trieu }
1617c0bd7bd4SRichard Trieu
1618c0bd7bd4SRichard Trieu #include "AMDGPUGenAsmWriter.inc"
1619