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