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