xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric // \file
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #include "AMDGPUInstPrinter.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
120b57cec5SDimitry Andric #include "SIDefines.h"
130b57cec5SDimitry Andric #include "Utils/AMDGPUAsmUtils.h"
140b57cec5SDimitry Andric #include "Utils/AMDGPUBaseInfo.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
195f757f3fSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
215ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
2206c3fb27SDimitry Andric #include "llvm/TargetParser/TargetParser.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
250b57cec5SDimitry Andric using namespace llvm::AMDGPU;
260b57cec5SDimitry Andric 
27bdd1243dSDimitry Andric void AMDGPUInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
285ffd83dbSDimitry Andric   // FIXME: The current implementation of
295ffd83dbSDimitry Andric   // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this
305ffd83dbSDimitry Andric   // as an integer or we provide a name which represents a physical register.
315ffd83dbSDimitry Andric   // For CFI instructions we really want to emit a name for the DWARF register
325ffd83dbSDimitry Andric   // instead, because there may be multiple DWARF registers corresponding to a
335ffd83dbSDimitry Andric   // single physical register. One case where this problem manifests is with
345ffd83dbSDimitry Andric   // wave32/wave64 where using the physical register name is ambiguous: if we
355ffd83dbSDimitry Andric   // write e.g. `.cfi_undefined v0` we lose information about the wavefront
365ffd83dbSDimitry Andric   // size which we need to encode the register in the final DWARF. Ideally we
375ffd83dbSDimitry Andric   // would extend MC to support parsing DWARF register names so we could do
385ffd83dbSDimitry Andric   // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with
395ffd83dbSDimitry Andric   // non-pretty DWARF register names in assembly text.
40bdd1243dSDimitry Andric   OS << Reg.id();
415ffd83dbSDimitry Andric }
425ffd83dbSDimitry Andric 
43480093f4SDimitry Andric void AMDGPUInstPrinter::printInst(const MCInst *MI, uint64_t Address,
44480093f4SDimitry Andric                                   StringRef Annot, const MCSubtargetInfo &STI,
45480093f4SDimitry Andric                                   raw_ostream &OS) {
46480093f4SDimitry Andric   printInstruction(MI, Address, STI, OS);
470b57cec5SDimitry Andric   printAnnotation(OS, Annot);
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
510b57cec5SDimitry Andric                                           const MCSubtargetInfo &STI,
520b57cec5SDimitry Andric                                           raw_ostream &O) {
530b57cec5SDimitry Andric   O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
570b57cec5SDimitry Andric                                            const MCSubtargetInfo &STI,
580b57cec5SDimitry Andric                                            raw_ostream &O) {
59*0fca6ea1SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
60*0fca6ea1SDimitry Andric   if (Op.isExpr()) {
61*0fca6ea1SDimitry Andric     Op.getExpr()->print(O, &MAI);
62*0fca6ea1SDimitry Andric     return;
63*0fca6ea1SDimitry Andric   }
64*0fca6ea1SDimitry Andric 
650b57cec5SDimitry Andric   // It's possible to end up with a 32-bit literal used with a 16-bit operand
660b57cec5SDimitry Andric   // with ignored high bits. Print as 32-bit anyway in that case.
67*0fca6ea1SDimitry Andric   int64_t Imm = Op.getImm();
680b57cec5SDimitry Andric   if (isInt<16>(Imm) || isUInt<16>(Imm))
690b57cec5SDimitry Andric     O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
700b57cec5SDimitry Andric   else
710b57cec5SDimitry Andric     printU32ImmOperand(MI, OpNo, STI, O);
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
750b57cec5SDimitry Andric                                              raw_ostream &O) {
760b57cec5SDimitry Andric   O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
800b57cec5SDimitry Andric                                              raw_ostream &O) {
810b57cec5SDimitry Andric   O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
850b57cec5SDimitry Andric                                               raw_ostream &O) {
860b57cec5SDimitry Andric   O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
900b57cec5SDimitry Andric                                            const MCSubtargetInfo &STI,
910b57cec5SDimitry Andric                                            raw_ostream &O) {
920b57cec5SDimitry Andric   O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
960b57cec5SDimitry Andric                                       raw_ostream &O, StringRef BitName) {
970b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getImm()) {
980b57cec5SDimitry Andric     O << ' ' << BitName;
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
1030b57cec5SDimitry Andric                                     const MCSubtargetInfo &STI,
1040b57cec5SDimitry Andric                                     raw_ostream &O) {
1055f757f3fSDimitry Andric   uint32_t Imm = MI->getOperand(OpNo).getImm();
1060b57cec5SDimitry Andric   if (Imm != 0) {
107e8d8bef9SDimitry Andric     O << " offset:";
1085f757f3fSDimitry Andric 
1095f757f3fSDimitry Andric     // GFX12 uses a 24-bit signed offset for VBUFFER.
1105f757f3fSDimitry Andric     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1115f757f3fSDimitry Andric     bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);
1125f757f3fSDimitry Andric     if (AMDGPU::isGFX12(STI) && IsVBuffer)
1135f757f3fSDimitry Andric       O << formatDec(SignExtend32<24>(Imm));
1145f757f3fSDimitry Andric     else
1150b57cec5SDimitry Andric       printU16ImmDecOperand(MI, OpNo, O);
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,
1200b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
1210b57cec5SDimitry Andric                                         raw_ostream &O) {
1225f757f3fSDimitry Andric   uint32_t Imm = MI->getOperand(OpNo).getImm();
1230b57cec5SDimitry Andric   if (Imm != 0) {
124e8d8bef9SDimitry Andric     O << " offset:";
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric     const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1275f757f3fSDimitry Andric     bool AllowNegative = (Desc.TSFlags & (SIInstrFlags::FlatGlobal |
1285f757f3fSDimitry Andric                                           SIInstrFlags::FlatScratch)) ||
1295f757f3fSDimitry Andric                          AMDGPU::isGFX12(STI);
1300b57cec5SDimitry Andric 
1315f757f3fSDimitry Andric     if (AllowNegative) // Signed offset
13206c3fb27SDimitry Andric       O << formatDec(SignExtend32(Imm, AMDGPU::getNumFlatOffsetBits(STI)));
1335f757f3fSDimitry Andric     else // Unsigned offset
1345f757f3fSDimitry Andric       printU16ImmDecOperand(MI, OpNo, O);
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
1390b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
1400b57cec5SDimitry Andric                                      raw_ostream &O) {
1410b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getImm()) {
1420b57cec5SDimitry Andric     O << " offset0:";
1430b57cec5SDimitry Andric     printU8ImmDecOperand(MI, OpNo, O);
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
1480b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
1490b57cec5SDimitry Andric                                      raw_ostream &O) {
1500b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getImm()) {
1510b57cec5SDimitry Andric     O << " offset1:";
1520b57cec5SDimitry Andric     printU8ImmDecOperand(MI, OpNo, O);
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
1570b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
1580b57cec5SDimitry Andric                                         raw_ostream &O) {
1590b57cec5SDimitry Andric   printU32ImmOperand(MI, OpNo, STI, O);
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1625ffd83dbSDimitry Andric void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,
1630b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
1640b57cec5SDimitry Andric                                         raw_ostream &O) {
1655ffd83dbSDimitry Andric   O << formatHex(MI->getOperand(OpNo).getImm());
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
16881ad6265SDimitry Andric void AMDGPUInstPrinter::printSMEMOffsetMod(const MCInst *MI, unsigned OpNo,
16981ad6265SDimitry Andric                                            const MCSubtargetInfo &STI,
17081ad6265SDimitry Andric                                            raw_ostream &O) {
17181ad6265SDimitry Andric   O << " offset:";
17281ad6265SDimitry Andric   printSMEMOffset(MI, OpNo, STI, O);
17381ad6265SDimitry Andric }
17481ad6265SDimitry Andric 
1750b57cec5SDimitry Andric void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
1760b57cec5SDimitry Andric                                                const MCSubtargetInfo &STI,
1770b57cec5SDimitry Andric                                                raw_ostream &O) {
1780b57cec5SDimitry Andric   printU32ImmOperand(MI, OpNo, STI, O);
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
181fe6060f1SDimitry Andric void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,
1820b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
183fe6060f1SDimitry Andric   auto Imm = MI->getOperand(OpNo).getImm();
1845f757f3fSDimitry Andric 
1855f757f3fSDimitry Andric   if (AMDGPU::isGFX12Plus(STI)) {
1865f757f3fSDimitry Andric     const int64_t TH = Imm & CPol::TH;
1875f757f3fSDimitry Andric     const int64_t Scope = Imm & CPol::SCOPE;
1885f757f3fSDimitry Andric 
1895f757f3fSDimitry Andric     printTH(MI, TH, Scope, O);
1905f757f3fSDimitry Andric     printScope(Scope, O);
1915f757f3fSDimitry Andric 
1925f757f3fSDimitry Andric     return;
1935f757f3fSDimitry Andric   }
1945f757f3fSDimitry Andric 
195fe6060f1SDimitry Andric   if (Imm & CPol::GLC)
19681ad6265SDimitry Andric     O << ((AMDGPU::isGFX940(STI) &&
19781ad6265SDimitry Andric            !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"
19881ad6265SDimitry Andric                                                                      : " glc");
199fe6060f1SDimitry Andric   if (Imm & CPol::SLC)
20081ad6265SDimitry Andric     O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");
201fe6060f1SDimitry Andric   if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))
202fe6060f1SDimitry Andric     O << " dlc";
203fe6060f1SDimitry Andric   if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))
20481ad6265SDimitry Andric     O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");
205fe6060f1SDimitry Andric   if (Imm & ~CPol::ALL)
206fe6060f1SDimitry Andric     O << " /* unexpected cache policy bit */";
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2095f757f3fSDimitry Andric void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,
2105f757f3fSDimitry Andric                                 raw_ostream &O) {
2115f757f3fSDimitry Andric   // For th = 0 do not print this field
2125f757f3fSDimitry Andric   if (TH == 0)
2135f757f3fSDimitry Andric     return;
2145f757f3fSDimitry Andric 
2155f757f3fSDimitry Andric   const unsigned Opcode = MI->getOpcode();
2165f757f3fSDimitry Andric   const MCInstrDesc &TID = MII.get(Opcode);
2175f757f3fSDimitry Andric   bool IsStore = TID.mayStore();
2185f757f3fSDimitry Andric   bool IsAtomic =
2195f757f3fSDimitry Andric       TID.TSFlags & (SIInstrFlags::IsAtomicNoRet | SIInstrFlags::IsAtomicRet);
2205f757f3fSDimitry Andric 
2215f757f3fSDimitry Andric   O << " th:";
2225f757f3fSDimitry Andric 
2235f757f3fSDimitry Andric   if (IsAtomic) {
2245f757f3fSDimitry Andric     O << "TH_ATOMIC_";
2255f757f3fSDimitry Andric     if (TH & AMDGPU::CPol::TH_ATOMIC_CASCADE) {
2265f757f3fSDimitry Andric       if (Scope >= AMDGPU::CPol::SCOPE_DEV)
2275f757f3fSDimitry Andric         O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");
2285f757f3fSDimitry Andric       else
2295f757f3fSDimitry Andric         O << formatHex(TH);
2305f757f3fSDimitry Andric     } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)
2315f757f3fSDimitry Andric       O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");
2325f757f3fSDimitry Andric     else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)
2335f757f3fSDimitry Andric       O << "RETURN";
2345f757f3fSDimitry Andric     else
2355f757f3fSDimitry Andric       O << formatHex(TH);
2365f757f3fSDimitry Andric   } else {
2375f757f3fSDimitry Andric     if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)
2385f757f3fSDimitry Andric       O << formatHex(TH);
2395f757f3fSDimitry Andric     else {
2405f757f3fSDimitry Andric       // This will default to printing load variants when neither MayStore nor
2415f757f3fSDimitry Andric       // MayLoad flag is present which is the case with instructions like
2425f757f3fSDimitry Andric       // image_get_resinfo.
2435f757f3fSDimitry Andric       O << (IsStore ? "TH_STORE_" : "TH_LOAD_");
2445f757f3fSDimitry Andric       switch (TH) {
2455f757f3fSDimitry Andric       case AMDGPU::CPol::TH_NT:
2465f757f3fSDimitry Andric         O << "NT";
2475f757f3fSDimitry Andric         break;
2485f757f3fSDimitry Andric       case AMDGPU::CPol::TH_HT:
2495f757f3fSDimitry Andric         O << "HT";
2505f757f3fSDimitry Andric         break;
2515f757f3fSDimitry Andric       case AMDGPU::CPol::TH_BYPASS: // or LU or RT_WB
2525f757f3fSDimitry Andric         O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"
2535f757f3fSDimitry Andric                                                : (IsStore ? "RT_WB" : "LU"));
2545f757f3fSDimitry Andric         break;
2555f757f3fSDimitry Andric       case AMDGPU::CPol::TH_NT_RT:
2565f757f3fSDimitry Andric         O << "NT_RT";
2575f757f3fSDimitry Andric         break;
2585f757f3fSDimitry Andric       case AMDGPU::CPol::TH_RT_NT:
2595f757f3fSDimitry Andric         O << "RT_NT";
2605f757f3fSDimitry Andric         break;
2615f757f3fSDimitry Andric       case AMDGPU::CPol::TH_NT_HT:
2625f757f3fSDimitry Andric         O << "NT_HT";
2635f757f3fSDimitry Andric         break;
2645f757f3fSDimitry Andric       case AMDGPU::CPol::TH_NT_WB:
2655f757f3fSDimitry Andric         O << "NT_WB";
2665f757f3fSDimitry Andric         break;
2675f757f3fSDimitry Andric       default:
2685f757f3fSDimitry Andric         llvm_unreachable("unexpected th value");
2695f757f3fSDimitry Andric       }
2705f757f3fSDimitry Andric     }
2715f757f3fSDimitry Andric   }
2725f757f3fSDimitry Andric }
2735f757f3fSDimitry Andric 
2745f757f3fSDimitry Andric void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {
2755f757f3fSDimitry Andric   if (Scope == CPol::SCOPE_CU)
2765f757f3fSDimitry Andric     return;
2775f757f3fSDimitry Andric 
2785f757f3fSDimitry Andric   O << " scope:";
2795f757f3fSDimitry Andric 
2805f757f3fSDimitry Andric   if (Scope == CPol::SCOPE_SE)
2815f757f3fSDimitry Andric     O << "SCOPE_SE";
2825f757f3fSDimitry Andric   else if (Scope == CPol::SCOPE_DEV)
2835f757f3fSDimitry Andric     O << "SCOPE_DEV";
2845f757f3fSDimitry Andric   else if (Scope == CPol::SCOPE_SYS)
2855f757f3fSDimitry Andric     O << "SCOPE_SYS";
2865f757f3fSDimitry Andric   else
2875f757f3fSDimitry Andric     llvm_unreachable("unexpected scope policy value");
2885f757f3fSDimitry Andric 
2895f757f3fSDimitry Andric   return;
2905f757f3fSDimitry Andric }
2915f757f3fSDimitry Andric 
2920b57cec5SDimitry Andric void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
2930b57cec5SDimitry Andric                                    const MCSubtargetInfo &STI, raw_ostream &O) {
2940b57cec5SDimitry Andric   if (MI->getOperand(OpNo).getImm()) {
2950b57cec5SDimitry Andric     O << " dmask:";
2960b57cec5SDimitry Andric     printU16ImmOperand(MI, OpNo, STI, O);
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,
3010b57cec5SDimitry Andric                                  const MCSubtargetInfo &STI, raw_ostream &O) {
3020b57cec5SDimitry Andric   unsigned Dim = MI->getOperand(OpNo).getImm();
3030b57cec5SDimitry Andric   O << " dim:SQ_RSRC_IMG_";
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);
3060b57cec5SDimitry Andric   if (DimInfo)
3070b57cec5SDimitry Andric     O << DimInfo->AsmSuffix;
3080b57cec5SDimitry Andric   else
3090b57cec5SDimitry Andric     O << Dim;
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,
3130b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI, raw_ostream &O) {
3140b57cec5SDimitry Andric   if (STI.hasFeature(AMDGPU::FeatureR128A16))
3150b57cec5SDimitry Andric     printNamedBit(MI, OpNo, O, "a16");
3160b57cec5SDimitry Andric   else
3170b57cec5SDimitry Andric     printNamedBit(MI, OpNo, O, "r128");
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,
3210b57cec5SDimitry Andric                                     const MCSubtargetInfo &STI,
3220b57cec5SDimitry Andric                                     raw_ostream &O) {
323e8d8bef9SDimitry Andric }
324e8d8bef9SDimitry Andric 
325e8d8bef9SDimitry Andric void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
326e8d8bef9SDimitry Andric                                             const MCSubtargetInfo &STI,
327e8d8bef9SDimitry Andric                                             raw_ostream &O) {
328e8d8bef9SDimitry Andric   using namespace llvm::AMDGPU::MTBUFFormat;
329e8d8bef9SDimitry Andric 
330e8d8bef9SDimitry Andric   int OpNo =
331e8d8bef9SDimitry Andric     AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);
332e8d8bef9SDimitry Andric   assert(OpNo != -1);
333e8d8bef9SDimitry Andric 
334e8d8bef9SDimitry Andric   unsigned Val = MI->getOperand(OpNo).getImm();
335e8d8bef9SDimitry Andric   if (AMDGPU::isGFX10Plus(STI)) {
336e8d8bef9SDimitry Andric     if (Val == UFMT_DEFAULT)
337e8d8bef9SDimitry Andric       return;
33881ad6265SDimitry Andric     if (isValidUnifiedFormat(Val, STI)) {
33981ad6265SDimitry Andric       O << " format:[" << getUnifiedFormatName(Val, STI) << ']';
340e8d8bef9SDimitry Andric     } else {
3410b57cec5SDimitry Andric       O << " format:" << Val;
342e8d8bef9SDimitry Andric     }
343e8d8bef9SDimitry Andric   } else {
344e8d8bef9SDimitry Andric     if (Val == DFMT_NFMT_DEFAULT)
345e8d8bef9SDimitry Andric       return;
346e8d8bef9SDimitry Andric     if (isValidDfmtNfmt(Val, STI)) {
347e8d8bef9SDimitry Andric       unsigned Dfmt;
348e8d8bef9SDimitry Andric       unsigned Nfmt;
349e8d8bef9SDimitry Andric       decodeDfmtNfmt(Val, Dfmt, Nfmt);
350e8d8bef9SDimitry Andric       O << " format:[";
351e8d8bef9SDimitry Andric       if (Dfmt != DFMT_DEFAULT) {
352e8d8bef9SDimitry Andric         O << getDfmtName(Dfmt);
353e8d8bef9SDimitry Andric         if (Nfmt != NFMT_DEFAULT) {
354e8d8bef9SDimitry Andric           O << ',';
355e8d8bef9SDimitry Andric         }
356e8d8bef9SDimitry Andric       }
357e8d8bef9SDimitry Andric       if (Nfmt != NFMT_DEFAULT) {
358e8d8bef9SDimitry Andric         O << getNfmtName(Nfmt, STI);
359e8d8bef9SDimitry Andric       }
360e8d8bef9SDimitry Andric       O << ']';
361e8d8bef9SDimitry Andric     } else {
362e8d8bef9SDimitry Andric       O << " format:" << Val;
3630b57cec5SDimitry Andric     }
3640b57cec5SDimitry Andric   }
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O,
3680b57cec5SDimitry Andric                                         const MCRegisterInfo &MRI) {
3690b57cec5SDimitry Andric #if !defined(NDEBUG)
3700b57cec5SDimitry Andric   switch (RegNo) {
3710b57cec5SDimitry Andric   case AMDGPU::FP_REG:
3720b57cec5SDimitry Andric   case AMDGPU::SP_REG:
3730b57cec5SDimitry Andric   case AMDGPU::PRIVATE_RSRC_REG:
3740b57cec5SDimitry Andric     llvm_unreachable("pseudo-register should not ever be emitted");
3750b57cec5SDimitry Andric   case AMDGPU::SCC:
3760b57cec5SDimitry Andric     llvm_unreachable("pseudo scc should not ever be emitted");
3770b57cec5SDimitry Andric   default:
3780b57cec5SDimitry Andric     break;
3790b57cec5SDimitry Andric   }
3800b57cec5SDimitry Andric #endif
3810b57cec5SDimitry Andric 
3825f757f3fSDimitry Andric   O << getRegisterName(RegNo);
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
38681ad6265SDimitry Andric                                     const MCSubtargetInfo &STI, raw_ostream &O) {
387fe6060f1SDimitry Andric   auto Opcode = MI->getOpcode();
388fe6060f1SDimitry Andric   auto Flags = MII.get(Opcode).TSFlags;
3890b57cec5SDimitry Andric   if (OpNo == 0) {
39081ad6265SDimitry Andric     if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)
39181ad6265SDimitry Andric       O << "_e64_dpp";
39281ad6265SDimitry Andric     else if (Flags & SIInstrFlags::VOP3) {
393fe6060f1SDimitry Andric       if (!getVOP3IsSingle(Opcode))
3940b57cec5SDimitry Andric         O << "_e64";
39581ad6265SDimitry Andric     } else if (Flags & SIInstrFlags::DPP)
3960b57cec5SDimitry Andric       O << "_dpp";
39781ad6265SDimitry Andric     else if (Flags & SIInstrFlags::SDWA)
3980b57cec5SDimitry Andric       O << "_sdwa";
39981ad6265SDimitry Andric     else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||
40081ad6265SDimitry Andric              ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))
4010b57cec5SDimitry Andric       O << "_e32";
402fe6060f1SDimitry Andric     O << " ";
403fe6060f1SDimitry Andric   }
4040b57cec5SDimitry Andric 
40581ad6265SDimitry Andric   printRegularOperand(MI, OpNo, STI, O);
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   // Print default vcc/vcc_lo operand.
408fe6060f1SDimitry Andric   switch (Opcode) {
4090b57cec5SDimitry Andric   default: break;
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
4120b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
4130b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4140b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
4150b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
4160b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
4170b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
4180b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
4190b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
4200b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
4210b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
4220b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
42381ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
42481ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
42581ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
42681ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
42781ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
42881ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
42981ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
43081ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
43181ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
4325f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
4335f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
4345f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
4355f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
4365f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
4375f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
4385f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
4395f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
4405f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
44181ad6265SDimitry Andric     printDefaultVccOperand(false, STI, O);
4420b57cec5SDimitry Andric     break;
4430b57cec5SDimitry Andric   }
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,
4470b57cec5SDimitry Andric                                        const MCSubtargetInfo &STI, raw_ostream &O) {
4480b57cec5SDimitry Andric   if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))
4490b57cec5SDimitry Andric     O << " ";
4500b57cec5SDimitry Andric   else
4510b57cec5SDimitry Andric     O << "_e32 ";
4520b57cec5SDimitry Andric 
45381ad6265SDimitry Andric   printRegularOperand(MI, OpNo, STI, O);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
4565ffd83dbSDimitry Andric void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,
4575ffd83dbSDimitry Andric                                             const MCSubtargetInfo &STI,
4585ffd83dbSDimitry Andric                                             raw_ostream &O) {
459*0fca6ea1SDimitry Andric   int32_t SImm = static_cast<int32_t>(Imm);
460e8d8bef9SDimitry Andric   if (isInlinableIntLiteral(SImm)) {
4615ffd83dbSDimitry Andric     O << SImm;
462*0fca6ea1SDimitry Andric     return;
4635ffd83dbSDimitry Andric   }
4645ffd83dbSDimitry Andric 
465*0fca6ea1SDimitry Andric   if (printImmediateFloat32(Imm, STI, O))
466*0fca6ea1SDimitry Andric     return;
467*0fca6ea1SDimitry Andric 
468*0fca6ea1SDimitry Andric   O << formatHex(static_cast<uint64_t>(Imm & 0xffff));
469*0fca6ea1SDimitry Andric }
470*0fca6ea1SDimitry Andric 
471*0fca6ea1SDimitry Andric static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI,
4720b57cec5SDimitry Andric                                raw_ostream &O) {
4730b57cec5SDimitry Andric   if (Imm == 0x3C00)
4740b57cec5SDimitry Andric     O << "1.0";
4750b57cec5SDimitry Andric   else if (Imm == 0xBC00)
4760b57cec5SDimitry Andric     O << "-1.0";
4770b57cec5SDimitry Andric   else if (Imm == 0x3800)
4780b57cec5SDimitry Andric     O << "0.5";
4790b57cec5SDimitry Andric   else if (Imm == 0xB800)
4800b57cec5SDimitry Andric     O << "-0.5";
4810b57cec5SDimitry Andric   else if (Imm == 0x4000)
4820b57cec5SDimitry Andric     O << "2.0";
4830b57cec5SDimitry Andric   else if (Imm == 0xC000)
4840b57cec5SDimitry Andric     O << "-2.0";
4850b57cec5SDimitry Andric   else if (Imm == 0x4400)
4860b57cec5SDimitry Andric     O << "4.0";
4870b57cec5SDimitry Andric   else if (Imm == 0xC400)
4880b57cec5SDimitry Andric     O << "-4.0";
4891db9f3b2SDimitry Andric   else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
4900b57cec5SDimitry Andric     O << "0.15915494";
4911db9f3b2SDimitry Andric   else
4921db9f3b2SDimitry Andric     return false;
4931db9f3b2SDimitry Andric 
4941db9f3b2SDimitry Andric   return true;
4950b57cec5SDimitry Andric }
4960b57cec5SDimitry Andric 
497*0fca6ea1SDimitry Andric static bool printImmediateBFloat16(uint32_t Imm, const MCSubtargetInfo &STI,
498*0fca6ea1SDimitry Andric                                    raw_ostream &O) {
499*0fca6ea1SDimitry Andric   if (Imm == 0x3F80)
500*0fca6ea1SDimitry Andric     O << "1.0";
501*0fca6ea1SDimitry Andric   else if (Imm == 0xBF80)
502*0fca6ea1SDimitry Andric     O << "-1.0";
503*0fca6ea1SDimitry Andric   else if (Imm == 0x3F00)
504*0fca6ea1SDimitry Andric     O << "0.5";
505*0fca6ea1SDimitry Andric   else if (Imm == 0xBF00)
506*0fca6ea1SDimitry Andric     O << "-0.5";
507*0fca6ea1SDimitry Andric   else if (Imm == 0x4000)
508*0fca6ea1SDimitry Andric     O << "2.0";
509*0fca6ea1SDimitry Andric   else if (Imm == 0xC000)
510*0fca6ea1SDimitry Andric     O << "-2.0";
511*0fca6ea1SDimitry Andric   else if (Imm == 0x4080)
512*0fca6ea1SDimitry Andric     O << "4.0";
513*0fca6ea1SDimitry Andric   else if (Imm == 0xC080)
514*0fca6ea1SDimitry Andric     O << "-4.0";
515*0fca6ea1SDimitry Andric   else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
516*0fca6ea1SDimitry Andric     O << "0.15915494";
517*0fca6ea1SDimitry Andric   else
518*0fca6ea1SDimitry Andric     return false;
519*0fca6ea1SDimitry Andric 
520*0fca6ea1SDimitry Andric   return true;
521*0fca6ea1SDimitry Andric }
522*0fca6ea1SDimitry Andric 
523*0fca6ea1SDimitry Andric void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,
524*0fca6ea1SDimitry Andric                                            const MCSubtargetInfo &STI,
525*0fca6ea1SDimitry Andric                                            raw_ostream &O) {
526*0fca6ea1SDimitry Andric   int16_t SImm = static_cast<int16_t>(Imm);
527*0fca6ea1SDimitry Andric   if (isInlinableIntLiteral(SImm)) {
528*0fca6ea1SDimitry Andric     O << SImm;
529*0fca6ea1SDimitry Andric     return;
530*0fca6ea1SDimitry Andric   }
531*0fca6ea1SDimitry Andric 
532*0fca6ea1SDimitry Andric   if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
533*0fca6ea1SDimitry Andric     return;
534*0fca6ea1SDimitry Andric 
535*0fca6ea1SDimitry Andric   O << formatHex(static_cast<uint64_t>(Imm));
536*0fca6ea1SDimitry Andric }
537*0fca6ea1SDimitry Andric 
538*0fca6ea1SDimitry Andric void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,
5390b57cec5SDimitry Andric                                           const MCSubtargetInfo &STI,
5400b57cec5SDimitry Andric                                           raw_ostream &O) {
5411db9f3b2SDimitry Andric   int16_t SImm = static_cast<int16_t>(Imm);
5421db9f3b2SDimitry Andric   if (isInlinableIntLiteral(SImm)) {
5430b57cec5SDimitry Andric     O << SImm;
5440b57cec5SDimitry Andric     return;
5450b57cec5SDimitry Andric   }
5460b57cec5SDimitry Andric 
5471db9f3b2SDimitry Andric   uint16_t HImm = static_cast<uint16_t>(Imm);
548*0fca6ea1SDimitry Andric   if (printImmediateFP16(HImm, STI, O))
5491db9f3b2SDimitry Andric     return;
5501db9f3b2SDimitry Andric 
5511db9f3b2SDimitry Andric   uint64_t Imm16 = static_cast<uint16_t>(Imm);
5521db9f3b2SDimitry Andric   O << formatHex(Imm16);
5531db9f3b2SDimitry Andric }
5541db9f3b2SDimitry Andric 
5551db9f3b2SDimitry Andric void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,
5561db9f3b2SDimitry Andric                                            const MCSubtargetInfo &STI,
5571db9f3b2SDimitry Andric                                            raw_ostream &O) {
5581db9f3b2SDimitry Andric   int32_t SImm = static_cast<int32_t>(Imm);
5591db9f3b2SDimitry Andric   if (isInlinableIntLiteral(SImm)) {
5601db9f3b2SDimitry Andric     O << SImm;
5611db9f3b2SDimitry Andric     return;
5621db9f3b2SDimitry Andric   }
5631db9f3b2SDimitry Andric 
5641db9f3b2SDimitry Andric   switch (OpType) {
5651db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2INT16:
5661db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
5671db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
5681db9f3b2SDimitry Andric     if (printImmediateFloat32(Imm, STI, O))
5691db9f3b2SDimitry Andric       return;
5701db9f3b2SDimitry Andric     break;
5711db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2FP16:
5721db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
5731db9f3b2SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
5741db9f3b2SDimitry Andric     if (isUInt<16>(Imm) &&
575*0fca6ea1SDimitry Andric         printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))
576*0fca6ea1SDimitry Andric       return;
577*0fca6ea1SDimitry Andric     break;
578*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2BF16:
579*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
580*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2BF16:
581*0fca6ea1SDimitry Andric     if (isUInt<16>(Imm) &&
582*0fca6ea1SDimitry Andric         printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))
5831db9f3b2SDimitry Andric       return;
5841db9f3b2SDimitry Andric     break;
5851db9f3b2SDimitry Andric   default:
5861db9f3b2SDimitry Andric     llvm_unreachable("bad operand type");
5871db9f3b2SDimitry Andric   }
5881db9f3b2SDimitry Andric 
5891db9f3b2SDimitry Andric   O << formatHex(static_cast<uint64_t>(Imm));
5901db9f3b2SDimitry Andric }
5911db9f3b2SDimitry Andric 
5921db9f3b2SDimitry Andric bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,
5931db9f3b2SDimitry Andric                                               const MCSubtargetInfo &STI,
5941db9f3b2SDimitry Andric                                               raw_ostream &O) {
59506c3fb27SDimitry Andric   if (Imm == llvm::bit_cast<uint32_t>(0.0f))
5960b57cec5SDimitry Andric     O << "0.0";
59706c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(1.0f))
5980b57cec5SDimitry Andric     O << "1.0";
59906c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))
6000b57cec5SDimitry Andric     O << "-1.0";
60106c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(0.5f))
6020b57cec5SDimitry Andric     O << "0.5";
60306c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))
6040b57cec5SDimitry Andric     O << "-0.5";
60506c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(2.0f))
6060b57cec5SDimitry Andric     O << "2.0";
60706c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))
6080b57cec5SDimitry Andric     O << "-2.0";
60906c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(4.0f))
6100b57cec5SDimitry Andric     O << "4.0";
61106c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))
6120b57cec5SDimitry Andric     O << "-4.0";
6130b57cec5SDimitry Andric   else if (Imm == 0x3e22f983 &&
61406c3fb27SDimitry Andric            STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
6150b57cec5SDimitry Andric     O << "0.15915494";
6160b57cec5SDimitry Andric   else
6171db9f3b2SDimitry Andric     return false;
6181db9f3b2SDimitry Andric 
6191db9f3b2SDimitry Andric   return true;
6201db9f3b2SDimitry Andric }
6211db9f3b2SDimitry Andric 
6221db9f3b2SDimitry Andric void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
6231db9f3b2SDimitry Andric                                          const MCSubtargetInfo &STI,
6241db9f3b2SDimitry Andric                                          raw_ostream &O) {
6251db9f3b2SDimitry Andric   int32_t SImm = static_cast<int32_t>(Imm);
6261db9f3b2SDimitry Andric   if (isInlinableIntLiteral(SImm)) {
6271db9f3b2SDimitry Andric     O << SImm;
6281db9f3b2SDimitry Andric     return;
6291db9f3b2SDimitry Andric   }
6301db9f3b2SDimitry Andric 
6311db9f3b2SDimitry Andric   if (printImmediateFloat32(Imm, STI, O))
6321db9f3b2SDimitry Andric     return;
6331db9f3b2SDimitry Andric 
6340b57cec5SDimitry Andric   O << formatHex(static_cast<uint64_t>(Imm));
6350b57cec5SDimitry Andric }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
6380b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI,
6395f757f3fSDimitry Andric                                          raw_ostream &O, bool IsFP) {
6400b57cec5SDimitry Andric   int64_t SImm = static_cast<int64_t>(Imm);
6410b57cec5SDimitry Andric   if (SImm >= -16 && SImm <= 64) {
6420b57cec5SDimitry Andric     O << SImm;
6430b57cec5SDimitry Andric     return;
6440b57cec5SDimitry Andric   }
6450b57cec5SDimitry Andric 
64606c3fb27SDimitry Andric   if (Imm == llvm::bit_cast<uint64_t>(0.0))
6470b57cec5SDimitry Andric     O << "0.0";
64806c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(1.0))
6490b57cec5SDimitry Andric     O << "1.0";
65006c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(-1.0))
6510b57cec5SDimitry Andric     O << "-1.0";
65206c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(0.5))
6530b57cec5SDimitry Andric     O << "0.5";
65406c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(-0.5))
6550b57cec5SDimitry Andric     O << "-0.5";
65606c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(2.0))
6570b57cec5SDimitry Andric     O << "2.0";
65806c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(-2.0))
6590b57cec5SDimitry Andric     O << "-2.0";
66006c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(4.0))
6610b57cec5SDimitry Andric     O << "4.0";
66206c3fb27SDimitry Andric   else if (Imm == llvm::bit_cast<uint64_t>(-4.0))
6630b57cec5SDimitry Andric     O << "-4.0";
6640b57cec5SDimitry Andric   else if (Imm == 0x3fc45f306dc9c882 &&
66506c3fb27SDimitry Andric            STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
6660b57cec5SDimitry Andric     O << "0.15915494309189532";
6675f757f3fSDimitry Andric   else if (IsFP) {
6685f757f3fSDimitry Andric     assert(AMDGPU::isValid32BitLiteral(Imm, true));
6695f757f3fSDimitry Andric     O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
6705f757f3fSDimitry Andric   } else {
67181ad6265SDimitry Andric     assert(isUInt<32>(Imm) || isInt<32>(Imm));
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric     // In rare situations, we will have a 32-bit literal in a 64-bit
6740b57cec5SDimitry Andric     // operand. This is technically allowed for the encoding of s_mov_b64.
6750b57cec5SDimitry Andric     O << formatHex(static_cast<uint64_t>(Imm));
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric }
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,
6800b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI,
6810b57cec5SDimitry Andric                                   raw_ostream &O) {
6820b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
6830b57cec5SDimitry Andric   if (!Imm)
6840b57cec5SDimitry Andric     return;
6850b57cec5SDimitry Andric 
68681ad6265SDimitry Andric   if (AMDGPU::isGFX940(STI)) {
68781ad6265SDimitry Andric     switch (MI->getOpcode()) {
68881ad6265SDimitry Andric     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
68981ad6265SDimitry Andric     case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
69081ad6265SDimitry Andric     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
69181ad6265SDimitry Andric     case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
69281ad6265SDimitry Andric       O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','
69381ad6265SDimitry Andric         << ((Imm >> 2) & 1) << ']';
69481ad6265SDimitry Andric       return;
69581ad6265SDimitry Andric     }
69681ad6265SDimitry Andric   }
69781ad6265SDimitry Andric 
6980b57cec5SDimitry Andric   O << " blgp:" << Imm;
6990b57cec5SDimitry Andric }
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric void AMDGPUInstPrinter::printCBSZ(const MCInst *MI, unsigned OpNo,
7020b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI,
7030b57cec5SDimitry Andric                                   raw_ostream &O) {
7040b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
7050b57cec5SDimitry Andric   if (!Imm)
7060b57cec5SDimitry Andric     return;
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   O << " cbsz:" << Imm;
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric void AMDGPUInstPrinter::printABID(const MCInst *MI, unsigned OpNo,
7120b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI,
7130b57cec5SDimitry Andric                                   raw_ostream &O) {
7140b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
7150b57cec5SDimitry Andric   if (!Imm)
7160b57cec5SDimitry Andric     return;
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   O << " abid:" << Imm;
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric 
72181ad6265SDimitry Andric void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,
7220b57cec5SDimitry Andric                                                const MCSubtargetInfo &STI,
7230b57cec5SDimitry Andric                                                raw_ostream &O) {
72481ad6265SDimitry Andric   if (!FirstOperand)
7250b57cec5SDimitry Andric     O << ", ";
72606c3fb27SDimitry Andric   printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize64)
72781ad6265SDimitry Andric                       ? AMDGPU::VCC
72881ad6265SDimitry Andric                       : AMDGPU::VCC_LO,
72981ad6265SDimitry Andric                   O, MRI);
73081ad6265SDimitry Andric   if (FirstOperand)
7310b57cec5SDimitry Andric     O << ", ";
7320b57cec5SDimitry Andric }
7330b57cec5SDimitry Andric 
73481ad6265SDimitry Andric void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
73581ad6265SDimitry Andric                                       const MCSubtargetInfo &STI,
73681ad6265SDimitry Andric                                       raw_ostream &O) {
73781ad6265SDimitry Andric   O << " wait_vdst:";
73881ad6265SDimitry Andric   printU4ImmDecOperand(MI, OpNo, O);
73981ad6265SDimitry Andric }
74081ad6265SDimitry Andric 
7411db9f3b2SDimitry Andric void AMDGPUInstPrinter::printWaitVAVDst(const MCInst *MI, unsigned OpNo,
7421db9f3b2SDimitry Andric                                         const MCSubtargetInfo &STI,
7431db9f3b2SDimitry Andric                                         raw_ostream &O) {
7441db9f3b2SDimitry Andric   O << " wait_va_vdst:";
7451db9f3b2SDimitry Andric   printU4ImmDecOperand(MI, OpNo, O);
7461db9f3b2SDimitry Andric }
7471db9f3b2SDimitry Andric 
7481db9f3b2SDimitry Andric void AMDGPUInstPrinter::printWaitVMVSrc(const MCInst *MI, unsigned OpNo,
7491db9f3b2SDimitry Andric                                         const MCSubtargetInfo &STI,
7501db9f3b2SDimitry Andric                                         raw_ostream &O) {
7511db9f3b2SDimitry Andric   O << " wait_vm_vsrc:";
7521db9f3b2SDimitry Andric   printU4ImmDecOperand(MI, OpNo, O);
7531db9f3b2SDimitry Andric }
7541db9f3b2SDimitry Andric 
75581ad6265SDimitry Andric void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
75681ad6265SDimitry Andric                                     const MCSubtargetInfo &STI,
75781ad6265SDimitry Andric                                     raw_ostream &O) {
75881ad6265SDimitry Andric   O << " wait_exp:";
75981ad6265SDimitry Andric   printU4ImmDecOperand(MI, OpNo, O);
76081ad6265SDimitry Andric }
76181ad6265SDimitry Andric 
76281ad6265SDimitry Andric bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,
76381ad6265SDimitry Andric                                         unsigned OpNo) const {
764fcaf7f86SDimitry Andric   return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&
76581ad6265SDimitry Andric          (Desc.TSFlags & SIInstrFlags::VOPC) &&
766*0fca6ea1SDimitry Andric          !isVOPCAsmOnly(Desc.getOpcode()) &&
76781ad6265SDimitry Andric          (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
76881ad6265SDimitry Andric           Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));
76981ad6265SDimitry Andric }
77081ad6265SDimitry Andric 
77181ad6265SDimitry Andric // Print default vcc/vcc_lo operand of VOPC.
7720b57cec5SDimitry Andric void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
7730b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
7740b57cec5SDimitry Andric                                      raw_ostream &O) {
77581ad6265SDimitry Andric   unsigned Opc = MI->getOpcode();
77681ad6265SDimitry Andric   const MCInstrDesc &Desc = MII.get(Opc);
77781ad6265SDimitry Andric   int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
77881ad6265SDimitry Andric   // 0, 1 and 2 are the first printed operands in different cases
77981ad6265SDimitry Andric   // If there are printed modifiers, printOperandAndFPInputMods or
78081ad6265SDimitry Andric   // printOperandAndIntInputMods will be called instead
78181ad6265SDimitry Andric   if ((OpNo == 0 ||
782fcaf7f86SDimitry Andric        (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&
783*0fca6ea1SDimitry Andric       (Desc.TSFlags & SIInstrFlags::VOPC) && !isVOPCAsmOnly(Desc.getOpcode()) &&
7840b57cec5SDimitry Andric       (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||
7850b57cec5SDimitry Andric        Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))
78681ad6265SDimitry Andric     printDefaultVccOperand(true, STI, O);
78781ad6265SDimitry Andric 
78881ad6265SDimitry Andric   printRegularOperand(MI, OpNo, STI, O);
78981ad6265SDimitry Andric }
79081ad6265SDimitry Andric 
79181ad6265SDimitry Andric // Print operands after vcc or modifier handling.
79281ad6265SDimitry Andric void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
79381ad6265SDimitry Andric                                             const MCSubtargetInfo &STI,
79481ad6265SDimitry Andric                                             raw_ostream &O) {
79581ad6265SDimitry Andric   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric   if (OpNo >= MI->getNumOperands()) {
7980b57cec5SDimitry Andric     O << "/*Missing OP" << OpNo << "*/";
7990b57cec5SDimitry Andric     return;
8000b57cec5SDimitry Andric   }
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
8030b57cec5SDimitry Andric   if (Op.isReg()) {
8040b57cec5SDimitry Andric     printRegOperand(Op.getReg(), O, MRI);
805bdd1243dSDimitry Andric 
806bdd1243dSDimitry Andric     // Check if operand register class contains register used.
807bdd1243dSDimitry Andric     // Intention: print disassembler message when invalid code is decoded,
808bdd1243dSDimitry Andric     // for example sgpr register used in VReg or VISrc(VReg or imm) operand.
809bdd1243dSDimitry Andric     int RCID = Desc.operands()[OpNo].RegClass;
810bdd1243dSDimitry Andric     if (RCID != -1) {
811bdd1243dSDimitry Andric       const MCRegisterClass RC = MRI.getRegClass(RCID);
812bdd1243dSDimitry Andric       auto Reg = mc2PseudoReg(Op.getReg());
813bdd1243dSDimitry Andric       if (!RC.contains(Reg) && !isInlineValue(Reg)) {
814bdd1243dSDimitry Andric         O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)
815bdd1243dSDimitry Andric           << "\' register class*/";
816bdd1243dSDimitry Andric       }
817bdd1243dSDimitry Andric     }
8180b57cec5SDimitry Andric   } else if (Op.isImm()) {
819bdd1243dSDimitry Andric     const uint8_t OpTy = Desc.operands()[OpNo].OperandType;
8205ffd83dbSDimitry Andric     switch (OpTy) {
8210b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_INT32:
8220b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_FP32:
823349cc55cSDimitry Andric     case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
8240b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_INT32:
8250b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_FP32:
8260b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
8270b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
828fe6060f1SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_V2INT32:
829fe6060f1SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_V2FP32:
830fe6060f1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
831fe6060f1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
8320b57cec5SDimitry Andric     case MCOI::OPERAND_IMMEDIATE:
8335f757f3fSDimitry Andric     case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
8340b57cec5SDimitry Andric       printImmediate32(Op.getImm(), STI, O);
8350b57cec5SDimitry Andric       break;
8360b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_INT64:
8370b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_INT64:
8385f757f3fSDimitry Andric       printImmediate64(Op.getImm(), STI, O, false);
8395f757f3fSDimitry Andric       break;
8405f757f3fSDimitry Andric     case AMDGPU::OPERAND_REG_IMM_FP64:
8410b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_FP64:
842fe6060f1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
8435f757f3fSDimitry Andric       printImmediate64(Op.getImm(), STI, O, true);
8440b57cec5SDimitry Andric       break;
8450b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_INT16:
8460b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
8470b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_INT16:
8485ffd83dbSDimitry Andric       printImmediateInt16(Op.getImm(), STI, O);
8495ffd83dbSDimitry Andric       break;
8505ffd83dbSDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_FP16:
8515ffd83dbSDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
8520b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_FP16:
853349cc55cSDimitry Andric     case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
854*0fca6ea1SDimitry Andric       printImmediateF16(Op.getImm(), STI, O);
855*0fca6ea1SDimitry Andric       break;
856*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_BF16:
857*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_BF16:
858*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_BF16:
859*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_BF16_DEFERRED:
860*0fca6ea1SDimitry Andric       printImmediateBF16(Op.getImm(), STI, O);
8610b57cec5SDimitry Andric       break;
8620b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_V2INT16:
863*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_V2BF16:
8640b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_IMM_V2FP16:
8650b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
8660b57cec5SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
867*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
8685ffd83dbSDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
869*0fca6ea1SDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_V2BF16:
8705ffd83dbSDimitry Andric     case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
8711db9f3b2SDimitry Andric       printImmediateV216(Op.getImm(), OpTy, STI, O);
8720b57cec5SDimitry Andric       break;
8730b57cec5SDimitry Andric     case MCOI::OPERAND_UNKNOWN:
8740b57cec5SDimitry Andric     case MCOI::OPERAND_PCREL:
8750b57cec5SDimitry Andric       O << formatDec(Op.getImm());
8760b57cec5SDimitry Andric       break;
8770b57cec5SDimitry Andric     case MCOI::OPERAND_REGISTER:
87806c3fb27SDimitry Andric       // Disassembler does not fail when operand should not allow immediate
87906c3fb27SDimitry Andric       // operands but decodes them into 32bit immediate operand.
88006c3fb27SDimitry Andric       printImmediate32(Op.getImm(), STI, O);
88106c3fb27SDimitry Andric       O << "/*Invalid immediate*/";
8820b57cec5SDimitry Andric       break;
8830b57cec5SDimitry Andric     default:
8840b57cec5SDimitry Andric       // We hit this for the immediate instruction bits that don't yet have a
8850b57cec5SDimitry Andric       // custom printer.
8860b57cec5SDimitry Andric       llvm_unreachable("unexpected immediate operand type");
8870b57cec5SDimitry Andric     }
888fe6060f1SDimitry Andric   } else if (Op.isDFPImm()) {
889fe6060f1SDimitry Andric     double Value = bit_cast<double>(Op.getDFPImm());
8900b57cec5SDimitry Andric     // We special case 0.0 because otherwise it will be printed as an integer.
891fe6060f1SDimitry Andric     if (Value == 0.0)
8920b57cec5SDimitry Andric       O << "0.0";
8930b57cec5SDimitry Andric     else {
8940b57cec5SDimitry Andric       const MCInstrDesc &Desc = MII.get(MI->getOpcode());
895bdd1243dSDimitry Andric       int RCID = Desc.operands()[OpNo].RegClass;
8960b57cec5SDimitry Andric       unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
8970b57cec5SDimitry Andric       if (RCBits == 32)
89806c3fb27SDimitry Andric         printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
8990b57cec5SDimitry Andric       else if (RCBits == 64)
9005f757f3fSDimitry Andric         printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
9010b57cec5SDimitry Andric       else
9020b57cec5SDimitry Andric         llvm_unreachable("Invalid register class size");
9030b57cec5SDimitry Andric     }
9040b57cec5SDimitry Andric   } else if (Op.isExpr()) {
9050b57cec5SDimitry Andric     const MCExpr *Exp = Op.getExpr();
9060b57cec5SDimitry Andric     Exp->print(O, &MAI);
9070b57cec5SDimitry Andric   } else {
9080b57cec5SDimitry Andric     O << "/*INV_OP*/";
9090b57cec5SDimitry Andric   }
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.
9120b57cec5SDimitry Andric   switch (MI->getOpcode()) {
9130b57cec5SDimitry Andric   default: break;
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   case AMDGPU::V_CNDMASK_B32_e32_gfx10:
9160b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:
9170b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:
9180b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
9190b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:
9200b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:
9210b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:
9228bcb0991SDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:
9230b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:
9240b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:
9250b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:
92681ad6265SDimitry Andric   case AMDGPU::V_CNDMASK_B32_e32_gfx11:
92781ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:
92881ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:
92981ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:
93081ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:
93181ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:
93281ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:
93381ad6265SDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:
93481ad6265SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:
93581ad6265SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:
93681ad6265SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:
9375f757f3fSDimitry Andric   case AMDGPU::V_CNDMASK_B32_e32_gfx12:
9385f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:
9395f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:
9405f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:
9415f757f3fSDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp_gfx12:
9425f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:
9435f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:
9445f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:
9455f757f3fSDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:
9465f757f3fSDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:
9475f757f3fSDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:
9485f757f3fSDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:
9510b57cec5SDimitry Andric   case AMDGPU::V_CNDMASK_B32_e32_vi:
9520b57cec5SDimitry Andric     if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
9530b57cec5SDimitry Andric                                                 AMDGPU::OpName::src1))
95481ad6265SDimitry Andric       printDefaultVccOperand(OpNo == 0, STI, O);
9550b57cec5SDimitry Andric     break;
9560b57cec5SDimitry Andric   }
957e8d8bef9SDimitry Andric 
958e8d8bef9SDimitry Andric   if (Desc.TSFlags & SIInstrFlags::MTBUF) {
959e8d8bef9SDimitry Andric     int SOffsetIdx =
960e8d8bef9SDimitry Andric       AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);
961e8d8bef9SDimitry Andric     assert(SOffsetIdx != -1);
962e8d8bef9SDimitry Andric     if ((int)OpNo == SOffsetIdx)
963e8d8bef9SDimitry Andric       printSymbolicFormat(MI, STI, O);
964e8d8bef9SDimitry Andric   }
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
9680b57cec5SDimitry Andric                                                    unsigned OpNo,
9690b57cec5SDimitry Andric                                                    const MCSubtargetInfo &STI,
9700b57cec5SDimitry Andric                                                    raw_ostream &O) {
97181ad6265SDimitry Andric   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
97281ad6265SDimitry Andric   if (needsImpliedVcc(Desc, OpNo))
97381ad6265SDimitry Andric     printDefaultVccOperand(true, STI, O);
97481ad6265SDimitry Andric 
9750b57cec5SDimitry Andric   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric   // Use 'neg(...)' instead of '-' to avoid ambiguity.
9780b57cec5SDimitry Andric   // This is important for integer literals because
9790b57cec5SDimitry Andric   // -1 is not the same value as neg(1).
9800b57cec5SDimitry Andric   bool NegMnemo = false;
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric   if (InputModifiers & SISrcMods::NEG) {
9830b57cec5SDimitry Andric     if (OpNo + 1 < MI->getNumOperands() &&
9840b57cec5SDimitry Andric         (InputModifiers & SISrcMods::ABS) == 0) {
9850b57cec5SDimitry Andric       const MCOperand &Op = MI->getOperand(OpNo + 1);
986fe6060f1SDimitry Andric       NegMnemo = Op.isImm() || Op.isDFPImm();
9870b57cec5SDimitry Andric     }
9880b57cec5SDimitry Andric     if (NegMnemo) {
9890b57cec5SDimitry Andric       O << "neg(";
9900b57cec5SDimitry Andric     } else {
9910b57cec5SDimitry Andric       O << '-';
9920b57cec5SDimitry Andric     }
9930b57cec5SDimitry Andric   }
9940b57cec5SDimitry Andric 
9950b57cec5SDimitry Andric   if (InputModifiers & SISrcMods::ABS)
9960b57cec5SDimitry Andric     O << '|';
99781ad6265SDimitry Andric   printRegularOperand(MI, OpNo + 1, STI, O);
9980b57cec5SDimitry Andric   if (InputModifiers & SISrcMods::ABS)
9990b57cec5SDimitry Andric     O << '|';
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   if (NegMnemo) {
10020b57cec5SDimitry Andric     O << ')';
10030b57cec5SDimitry Andric   }
1004bdd1243dSDimitry Andric 
1005bdd1243dSDimitry Andric   // Print default vcc/vcc_lo operand of VOP2b.
1006bdd1243dSDimitry Andric   switch (MI->getOpcode()) {
1007bdd1243dSDimitry Andric   default:
1008bdd1243dSDimitry Andric     break;
1009bdd1243dSDimitry Andric 
1010bdd1243dSDimitry Andric   case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:
1011bdd1243dSDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp_gfx10:
1012bdd1243dSDimitry Andric   case AMDGPU::V_CNDMASK_B32_dpp_gfx11:
1013bdd1243dSDimitry Andric     if ((int)OpNo + 1 ==
1014bdd1243dSDimitry Andric         AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))
1015bdd1243dSDimitry Andric       printDefaultVccOperand(OpNo == 0, STI, O);
1016bdd1243dSDimitry Andric     break;
1017bdd1243dSDimitry Andric   }
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
10210b57cec5SDimitry Andric                                                     unsigned OpNo,
10220b57cec5SDimitry Andric                                                     const MCSubtargetInfo &STI,
10230b57cec5SDimitry Andric                                                     raw_ostream &O) {
102481ad6265SDimitry Andric   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
102581ad6265SDimitry Andric   if (needsImpliedVcc(Desc, OpNo))
102681ad6265SDimitry Andric     printDefaultVccOperand(true, STI, O);
102781ad6265SDimitry Andric 
10280b57cec5SDimitry Andric   unsigned InputModifiers = MI->getOperand(OpNo).getImm();
10290b57cec5SDimitry Andric   if (InputModifiers & SISrcMods::SEXT)
10300b57cec5SDimitry Andric     O << "sext(";
103181ad6265SDimitry Andric   printRegularOperand(MI, OpNo + 1, STI, O);
10320b57cec5SDimitry Andric   if (InputModifiers & SISrcMods::SEXT)
10330b57cec5SDimitry Andric     O << ')';
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   // Print default vcc/vcc_lo operand of VOP2b.
10360b57cec5SDimitry Andric   switch (MI->getOpcode()) {
10370b57cec5SDimitry Andric   default: break;
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric   case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:
10400b57cec5SDimitry Andric   case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:
10410b57cec5SDimitry Andric   case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:
10420b57cec5SDimitry Andric     if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),
10430b57cec5SDimitry Andric                                                     AMDGPU::OpName::src1))
104481ad6265SDimitry Andric       printDefaultVccOperand(OpNo == 0, STI, O);
10450b57cec5SDimitry Andric     break;
10460b57cec5SDimitry Andric   }
10470b57cec5SDimitry Andric }
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,
10500b57cec5SDimitry Andric                                   const MCSubtargetInfo &STI,
10510b57cec5SDimitry Andric                                   raw_ostream &O) {
1052e8d8bef9SDimitry Andric   if (!AMDGPU::isGFX10Plus(STI))
10530b57cec5SDimitry Andric     llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
10560b57cec5SDimitry Andric   O << "dpp8:[" << formatDec(Imm & 0x7);
10570b57cec5SDimitry Andric   for (size_t i = 1; i < 8; ++i) {
10580b57cec5SDimitry Andric     O << ',' << formatDec((Imm >> (3 * i)) & 0x7);
10590b57cec5SDimitry Andric   }
10600b57cec5SDimitry Andric   O << ']';
10610b57cec5SDimitry Andric }
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
10640b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
10650b57cec5SDimitry Andric                                      raw_ostream &O) {
10660b57cec5SDimitry Andric   using namespace AMDGPU::DPP;
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
1069fe6060f1SDimitry Andric   const MCInstrDesc &Desc = MII.get(MI->getOpcode());
1070fe6060f1SDimitry Andric 
10715f757f3fSDimitry Andric   if (!AMDGPU::isLegalDPALU_DPPControl(Imm) && AMDGPU::isDPALU_DPP(Desc)) {
10725f757f3fSDimitry Andric     O << " /* DP ALU dpp only supports row_newbcast */";
1073fe6060f1SDimitry Andric     return;
1074*0fca6ea1SDimitry Andric   }
1075*0fca6ea1SDimitry Andric   if (Imm <= DppCtrl::QUAD_PERM_LAST) {
10760b57cec5SDimitry Andric     O << "quad_perm:[";
10770b57cec5SDimitry Andric     O << formatDec(Imm & 0x3)         << ',';
10780b57cec5SDimitry Andric     O << formatDec((Imm & 0xc)  >> 2) << ',';
10790b57cec5SDimitry Andric     O << formatDec((Imm & 0x30) >> 4) << ',';
10800b57cec5SDimitry Andric     O << formatDec((Imm & 0xc0) >> 6) << ']';
10810b57cec5SDimitry Andric   } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&
10820b57cec5SDimitry Andric              (Imm <= DppCtrl::ROW_SHL_LAST)) {
10830b57cec5SDimitry Andric     O << "row_shl:";
10840b57cec5SDimitry Andric     printU4ImmDecOperand(MI, OpNo, O);
10850b57cec5SDimitry Andric   } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&
10860b57cec5SDimitry Andric              (Imm <= DppCtrl::ROW_SHR_LAST)) {
10870b57cec5SDimitry Andric     O << "row_shr:";
10880b57cec5SDimitry Andric     printU4ImmDecOperand(MI, OpNo, O);
10890b57cec5SDimitry Andric   } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&
10900b57cec5SDimitry Andric              (Imm <= DppCtrl::ROW_ROR_LAST)) {
10910b57cec5SDimitry Andric     O << "row_ror:";
10920b57cec5SDimitry Andric     printU4ImmDecOperand(MI, OpNo, O);
10930b57cec5SDimitry Andric   } else if (Imm == DppCtrl::WAVE_SHL1) {
1094e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
10950b57cec5SDimitry Andric       O << "/* wave_shl is not supported starting from GFX10 */";
10960b57cec5SDimitry Andric       return;
10970b57cec5SDimitry Andric     }
10980b57cec5SDimitry Andric     O << "wave_shl:1";
10990b57cec5SDimitry Andric   } else if (Imm == DppCtrl::WAVE_ROL1) {
1100e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
11010b57cec5SDimitry Andric       O << "/* wave_rol is not supported starting from GFX10 */";
11020b57cec5SDimitry Andric       return;
11030b57cec5SDimitry Andric     }
11040b57cec5SDimitry Andric     O << "wave_rol:1";
11050b57cec5SDimitry Andric   } else if (Imm == DppCtrl::WAVE_SHR1) {
1106e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
11070b57cec5SDimitry Andric       O << "/* wave_shr is not supported starting from GFX10 */";
11080b57cec5SDimitry Andric       return;
11090b57cec5SDimitry Andric     }
11100b57cec5SDimitry Andric     O << "wave_shr:1";
11110b57cec5SDimitry Andric   } else if (Imm == DppCtrl::WAVE_ROR1) {
1112e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
11130b57cec5SDimitry Andric       O << "/* wave_ror is not supported starting from GFX10 */";
11140b57cec5SDimitry Andric       return;
11150b57cec5SDimitry Andric     }
11160b57cec5SDimitry Andric     O << "wave_ror:1";
11170b57cec5SDimitry Andric   } else if (Imm == DppCtrl::ROW_MIRROR) {
11180b57cec5SDimitry Andric     O << "row_mirror";
11190b57cec5SDimitry Andric   } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {
11200b57cec5SDimitry Andric     O << "row_half_mirror";
11210b57cec5SDimitry Andric   } else if (Imm == DppCtrl::BCAST15) {
1122e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
11230b57cec5SDimitry Andric       O << "/* row_bcast is not supported starting from GFX10 */";
11240b57cec5SDimitry Andric       return;
11250b57cec5SDimitry Andric     }
11260b57cec5SDimitry Andric     O << "row_bcast:15";
11270b57cec5SDimitry Andric   } else if (Imm == DppCtrl::BCAST31) {
1128e8d8bef9SDimitry Andric     if (AMDGPU::isGFX10Plus(STI)) {
11290b57cec5SDimitry Andric       O << "/* row_bcast is not supported starting from GFX10 */";
11300b57cec5SDimitry Andric       return;
11310b57cec5SDimitry Andric     }
11320b57cec5SDimitry Andric     O << "row_bcast:31";
11330b57cec5SDimitry Andric   } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&
11340b57cec5SDimitry Andric              (Imm <= DppCtrl::ROW_SHARE_LAST)) {
1135fe6060f1SDimitry Andric     if (AMDGPU::isGFX90A(STI)) {
1136fe6060f1SDimitry Andric       O << "row_newbcast:";
1137fe6060f1SDimitry Andric     } else if (AMDGPU::isGFX10Plus(STI)) {
1138fe6060f1SDimitry Andric       O << "row_share:";
1139fe6060f1SDimitry Andric     } else {
1140fe6060f1SDimitry Andric       O << " /* row_newbcast/row_share is not supported on ASICs earlier "
1141fe6060f1SDimitry Andric            "than GFX90A/GFX10 */";
11420b57cec5SDimitry Andric       return;
11430b57cec5SDimitry Andric     }
11440b57cec5SDimitry Andric     printU4ImmDecOperand(MI, OpNo, O);
11450b57cec5SDimitry Andric   } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&
11460b57cec5SDimitry Andric              (Imm <= DppCtrl::ROW_XMASK_LAST)) {
1147e8d8bef9SDimitry Andric     if (!AMDGPU::isGFX10Plus(STI)) {
11480b57cec5SDimitry Andric       O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";
11490b57cec5SDimitry Andric       return;
11500b57cec5SDimitry Andric     }
11510b57cec5SDimitry Andric     O << "row_xmask:";
11520b57cec5SDimitry Andric     printU4ImmDecOperand(MI, OpNo, O);
11530b57cec5SDimitry Andric   } else {
11540b57cec5SDimitry Andric     O << "/* Invalid dpp_ctrl value */";
11550b57cec5SDimitry Andric   }
11560b57cec5SDimitry Andric }
11570b57cec5SDimitry Andric 
115806c3fb27SDimitry Andric void AMDGPUInstPrinter::printDppRowMask(const MCInst *MI, unsigned OpNo,
11590b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
11600b57cec5SDimitry Andric                                         raw_ostream &O) {
11610b57cec5SDimitry Andric   O << " row_mask:";
11620b57cec5SDimitry Andric   printU4ImmOperand(MI, OpNo, STI, O);
11630b57cec5SDimitry Andric }
11640b57cec5SDimitry Andric 
116506c3fb27SDimitry Andric void AMDGPUInstPrinter::printDppBankMask(const MCInst *MI, unsigned OpNo,
11660b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI,
11670b57cec5SDimitry Andric                                          raw_ostream &O) {
11680b57cec5SDimitry Andric   O << " bank_mask:";
11690b57cec5SDimitry Andric   printU4ImmOperand(MI, OpNo, STI, O);
11700b57cec5SDimitry Andric }
11710b57cec5SDimitry Andric 
1172bdd1243dSDimitry Andric void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,
11730b57cec5SDimitry Andric                                           const MCSubtargetInfo &STI,
11740b57cec5SDimitry Andric                                           raw_ostream &O) {
11750b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
11760b57cec5SDimitry Andric   if (Imm) {
1177fe6060f1SDimitry Andric     O << " bound_ctrl:1";
11780b57cec5SDimitry Andric   }
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric 
118106c3fb27SDimitry Andric void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,
118206c3fb27SDimitry Andric                                    const MCSubtargetInfo &STI, raw_ostream &O) {
11830b57cec5SDimitry Andric   using namespace llvm::AMDGPU::DPP;
11840b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
11850b57cec5SDimitry Andric   if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {
11860b57cec5SDimitry Andric     O << " fi:1";
11870b57cec5SDimitry Andric   }
11880b57cec5SDimitry Andric }
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
11910b57cec5SDimitry Andric                                      raw_ostream &O) {
11920b57cec5SDimitry Andric   using namespace llvm::AMDGPU::SDWA;
11930b57cec5SDimitry Andric 
11940b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
11950b57cec5SDimitry Andric   switch (Imm) {
11960b57cec5SDimitry Andric   case SdwaSel::BYTE_0: O << "BYTE_0"; break;
11970b57cec5SDimitry Andric   case SdwaSel::BYTE_1: O << "BYTE_1"; break;
11980b57cec5SDimitry Andric   case SdwaSel::BYTE_2: O << "BYTE_2"; break;
11990b57cec5SDimitry Andric   case SdwaSel::BYTE_3: O << "BYTE_3"; break;
12000b57cec5SDimitry Andric   case SdwaSel::WORD_0: O << "WORD_0"; break;
12010b57cec5SDimitry Andric   case SdwaSel::WORD_1: O << "WORD_1"; break;
12020b57cec5SDimitry Andric   case SdwaSel::DWORD: O << "DWORD"; break;
12030b57cec5SDimitry Andric   default: llvm_unreachable("Invalid SDWA data select operand");
12040b57cec5SDimitry Andric   }
12050b57cec5SDimitry Andric }
12060b57cec5SDimitry Andric 
12070b57cec5SDimitry Andric void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
12080b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
12090b57cec5SDimitry Andric                                         raw_ostream &O) {
12100b57cec5SDimitry Andric   O << "dst_sel:";
12110b57cec5SDimitry Andric   printSDWASel(MI, OpNo, O);
12120b57cec5SDimitry Andric }
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
12150b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI,
12160b57cec5SDimitry Andric                                          raw_ostream &O) {
12170b57cec5SDimitry Andric   O << "src0_sel:";
12180b57cec5SDimitry Andric   printSDWASel(MI, OpNo, O);
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
12220b57cec5SDimitry Andric                                          const MCSubtargetInfo &STI,
12230b57cec5SDimitry Andric                                          raw_ostream &O) {
12240b57cec5SDimitry Andric   O << "src1_sel:";
12250b57cec5SDimitry Andric   printSDWASel(MI, OpNo, O);
12260b57cec5SDimitry Andric }
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
12290b57cec5SDimitry Andric                                            const MCSubtargetInfo &STI,
12300b57cec5SDimitry Andric                                            raw_ostream &O) {
12310b57cec5SDimitry Andric   using namespace llvm::AMDGPU::SDWA;
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric   O << "dst_unused:";
12340b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNo).getImm();
12350b57cec5SDimitry Andric   switch (Imm) {
12360b57cec5SDimitry Andric   case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;
12370b57cec5SDimitry Andric   case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;
12380b57cec5SDimitry Andric   case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;
12390b57cec5SDimitry Andric   default: llvm_unreachable("Invalid SDWA dest_unused operand");
12400b57cec5SDimitry Andric   }
12410b57cec5SDimitry Andric }
12420b57cec5SDimitry Andric 
12430b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
1244e8d8bef9SDimitry Andric                                      const MCSubtargetInfo &STI, raw_ostream &O,
1245e8d8bef9SDimitry Andric                                      unsigned N) {
12460b57cec5SDimitry Andric   unsigned Opc = MI->getOpcode();
12470b57cec5SDimitry Andric   int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);
12480b57cec5SDimitry Andric   unsigned En = MI->getOperand(EnIdx).getImm();
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric   // If compr is set, print as src0, src0, src1, src1
1253e8d8bef9SDimitry Andric   if (MI->getOperand(ComprIdx).getImm())
1254e8d8bef9SDimitry Andric     OpNo = OpNo - N + N / 2;
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric   if (En & (1 << N))
12570b57cec5SDimitry Andric     printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
12580b57cec5SDimitry Andric   else
12590b57cec5SDimitry Andric     O << "off";
12600b57cec5SDimitry Andric }
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,
12630b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
12640b57cec5SDimitry Andric                                      raw_ostream &O) {
1265e8d8bef9SDimitry Andric   printExpSrcN(MI, OpNo, STI, O, 0);
12660b57cec5SDimitry Andric }
12670b57cec5SDimitry Andric 
12680b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,
12690b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
12700b57cec5SDimitry Andric                                      raw_ostream &O) {
1271e8d8bef9SDimitry Andric   printExpSrcN(MI, OpNo, STI, O, 1);
12720b57cec5SDimitry Andric }
12730b57cec5SDimitry Andric 
12740b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,
12750b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
12760b57cec5SDimitry Andric                                      raw_ostream &O) {
1277e8d8bef9SDimitry Andric   printExpSrcN(MI, OpNo, STI, O, 2);
12780b57cec5SDimitry Andric }
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
12810b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
12820b57cec5SDimitry Andric                                      raw_ostream &O) {
1283e8d8bef9SDimitry Andric   printExpSrcN(MI, OpNo, STI, O, 3);
12840b57cec5SDimitry Andric }
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
12870b57cec5SDimitry Andric                                     const MCSubtargetInfo &STI,
12880b57cec5SDimitry Andric                                     raw_ostream &O) {
1289e8d8bef9SDimitry Andric   using namespace llvm::AMDGPU::Exp;
12900b57cec5SDimitry Andric 
1291e8d8bef9SDimitry Andric   // This is really a 6 bit field.
1292e8d8bef9SDimitry Andric   unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
1293e8d8bef9SDimitry Andric 
1294e8d8bef9SDimitry Andric   int Index;
1295e8d8bef9SDimitry Andric   StringRef TgtName;
1296e8d8bef9SDimitry Andric   if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
1297e8d8bef9SDimitry Andric     O << ' ' << TgtName;
1298e8d8bef9SDimitry Andric     if (Index >= 0)
1299e8d8bef9SDimitry Andric       O << Index;
1300e8d8bef9SDimitry Andric   } else {
1301e8d8bef9SDimitry Andric     O << " invalid_target_" << Id;
13020b57cec5SDimitry Andric   }
13030b57cec5SDimitry Andric }
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,
13060b57cec5SDimitry Andric                                bool IsPacked, bool HasDstSel) {
13070b57cec5SDimitry Andric   int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);
13080b57cec5SDimitry Andric 
13090b57cec5SDimitry Andric   for (int I = 0; I < NumOps; ++I) {
13100b57cec5SDimitry Andric     if (!!(Ops[I] & Mod) != DefaultValue)
13110b57cec5SDimitry Andric       return false;
13120b57cec5SDimitry Andric   }
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric   if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)
13150b57cec5SDimitry Andric     return false;
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric   return true;
13180b57cec5SDimitry Andric }
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,
13210b57cec5SDimitry Andric                                             StringRef Name,
13220b57cec5SDimitry Andric                                             unsigned Mod,
13230b57cec5SDimitry Andric                                             raw_ostream &O) {
13240b57cec5SDimitry Andric   unsigned Opc = MI->getOpcode();
13250b57cec5SDimitry Andric   int NumOps = 0;
13260b57cec5SDimitry Andric   int Ops[3];
13270b57cec5SDimitry Andric 
13287a6dacacSDimitry Andric   std::pair<int, int> MOps[] = {
13297a6dacacSDimitry Andric       {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},
13307a6dacacSDimitry Andric       {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},
13317a6dacacSDimitry Andric       {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};
13327a6dacacSDimitry Andric   int DefaultValue = (Mod == SISrcMods::OP_SEL_1);
13337a6dacacSDimitry Andric 
13347a6dacacSDimitry Andric   for (auto [SrcMod, Src] : MOps) {
13357a6dacacSDimitry Andric     if (!AMDGPU::hasNamedOperand(Opc, Src))
13360b57cec5SDimitry Andric       break;
13370b57cec5SDimitry Andric 
13387a6dacacSDimitry Andric     int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);
13397a6dacacSDimitry Andric     Ops[NumOps++] =
13407a6dacacSDimitry Andric         (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;
13410b57cec5SDimitry Andric   }
13420b57cec5SDimitry Andric 
1343b3edf446SDimitry Andric   // Print three values of neg/opsel for wmma instructions (prints 0 when there
1344b3edf446SDimitry Andric   // is no src_modifier operand instead of not printing anything).
1345b3edf446SDimitry Andric   if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsSWMMAC ||
1346b3edf446SDimitry Andric       MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsWMMA) {
1347b3edf446SDimitry Andric     NumOps = 0;
1348b3edf446SDimitry Andric     int DefaultValue = Mod == SISrcMods::OP_SEL_1;
1349b3edf446SDimitry Andric     for (int OpName :
1350b3edf446SDimitry Andric          {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
1351b3edf446SDimitry Andric           AMDGPU::OpName::src2_modifiers}) {
1352b3edf446SDimitry Andric       int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);
1353b3edf446SDimitry Andric       if (Idx != -1)
1354b3edf446SDimitry Andric         Ops[NumOps++] = MI->getOperand(Idx).getImm();
1355b3edf446SDimitry Andric       else
1356b3edf446SDimitry Andric         Ops[NumOps++] = DefaultValue;
1357b3edf446SDimitry Andric     }
1358b3edf446SDimitry Andric   }
1359b3edf446SDimitry Andric 
13600b57cec5SDimitry Andric   const bool HasDstSel =
13610b57cec5SDimitry Andric     NumOps > 0 &&
13620b57cec5SDimitry Andric     Mod == SISrcMods::OP_SEL_0 &&
13630b57cec5SDimitry Andric     MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric   const bool IsPacked =
13660b57cec5SDimitry Andric     MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;
13670b57cec5SDimitry Andric 
13680b57cec5SDimitry Andric   if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))
13690b57cec5SDimitry Andric     return;
13700b57cec5SDimitry Andric 
13710b57cec5SDimitry Andric   O << Name;
13720b57cec5SDimitry Andric   for (int I = 0; I < NumOps; ++I) {
13730b57cec5SDimitry Andric     if (I != 0)
13740b57cec5SDimitry Andric       O << ',';
13750b57cec5SDimitry Andric 
13760b57cec5SDimitry Andric     O << !!(Ops[I] & Mod);
13770b57cec5SDimitry Andric   }
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric   if (HasDstSel) {
13800b57cec5SDimitry Andric     O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);
13810b57cec5SDimitry Andric   }
13820b57cec5SDimitry Andric 
13830b57cec5SDimitry Andric   O << ']';
13840b57cec5SDimitry Andric }
13850b57cec5SDimitry Andric 
13860b57cec5SDimitry Andric void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,
13870b57cec5SDimitry Andric                                    const MCSubtargetInfo &STI,
13880b57cec5SDimitry Andric                                    raw_ostream &O) {
13890b57cec5SDimitry Andric   unsigned Opc = MI->getOpcode();
1390b3edf446SDimitry Andric   if (isCvt_F32_Fp8_Bf8_e64(Opc)) {
1391b3edf446SDimitry Andric     auto SrcMod =
1392b3edf446SDimitry Andric         AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
1393b3edf446SDimitry Andric     unsigned Mod = MI->getOperand(SrcMod).getImm();
1394b3edf446SDimitry Andric     unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);
1395b3edf446SDimitry Andric     unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);
1396b3edf446SDimitry Andric     if (Index0 || Index1)
1397b3edf446SDimitry Andric       O << " op_sel:[" << Index0 << ',' << Index1 << ']';
1398b3edf446SDimitry Andric     return;
1399b3edf446SDimitry Andric   }
1400bdd1243dSDimitry Andric   if (isPermlane16(Opc)) {
14010b57cec5SDimitry Andric     auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
14020b57cec5SDimitry Andric     auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);
14030b57cec5SDimitry Andric     unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);
14040b57cec5SDimitry Andric     unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);
14050b57cec5SDimitry Andric     if (FI || BC)
14060b57cec5SDimitry Andric       O << " op_sel:[" << FI << ',' << BC << ']';
14070b57cec5SDimitry Andric     return;
14080b57cec5SDimitry Andric   }
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric   printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,
14140b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
14150b57cec5SDimitry Andric                                      raw_ostream &O) {
14160b57cec5SDimitry Andric   printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,
14200b57cec5SDimitry Andric                                    const MCSubtargetInfo &STI,
14210b57cec5SDimitry Andric                                    raw_ostream &O) {
14220b57cec5SDimitry Andric   printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);
14230b57cec5SDimitry Andric }
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,
14260b57cec5SDimitry Andric                                    const MCSubtargetInfo &STI,
14270b57cec5SDimitry Andric                                    raw_ostream &O) {
14280b57cec5SDimitry Andric   printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);
14290b57cec5SDimitry Andric }
14300b57cec5SDimitry Andric 
1431b3edf446SDimitry Andric void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,
1432b3edf446SDimitry Andric                                           const MCSubtargetInfo &STI,
1433b3edf446SDimitry Andric                                           raw_ostream &O) {
1434b3edf446SDimitry Andric   auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1435b3edf446SDimitry Andric   if (Imm == 0)
1436b3edf446SDimitry Andric     return;
1437b3edf446SDimitry Andric 
1438b3edf446SDimitry Andric   O << " index_key:" << Imm;
1439b3edf446SDimitry Andric }
1440b3edf446SDimitry Andric 
1441b3edf446SDimitry Andric void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,
1442b3edf446SDimitry Andric                                            const MCSubtargetInfo &STI,
1443b3edf446SDimitry Andric                                            raw_ostream &O) {
1444b3edf446SDimitry Andric   auto Imm = MI->getOperand(OpNo).getImm() & 0x7;
1445b3edf446SDimitry Andric   if (Imm == 0)
1446b3edf446SDimitry Andric     return;
1447b3edf446SDimitry Andric 
1448b3edf446SDimitry Andric   O << " index_key:" << Imm;
1449b3edf446SDimitry Andric }
1450b3edf446SDimitry Andric 
14510b57cec5SDimitry Andric void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
14520b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
14530b57cec5SDimitry Andric                                         raw_ostream &O) {
14540b57cec5SDimitry Andric   unsigned Imm = MI->getOperand(OpNum).getImm();
14550b57cec5SDimitry Andric   switch (Imm) {
14560b57cec5SDimitry Andric   case 0:
14570b57cec5SDimitry Andric     O << "p10";
14580b57cec5SDimitry Andric     break;
14590b57cec5SDimitry Andric   case 1:
14600b57cec5SDimitry Andric     O << "p20";
14610b57cec5SDimitry Andric     break;
14620b57cec5SDimitry Andric   case 2:
14630b57cec5SDimitry Andric     O << "p0";
14640b57cec5SDimitry Andric     break;
14650b57cec5SDimitry Andric   default:
14660b57cec5SDimitry Andric     O << "invalid_param_" << Imm;
14670b57cec5SDimitry Andric   }
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,
14710b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
14720b57cec5SDimitry Andric                                         raw_ostream &O) {
14730b57cec5SDimitry Andric   unsigned Attr = MI->getOperand(OpNum).getImm();
14740b57cec5SDimitry Andric   O << "attr" << Attr;
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric 
14770b57cec5SDimitry Andric void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
14780b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
14790b57cec5SDimitry Andric                                         raw_ostream &O) {
14800b57cec5SDimitry Andric   unsigned Chan = MI->getOperand(OpNum).getImm();
14810b57cec5SDimitry Andric   O << '.' << "xyzw"[Chan & 0x3];
14820b57cec5SDimitry Andric }
14830b57cec5SDimitry Andric 
148406c3fb27SDimitry Andric void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,
14850b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
14860b57cec5SDimitry Andric                                         raw_ostream &O) {
14870b57cec5SDimitry Andric   using namespace llvm::AMDGPU::VGPRIndexMode;
14880b57cec5SDimitry Andric   unsigned Val = MI->getOperand(OpNo).getImm();
14890b57cec5SDimitry Andric 
14900b57cec5SDimitry Andric   if ((Val & ~ENABLE_MASK) != 0) {
1491e8d8bef9SDimitry Andric     O << formatHex(static_cast<uint64_t>(Val));
14920b57cec5SDimitry Andric   } else {
14930b57cec5SDimitry Andric     O << "gpr_idx(";
14940b57cec5SDimitry Andric     bool NeedComma = false;
14950b57cec5SDimitry Andric     for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
14960b57cec5SDimitry Andric       if (Val & (1 << ModeId)) {
14970b57cec5SDimitry Andric         if (NeedComma)
14980b57cec5SDimitry Andric           O << ',';
14990b57cec5SDimitry Andric         O << IdSymbolic[ModeId];
15000b57cec5SDimitry Andric         NeedComma = true;
15010b57cec5SDimitry Andric       }
15020b57cec5SDimitry Andric     }
15030b57cec5SDimitry Andric     O << ')';
15040b57cec5SDimitry Andric   }
15050b57cec5SDimitry Andric }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
15080b57cec5SDimitry Andric                                         const MCSubtargetInfo &STI,
15090b57cec5SDimitry Andric                                         raw_ostream &O) {
151081ad6265SDimitry Andric   printRegularOperand(MI, OpNo, STI, O);
15110b57cec5SDimitry Andric   O  << ", ";
151281ad6265SDimitry Andric   printRegularOperand(MI, OpNo + 1, STI, O);
15130b57cec5SDimitry Andric }
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
15160b57cec5SDimitry Andric                                    raw_ostream &O, StringRef Asm,
15170b57cec5SDimitry Andric                                    StringRef Default) {
15180b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
15190b57cec5SDimitry Andric   assert(Op.isImm());
15200b57cec5SDimitry Andric   if (Op.getImm() == 1) {
15210b57cec5SDimitry Andric     O << Asm;
15220b57cec5SDimitry Andric   } else {
15230b57cec5SDimitry Andric     O << Default;
15240b57cec5SDimitry Andric   }
15250b57cec5SDimitry Andric }
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
15280b57cec5SDimitry Andric                                    raw_ostream &O, char Asm) {
15290b57cec5SDimitry Andric   const MCOperand &Op = MI->getOperand(OpNo);
15300b57cec5SDimitry Andric   assert(Op.isImm());
15310b57cec5SDimitry Andric   if (Op.getImm() == 1)
15320b57cec5SDimitry Andric     O << Asm;
15330b57cec5SDimitry Andric }
15340b57cec5SDimitry Andric 
15350b57cec5SDimitry Andric void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
15360b57cec5SDimitry Andric                                     const MCSubtargetInfo &STI,
15370b57cec5SDimitry Andric                                     raw_ostream &O) {
15380b57cec5SDimitry Andric   int Imm = MI->getOperand(OpNo).getImm();
15390b57cec5SDimitry Andric   if (Imm == SIOutMods::MUL2)
15400b57cec5SDimitry Andric     O << " mul:2";
15410b57cec5SDimitry Andric   else if (Imm == SIOutMods::MUL4)
15420b57cec5SDimitry Andric     O << " mul:4";
15430b57cec5SDimitry Andric   else if (Imm == SIOutMods::DIV2)
15440b57cec5SDimitry Andric     O << " div:2";
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric 
15470b57cec5SDimitry Andric void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
15480b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
15490b57cec5SDimitry Andric                                      raw_ostream &O) {
15500b57cec5SDimitry Andric   using namespace llvm::AMDGPU::SendMsg;
15510b57cec5SDimitry Andric 
15520b57cec5SDimitry Andric   const unsigned Imm16 = MI->getOperand(OpNo).getImm();
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric   uint16_t MsgId;
15550b57cec5SDimitry Andric   uint16_t OpId;
15560b57cec5SDimitry Andric   uint16_t StreamId;
155781ad6265SDimitry Andric   decodeMsg(Imm16, MsgId, OpId, StreamId, STI);
15580b57cec5SDimitry Andric 
155981ad6265SDimitry Andric   StringRef MsgName = getMsgName(MsgId, STI);
156081ad6265SDimitry Andric 
156181ad6265SDimitry Andric   if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&
1562fe6060f1SDimitry Andric       isValidMsgStream(MsgId, OpId, StreamId, STI)) {
156381ad6265SDimitry Andric     O << "sendmsg(" << MsgName;
156481ad6265SDimitry Andric     if (msgRequiresOp(MsgId, STI)) {
156581ad6265SDimitry Andric       O << ", " << getMsgOpName(MsgId, OpId, STI);
156681ad6265SDimitry Andric       if (msgSupportsStream(MsgId, OpId, STI)) {
15670b57cec5SDimitry Andric         O << ", " << StreamId;
15680b57cec5SDimitry Andric       }
15690b57cec5SDimitry Andric     }
15700b57cec5SDimitry Andric     O << ')';
15710b57cec5SDimitry Andric   } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {
15720b57cec5SDimitry Andric     O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';
15730b57cec5SDimitry Andric   } else {
15740b57cec5SDimitry Andric     O << Imm16; // Unknown imm16 code.
15750b57cec5SDimitry Andric   }
15760b57cec5SDimitry Andric }
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric static void printSwizzleBitmask(const uint16_t AndMask,
15790b57cec5SDimitry Andric                                 const uint16_t OrMask,
15800b57cec5SDimitry Andric                                 const uint16_t XorMask,
15810b57cec5SDimitry Andric                                 raw_ostream &O) {
15820b57cec5SDimitry Andric   using namespace llvm::AMDGPU::Swizzle;
15830b57cec5SDimitry Andric 
15840b57cec5SDimitry Andric   uint16_t Probe0 = ((0            & AndMask) | OrMask) ^ XorMask;
15850b57cec5SDimitry Andric   uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric   O << "\"";
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {
15900b57cec5SDimitry Andric     uint16_t p0 = Probe0 & Mask;
15910b57cec5SDimitry Andric     uint16_t p1 = Probe1 & Mask;
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric     if (p0 == p1) {
15940b57cec5SDimitry Andric       if (p0 == 0) {
15950b57cec5SDimitry Andric         O << "0";
15960b57cec5SDimitry Andric       } else {
15970b57cec5SDimitry Andric         O << "1";
15980b57cec5SDimitry Andric       }
15990b57cec5SDimitry Andric     } else {
16000b57cec5SDimitry Andric       if (p0 == 0) {
16010b57cec5SDimitry Andric         O << "p";
16020b57cec5SDimitry Andric       } else {
16030b57cec5SDimitry Andric         O << "i";
16040b57cec5SDimitry Andric       }
16050b57cec5SDimitry Andric     }
16060b57cec5SDimitry Andric   }
16070b57cec5SDimitry Andric 
16080b57cec5SDimitry Andric   O << "\"";
16090b57cec5SDimitry Andric }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,
16120b57cec5SDimitry Andric                                      const MCSubtargetInfo &STI,
16130b57cec5SDimitry Andric                                      raw_ostream &O) {
16140b57cec5SDimitry Andric   using namespace llvm::AMDGPU::Swizzle;
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric   uint16_t Imm = MI->getOperand(OpNo).getImm();
16170b57cec5SDimitry Andric   if (Imm == 0) {
16180b57cec5SDimitry Andric     return;
16190b57cec5SDimitry Andric   }
16200b57cec5SDimitry Andric 
16210b57cec5SDimitry Andric   O << " offset:";
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric   if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric     O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];
16260b57cec5SDimitry Andric     for (unsigned I = 0; I < LANE_NUM; ++I) {
16270b57cec5SDimitry Andric       O << ",";
16280b57cec5SDimitry Andric       O << formatDec(Imm & LANE_MASK);
16290b57cec5SDimitry Andric       Imm >>= LANE_SHIFT;
16300b57cec5SDimitry Andric     }
16310b57cec5SDimitry Andric     O << ")";
16320b57cec5SDimitry Andric 
16330b57cec5SDimitry Andric   } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {
16340b57cec5SDimitry Andric 
16350b57cec5SDimitry Andric     uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;
16360b57cec5SDimitry Andric     uint16_t OrMask  = (Imm >> BITMASK_OR_SHIFT)  & BITMASK_MASK;
16370b57cec5SDimitry Andric     uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;
16380b57cec5SDimitry Andric 
1639bdd1243dSDimitry Andric     if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric       O << "swizzle(" << IdSymbolic[ID_SWAP];
16420b57cec5SDimitry Andric       O << ",";
16430b57cec5SDimitry Andric       O << formatDec(XorMask);
16440b57cec5SDimitry Andric       O << ")";
16450b57cec5SDimitry Andric 
1646bdd1243dSDimitry Andric     } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&
16470b57cec5SDimitry Andric                isPowerOf2_64(XorMask + 1)) {
16480b57cec5SDimitry Andric 
16490b57cec5SDimitry Andric       O << "swizzle(" << IdSymbolic[ID_REVERSE];
16500b57cec5SDimitry Andric       O << ",";
16510b57cec5SDimitry Andric       O << formatDec(XorMask + 1);
16520b57cec5SDimitry Andric       O << ")";
16530b57cec5SDimitry Andric 
16540b57cec5SDimitry Andric     } else {
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric       uint16_t GroupSize = BITMASK_MAX - AndMask + 1;
16570b57cec5SDimitry Andric       if (GroupSize > 1 &&
16580b57cec5SDimitry Andric           isPowerOf2_64(GroupSize) &&
16590b57cec5SDimitry Andric           OrMask < GroupSize &&
16600b57cec5SDimitry Andric           XorMask == 0) {
16610b57cec5SDimitry Andric 
16620b57cec5SDimitry Andric         O << "swizzle(" << IdSymbolic[ID_BROADCAST];
16630b57cec5SDimitry Andric         O << ",";
16640b57cec5SDimitry Andric         O << formatDec(GroupSize);
16650b57cec5SDimitry Andric         O << ",";
16660b57cec5SDimitry Andric         O << formatDec(OrMask);
16670b57cec5SDimitry Andric         O << ")";
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric       } else {
16700b57cec5SDimitry Andric         O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];
16710b57cec5SDimitry Andric         O << ",";
16720b57cec5SDimitry Andric         printSwizzleBitmask(AndMask, OrMask, XorMask, O);
16730b57cec5SDimitry Andric         O << ")";
16740b57cec5SDimitry Andric       }
16750b57cec5SDimitry Andric     }
16760b57cec5SDimitry Andric   } else {
16770b57cec5SDimitry Andric     printU16ImmDecOperand(MI, OpNo, O);
16780b57cec5SDimitry Andric   }
16790b57cec5SDimitry Andric }
16800b57cec5SDimitry Andric 
168106c3fb27SDimitry Andric void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,
16820b57cec5SDimitry Andric                                       const MCSubtargetInfo &STI,
16830b57cec5SDimitry Andric                                       raw_ostream &O) {
16840b57cec5SDimitry Andric   AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());
16850b57cec5SDimitry Andric 
16860b57cec5SDimitry Andric   unsigned SImm16 = MI->getOperand(OpNo).getImm();
16870b57cec5SDimitry Andric   unsigned Vmcnt, Expcnt, Lgkmcnt;
16880b57cec5SDimitry Andric   decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);
16890b57cec5SDimitry Andric 
169004eeddc0SDimitry Andric   bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);
169104eeddc0SDimitry Andric   bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);
169204eeddc0SDimitry Andric   bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);
169304eeddc0SDimitry Andric   bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;
169404eeddc0SDimitry Andric 
16950b57cec5SDimitry Andric   bool NeedSpace = false;
16960b57cec5SDimitry Andric 
169704eeddc0SDimitry Andric   if (!IsDefaultVmcnt || PrintAll) {
16980b57cec5SDimitry Andric     O << "vmcnt(" << Vmcnt << ')';
16990b57cec5SDimitry Andric     NeedSpace = true;
17000b57cec5SDimitry Andric   }
17010b57cec5SDimitry Andric 
170204eeddc0SDimitry Andric   if (!IsDefaultExpcnt || PrintAll) {
17030b57cec5SDimitry Andric     if (NeedSpace)
17040b57cec5SDimitry Andric       O << ' ';
17050b57cec5SDimitry Andric     O << "expcnt(" << Expcnt << ')';
17060b57cec5SDimitry Andric     NeedSpace = true;
17070b57cec5SDimitry Andric   }
17080b57cec5SDimitry Andric 
170904eeddc0SDimitry Andric   if (!IsDefaultLgkmcnt || PrintAll) {
17100b57cec5SDimitry Andric     if (NeedSpace)
17110b57cec5SDimitry Andric       O << ' ';
17120b57cec5SDimitry Andric     O << "lgkmcnt(" << Lgkmcnt << ')';
17130b57cec5SDimitry Andric   }
17140b57cec5SDimitry Andric }
17150b57cec5SDimitry Andric 
171681ad6265SDimitry Andric void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,
171781ad6265SDimitry Andric                                     const MCSubtargetInfo &STI,
171881ad6265SDimitry Andric                                     raw_ostream &O) {
171981ad6265SDimitry Andric   using namespace llvm::AMDGPU::DepCtr;
172081ad6265SDimitry Andric 
172181ad6265SDimitry Andric   uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;
172281ad6265SDimitry Andric 
172381ad6265SDimitry Andric   bool HasNonDefaultVal = false;
172481ad6265SDimitry Andric   if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {
172581ad6265SDimitry Andric     int Id = 0;
172681ad6265SDimitry Andric     StringRef Name;
172781ad6265SDimitry Andric     unsigned Val;
172881ad6265SDimitry Andric     bool IsDefault;
172981ad6265SDimitry Andric     bool NeedSpace = false;
173081ad6265SDimitry Andric     while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {
173181ad6265SDimitry Andric       if (!IsDefault || !HasNonDefaultVal) {
173281ad6265SDimitry Andric         if (NeedSpace)
173381ad6265SDimitry Andric           O << ' ';
173481ad6265SDimitry Andric         O << Name << '(' << Val << ')';
173581ad6265SDimitry Andric         NeedSpace = true;
173681ad6265SDimitry Andric       }
173781ad6265SDimitry Andric     }
173881ad6265SDimitry Andric   } else {
173981ad6265SDimitry Andric     O << formatHex(Imm16);
174081ad6265SDimitry Andric   }
174181ad6265SDimitry Andric }
174281ad6265SDimitry Andric 
174306c3fb27SDimitry Andric void AMDGPUInstPrinter::printSDelayALU(const MCInst *MI, unsigned OpNo,
174481ad6265SDimitry Andric                                        const MCSubtargetInfo &STI,
174581ad6265SDimitry Andric                                        raw_ostream &O) {
174681ad6265SDimitry Andric   const char *BadInstId = "/* invalid instid value */";
174781ad6265SDimitry Andric   static const std::array<const char *, 12> InstIds = {
174881ad6265SDimitry Andric       "NO_DEP",        "VALU_DEP_1",    "VALU_DEP_2",
174981ad6265SDimitry Andric       "VALU_DEP_3",    "VALU_DEP_4",    "TRANS32_DEP_1",
175081ad6265SDimitry Andric       "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",
175181ad6265SDimitry Andric       "SALU_CYCLE_1",  "SALU_CYCLE_2",  "SALU_CYCLE_3"};
175281ad6265SDimitry Andric 
175381ad6265SDimitry Andric   const char *BadInstSkip = "/* invalid instskip value */";
175481ad6265SDimitry Andric   static const std::array<const char *, 6> InstSkips = {
175581ad6265SDimitry Andric       "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};
175681ad6265SDimitry Andric 
175781ad6265SDimitry Andric   unsigned SImm16 = MI->getOperand(OpNo).getImm();
175881ad6265SDimitry Andric   const char *Prefix = "";
175981ad6265SDimitry Andric 
176081ad6265SDimitry Andric   unsigned Value = SImm16 & 0xF;
176181ad6265SDimitry Andric   if (Value) {
176281ad6265SDimitry Andric     const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
176381ad6265SDimitry Andric     O << Prefix << "instid0(" << Name << ')';
176481ad6265SDimitry Andric     Prefix = " | ";
176581ad6265SDimitry Andric   }
176681ad6265SDimitry Andric 
176781ad6265SDimitry Andric   Value = (SImm16 >> 4) & 7;
176881ad6265SDimitry Andric   if (Value) {
176981ad6265SDimitry Andric     const char *Name =
177081ad6265SDimitry Andric         Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;
177181ad6265SDimitry Andric     O << Prefix << "instskip(" << Name << ')';
177281ad6265SDimitry Andric     Prefix = " | ";
177381ad6265SDimitry Andric   }
177481ad6265SDimitry Andric 
177581ad6265SDimitry Andric   Value = (SImm16 >> 7) & 0xF;
177681ad6265SDimitry Andric   if (Value) {
177781ad6265SDimitry Andric     const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;
177881ad6265SDimitry Andric     O << Prefix << "instid1(" << Name << ')';
177981ad6265SDimitry Andric     Prefix = " | ";
178081ad6265SDimitry Andric   }
178181ad6265SDimitry Andric 
178281ad6265SDimitry Andric   if (!*Prefix)
178381ad6265SDimitry Andric     O << "0";
178481ad6265SDimitry Andric }
178581ad6265SDimitry Andric 
17860b57cec5SDimitry Andric void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
17870b57cec5SDimitry Andric                                    const MCSubtargetInfo &STI, raw_ostream &O) {
17880b57cec5SDimitry Andric   using namespace llvm::AMDGPU::Hwreg;
17890b57cec5SDimitry Andric   unsigned Val = MI->getOperand(OpNo).getImm();
1790*0fca6ea1SDimitry Andric   auto [Id, Offset, Width] = HwregEncoding::decode(Val);
17910b57cec5SDimitry Andric   StringRef HwRegName = getHwreg(Id, STI);
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric   O << "hwreg(";
17940b57cec5SDimitry Andric   if (!HwRegName.empty()) {
17950b57cec5SDimitry Andric     O << HwRegName;
17960b57cec5SDimitry Andric   } else {
17970b57cec5SDimitry Andric     O << Id;
17980b57cec5SDimitry Andric   }
1799*0fca6ea1SDimitry Andric   if (Width != HwregSize::Default || Offset != HwregOffset::Default)
18000b57cec5SDimitry Andric     O << ", " << Offset << ", " << Width;
18010b57cec5SDimitry Andric   O << ')';
18020b57cec5SDimitry Andric }
18030b57cec5SDimitry Andric 
18040b57cec5SDimitry Andric void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,
18050b57cec5SDimitry Andric                                     const MCSubtargetInfo &STI,
18060b57cec5SDimitry Andric                                     raw_ostream &O) {
18070b57cec5SDimitry Andric   uint16_t Imm = MI->getOperand(OpNo).getImm();
18080b57cec5SDimitry Andric   if (Imm == 0) {
18090b57cec5SDimitry Andric     return;
18100b57cec5SDimitry Andric   }
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   O << ' ' << formatDec(Imm);
18130b57cec5SDimitry Andric }
18140b57cec5SDimitry Andric 
1815*0fca6ea1SDimitry Andric void AMDGPUInstPrinter::printByteSel(const MCInst *MI, unsigned OpNo,
1816*0fca6ea1SDimitry Andric                                      const MCSubtargetInfo &STI,
1817*0fca6ea1SDimitry Andric                                      raw_ostream &O) {
1818*0fca6ea1SDimitry Andric   uint8_t Imm = MI->getOperand(OpNo).getImm();
1819*0fca6ea1SDimitry Andric   if (!Imm)
1820*0fca6ea1SDimitry Andric     return;
1821*0fca6ea1SDimitry Andric 
1822*0fca6ea1SDimitry Andric   O << " byte_sel:" << formatDec(Imm);
1823*0fca6ea1SDimitry Andric }
1824*0fca6ea1SDimitry Andric 
18250b57cec5SDimitry Andric #include "AMDGPUGenAsmWriter.inc"
1826