1948 lines · cpp
1//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7// \file8//===----------------------------------------------------------------------===//9 10#include "AMDGPUInstPrinter.h"11#include "MCTargetDesc/AMDGPUMCTargetDesc.h"12#include "SIDefines.h"13#include "Utils/AMDGPUAsmUtils.h"14#include "Utils/AMDGPUBaseInfo.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/MC/MCAsmInfo.h"17#include "llvm/MC/MCExpr.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstrDesc.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegisterInfo.h"22#include "llvm/MC/MCSubtargetInfo.h"23#include "llvm/TargetParser/TargetParser.h"24 25using namespace llvm;26using namespace llvm::AMDGPU;27 28void AMDGPUInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) {29 // FIXME: The current implementation of30 // AsmParser::parseRegisterOrRegisterNumber in MC implies we either emit this31 // as an integer or we provide a name which represents a physical register.32 // For CFI instructions we really want to emit a name for the DWARF register33 // instead, because there may be multiple DWARF registers corresponding to a34 // single physical register. One case where this problem manifests is with35 // wave32/wave64 where using the physical register name is ambiguous: if we36 // write e.g. `.cfi_undefined v0` we lose information about the wavefront37 // size which we need to encode the register in the final DWARF. Ideally we38 // would extend MC to support parsing DWARF register names so we could do39 // something like `.cfi_undefined dwarf_wave32_v0`. For now we just live with40 // non-pretty DWARF register names in assembly text.41 OS << Reg.id();42}43 44void AMDGPUInstPrinter::printInst(const MCInst *MI, uint64_t Address,45 StringRef Annot, const MCSubtargetInfo &STI,46 raw_ostream &OS) {47 printInstruction(MI, Address, STI, OS);48 printAnnotation(OS, Annot);49}50 51void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,52 const MCSubtargetInfo &STI,53 raw_ostream &O) {54 const MCOperand &Op = MI->getOperand(OpNo);55 if (Op.isExpr()) {56 MAI.printExpr(O, *Op.getExpr());57 return;58 }59 60 // It's possible to end up with a 32-bit literal used with a 16-bit operand61 // with ignored high bits. Print as 32-bit anyway in that case.62 int64_t Imm = Op.getImm();63 if (isInt<16>(Imm) || isUInt<16>(Imm))64 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));65 else66 printU32ImmOperand(MI, OpNo, STI, O);67}68 69void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,70 raw_ostream &O) {71 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);72}73 74void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,75 const MCSubtargetInfo &STI,76 raw_ostream &O) {77 const MCOperand &Op = MI->getOperand(OpNo);78 if (Op.isExpr()) {79 MAI.printExpr(O, *Op.getExpr());80 return;81 }82 83 O << formatHex(Op.getImm() & 0xffffffff);84}85 86void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,87 const MCSubtargetInfo &STI,88 raw_ostream &O) {89 // KIMM6490 const MCOperand &Op = MI->getOperand(OpNo);91 if (Op.isExpr()) {92 MAI.printExpr(O, *Op.getExpr());93 return;94 }95 96 printLiteral64(Op.getImm(), O, /*IsFP=*/true);97}98 99void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,100 raw_ostream &O, StringRef BitName) {101 if (MI->getOperand(OpNo).getImm()) {102 O << ' ' << BitName;103 }104}105 106void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,107 const MCSubtargetInfo &STI,108 raw_ostream &O) {109 uint32_t Imm = MI->getOperand(OpNo).getImm();110 if (Imm != 0) {111 O << " offset:";112 113 // GFX12 uses a 24-bit signed offset for VBUFFER.114 const MCInstrDesc &Desc = MII.get(MI->getOpcode());115 bool IsVBuffer = Desc.TSFlags & (SIInstrFlags::MUBUF | SIInstrFlags::MTBUF);116 if (AMDGPU::isGFX12(STI) && IsVBuffer)117 O << formatDec(SignExtend32<24>(Imm));118 else119 printU16ImmDecOperand(MI, OpNo, O);120 }121}122 123void AMDGPUInstPrinter::printFlatOffset(const MCInst *MI, unsigned OpNo,124 const MCSubtargetInfo &STI,125 raw_ostream &O) {126 uint32_t Imm = MI->getOperand(OpNo).getImm();127 if (Imm != 0) {128 O << " offset:";129 130 const MCInstrDesc &Desc = MII.get(MI->getOpcode());131 bool AllowNegative = (Desc.TSFlags & (SIInstrFlags::FlatGlobal |132 SIInstrFlags::FlatScratch)) ||133 AMDGPU::isGFX12(STI);134 135 if (AllowNegative) // Signed offset136 O << formatDec(SignExtend32(Imm, AMDGPU::getNumFlatOffsetBits(STI)));137 else // Unsigned offset138 printU16ImmDecOperand(MI, OpNo, O);139 }140}141 142void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,143 const MCSubtargetInfo &STI,144 raw_ostream &O) {145 printU32ImmOperand(MI, OpNo, STI, O);146}147 148void AMDGPUInstPrinter::printSMEMOffset(const MCInst *MI, unsigned OpNo,149 const MCSubtargetInfo &STI,150 raw_ostream &O) {151 O << formatHex(MI->getOperand(OpNo).getImm());152}153 154void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,155 const MCSubtargetInfo &STI,156 raw_ostream &O) {157 printU32ImmOperand(MI, OpNo, STI, O);158}159 160void AMDGPUInstPrinter::printCPol(const MCInst *MI, unsigned OpNo,161 const MCSubtargetInfo &STI, raw_ostream &O) {162 auto Imm = MI->getOperand(OpNo).getImm();163 164 if (AMDGPU::isGFX12Plus(STI)) {165 const int64_t TH = Imm & CPol::TH;166 const int64_t Scope = Imm & CPol::SCOPE;167 168 if (Imm & CPol::SCAL)169 O << " scale_offset";170 171 printTH(MI, TH, Scope, O);172 printScope(Scope, O);173 174 if (Imm & CPol::NV)175 O << " nv";176 177 return;178 }179 180 if (Imm & CPol::GLC)181 O << ((AMDGPU::isGFX940(STI) &&182 !(MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SMRD)) ? " sc0"183 : " glc");184 if (Imm & CPol::SLC)185 O << (AMDGPU::isGFX940(STI) ? " nt" : " slc");186 if ((Imm & CPol::DLC) && AMDGPU::isGFX10Plus(STI))187 O << " dlc";188 if ((Imm & CPol::SCC) && AMDGPU::isGFX90A(STI))189 O << (AMDGPU::isGFX940(STI) ? " sc1" : " scc");190 if (Imm & ~CPol::ALL_pregfx12)191 O << " /* unexpected cache policy bit */";192}193 194void AMDGPUInstPrinter::printTH(const MCInst *MI, int64_t TH, int64_t Scope,195 raw_ostream &O) {196 // For th = 0 do not print this field197 if (TH == 0)198 return;199 200 const unsigned Opcode = MI->getOpcode();201 const MCInstrDesc &TID = MII.get(Opcode);202 unsigned THType = AMDGPU::getTemporalHintType(TID);203 bool IsStore = (THType == AMDGPU::CPol::TH_TYPE_STORE);204 205 O << " th:";206 207 if (THType == AMDGPU::CPol::TH_TYPE_ATOMIC) {208 O << "TH_ATOMIC_";209 if (TH & AMDGPU::CPol::TH_ATOMIC_CASCADE) {210 if (Scope >= AMDGPU::CPol::SCOPE_DEV)211 O << "CASCADE" << (TH & AMDGPU::CPol::TH_ATOMIC_NT ? "_NT" : "_RT");212 else213 O << formatHex(TH);214 } else if (TH & AMDGPU::CPol::TH_ATOMIC_NT)215 O << "NT" << (TH & AMDGPU::CPol::TH_ATOMIC_RETURN ? "_RETURN" : "");216 else if (TH & AMDGPU::CPol::TH_ATOMIC_RETURN)217 O << "RETURN";218 else219 O << formatHex(TH);220 } else {221 if (!IsStore && TH == AMDGPU::CPol::TH_RESERVED)222 O << formatHex(TH);223 else {224 O << (IsStore ? "TH_STORE_" : "TH_LOAD_");225 switch (TH) {226 case AMDGPU::CPol::TH_NT:227 O << "NT";228 break;229 case AMDGPU::CPol::TH_HT:230 O << "HT";231 break;232 case AMDGPU::CPol::TH_BYPASS: // or LU or WB233 O << (Scope == AMDGPU::CPol::SCOPE_SYS ? "BYPASS"234 : (IsStore ? "WB" : "LU"));235 break;236 case AMDGPU::CPol::TH_NT_RT:237 O << "NT_RT";238 break;239 case AMDGPU::CPol::TH_RT_NT:240 O << "RT_NT";241 break;242 case AMDGPU::CPol::TH_NT_HT:243 O << "NT_HT";244 break;245 case AMDGPU::CPol::TH_NT_WB:246 O << "NT_WB";247 break;248 default:249 llvm_unreachable("unexpected th value");250 }251 }252 }253}254 255void AMDGPUInstPrinter::printScope(int64_t Scope, raw_ostream &O) {256 if (Scope == CPol::SCOPE_CU)257 return;258 259 O << " scope:";260 261 if (Scope == CPol::SCOPE_SE)262 O << "SCOPE_SE";263 else if (Scope == CPol::SCOPE_DEV)264 O << "SCOPE_DEV";265 else if (Scope == CPol::SCOPE_SYS)266 O << "SCOPE_SYS";267 else268 llvm_unreachable("unexpected scope policy value");269}270 271void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo,272 const MCSubtargetInfo &STI, raw_ostream &O) {273 unsigned Dim = MI->getOperand(OpNo).getImm();274 O << " dim:SQ_RSRC_IMG_";275 276 const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim);277 if (DimInfo)278 O << DimInfo->AsmSuffix;279 else280 O << Dim;281}282 283void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo,284 const MCSubtargetInfo &STI, raw_ostream &O) {285 if (STI.hasFeature(AMDGPU::FeatureR128A16))286 printNamedBit(MI, OpNo, O, "a16");287 else288 printNamedBit(MI, OpNo, O, "r128");289}290 291void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo,292 const MCSubtargetInfo &STI,293 raw_ostream &O) {294}295 296void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,297 const MCSubtargetInfo &STI,298 raw_ostream &O) {299 using namespace llvm::AMDGPU::MTBUFFormat;300 301 int OpNo =302 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::format);303 assert(OpNo != -1);304 305 unsigned Val = MI->getOperand(OpNo).getImm();306 if (AMDGPU::isGFX10Plus(STI)) {307 if (Val == UFMT_DEFAULT)308 return;309 if (isValidUnifiedFormat(Val, STI)) {310 O << " format:[" << getUnifiedFormatName(Val, STI) << ']';311 } else {312 O << " format:" << Val;313 }314 } else {315 if (Val == DFMT_NFMT_DEFAULT)316 return;317 if (isValidDfmtNfmt(Val, STI)) {318 unsigned Dfmt;319 unsigned Nfmt;320 decodeDfmtNfmt(Val, Dfmt, Nfmt);321 O << " format:[";322 if (Dfmt != DFMT_DEFAULT) {323 O << getDfmtName(Dfmt);324 if (Nfmt != NFMT_DEFAULT) {325 O << ',';326 }327 }328 if (Nfmt != NFMT_DEFAULT) {329 O << getNfmtName(Nfmt, STI);330 }331 O << ']';332 } else {333 O << " format:" << Val;334 }335 }336}337 338// \returns a low 256 vgpr representing a high vgpr \p Reg [v256..v1023] or339// \p Reg itself otherwise.340static MCRegister getRegForPrinting(MCRegister Reg, const MCRegisterInfo &MRI) {341 unsigned Enc = MRI.getEncodingValue(Reg);342 unsigned Idx = Enc & AMDGPU::HWEncoding::REG_IDX_MASK;343 if (Idx < 0x100)344 return Reg;345 346 unsigned RegNo = Idx % 0x100;347 const MCRegisterClass *RC = getVGPRPhysRegClass(Reg, MRI);348 if (RC->getID() == AMDGPU::VGPR_16RegClassID) {349 // This class has 2048 registers with interleaved lo16 and hi16.350 RegNo *= 2;351 if (Enc & AMDGPU::HWEncoding::IS_HI16)352 ++RegNo;353 }354 355 return RC->getRegister(RegNo);356}357 358// Restore MSBs of a VGPR above 255 from the MCInstrAnalysis.359static MCRegister getRegFromMIA(MCRegister Reg, unsigned OpNo,360 const MCInstrDesc &Desc,361 const MCRegisterInfo &MRI,362 const AMDGPUMCInstrAnalysis &MIA) {363 unsigned VgprMSBs = MIA.getVgprMSBs();364 if (!VgprMSBs)365 return Reg;366 367 unsigned Enc = MRI.getEncodingValue(Reg);368 if (!(Enc & AMDGPU::HWEncoding::IS_VGPR))369 return Reg;370 371 auto Ops = AMDGPU::getVGPRLoweringOperandTables(Desc);372 if (!Ops.first)373 return Reg;374 unsigned Opc = Desc.getOpcode();375 unsigned I;376 for (I = 0; I < 4; ++I) {377 if (Ops.first[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&378 (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.first[I]) == OpNo)379 break;380 if (Ops.second && Ops.second[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&381 (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.second[I]) == OpNo)382 break;383 }384 if (I == 4)385 return Reg;386 unsigned OpMSBs = (VgprMSBs >> (I * 2)) & 3;387 if (!OpMSBs)388 return Reg;389 if (MCRegister NewReg = AMDGPU::getVGPRWithMSBs(Reg, OpMSBs, MRI))390 return NewReg;391 return Reg;392}393 394void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,395 const MCRegisterInfo &MRI) {396#if !defined(NDEBUG)397 switch (Reg.id()) {398 case AMDGPU::FP_REG:399 case AMDGPU::SP_REG:400 case AMDGPU::PRIVATE_RSRC_REG:401 llvm_unreachable("pseudo-register should not ever be emitted");402 default:403 break;404 }405#endif406 407 MCRegister PrintReg = getRegForPrinting(Reg, MRI);408 O << getRegisterName(PrintReg);409 410 if (PrintReg != Reg)411 O << " /*" << getRegisterName(Reg) << "*/";412}413 414void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, unsigned Opc,415 unsigned OpNo, raw_ostream &O,416 const MCRegisterInfo &MRI) {417 if (MIA)418 Reg = getRegFromMIA(Reg, OpNo, MII.get(Opc), MRI,419 *static_cast<const AMDGPUMCInstrAnalysis *>(MIA));420 printRegOperand(Reg, O, MRI);421}422 423void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,424 const MCSubtargetInfo &STI, raw_ostream &O) {425 auto Opcode = MI->getOpcode();426 auto Flags = MII.get(Opcode).TSFlags;427 if (OpNo == 0) {428 if (Flags & SIInstrFlags::VOP3 && Flags & SIInstrFlags::DPP)429 O << "_e64_dpp";430 else if (Flags & SIInstrFlags::VOP3) {431 if (!getVOP3IsSingle(Opcode))432 O << "_e64";433 } else if (Flags & SIInstrFlags::DPP)434 O << "_dpp";435 else if (Flags & SIInstrFlags::SDWA)436 O << "_sdwa";437 else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) ||438 ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode)))439 O << "_e32";440 O << " ";441 }442 443 printRegularOperand(MI, OpNo, STI, O);444 445 // Print default vcc/vcc_lo operand.446 switch (Opcode) {447 default: break;448 449 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:450 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:451 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:452 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:453 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:454 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:455 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:456 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:457 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:458 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:459 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:460 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:461 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:462 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:463 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:464 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:465 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:466 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:467 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:468 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:469 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:470 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:471 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:472 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:473 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:474 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:475 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:476 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:477 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:478 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:479 printDefaultVccOperand(false, STI, O);480 break;481 }482}483 484void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo,485 const MCSubtargetInfo &STI, raw_ostream &O) {486 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI))487 O << " ";488 else489 O << "_e32 ";490 491 printRegularOperand(MI, OpNo, STI, O);492}493 494void AMDGPUInstPrinter::printAVLdSt32Align2RegOp(const MCInst *MI,495 unsigned OpNo,496 const MCSubtargetInfo &STI,497 raw_ostream &O) {498 MCRegister Reg = MI->getOperand(OpNo).getReg();499 500 // On targets with an even alignment requirement501 if (MCRegister SubReg = MRI.getSubReg(Reg, AMDGPU::sub0))502 Reg = SubReg;503 printRegOperand(Reg, O, MRI);504}505 506void AMDGPUInstPrinter::printImmediateInt16(uint32_t Imm,507 const MCSubtargetInfo &STI,508 raw_ostream &O) {509 int32_t SImm = static_cast<int32_t>(Imm);510 if (isInlinableIntLiteral(SImm)) {511 O << SImm;512 return;513 }514 515 if (printImmediateFloat32(Imm, STI, O))516 return;517 518 O << formatHex(static_cast<uint64_t>(Imm & 0xffff));519}520 521static bool printImmediateFP16(uint32_t Imm, const MCSubtargetInfo &STI,522 raw_ostream &O) {523 if (Imm == 0x3C00)524 O << "1.0";525 else if (Imm == 0xBC00)526 O << "-1.0";527 else if (Imm == 0x3800)528 O << "0.5";529 else if (Imm == 0xB800)530 O << "-0.5";531 else if (Imm == 0x4000)532 O << "2.0";533 else if (Imm == 0xC000)534 O << "-2.0";535 else if (Imm == 0x4400)536 O << "4.0";537 else if (Imm == 0xC400)538 O << "-4.0";539 else if (Imm == 0x3118 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))540 O << "0.15915494";541 else542 return false;543 544 return true;545}546 547static bool printImmediateBFloat16(uint32_t Imm, const MCSubtargetInfo &STI,548 raw_ostream &O) {549 if (Imm == 0x3F80)550 O << "1.0";551 else if (Imm == 0xBF80)552 O << "-1.0";553 else if (Imm == 0x3F00)554 O << "0.5";555 else if (Imm == 0xBF00)556 O << "-0.5";557 else if (Imm == 0x4000)558 O << "2.0";559 else if (Imm == 0xC000)560 O << "-2.0";561 else if (Imm == 0x4080)562 O << "4.0";563 else if (Imm == 0xC080)564 O << "-4.0";565 else if (Imm == 0x3E22 && STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))566 O << "0.15915494";567 else568 return false;569 570 return true;571}572 573void AMDGPUInstPrinter::printImmediateBF16(uint32_t Imm,574 const MCSubtargetInfo &STI,575 raw_ostream &O) {576 int16_t SImm = static_cast<int16_t>(Imm);577 if (isInlinableIntLiteral(SImm)) {578 O << SImm;579 return;580 }581 582 if (printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))583 return;584 585 O << formatHex(static_cast<uint64_t>(Imm));586}587 588void AMDGPUInstPrinter::printImmediateF16(uint32_t Imm,589 const MCSubtargetInfo &STI,590 raw_ostream &O) {591 int16_t SImm = static_cast<int16_t>(Imm);592 if (isInlinableIntLiteral(SImm)) {593 O << SImm;594 return;595 }596 597 uint16_t HImm = static_cast<uint16_t>(Imm);598 if (printImmediateFP16(HImm, STI, O))599 return;600 601 uint64_t Imm16 = static_cast<uint16_t>(Imm);602 O << formatHex(Imm16);603}604 605void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, uint8_t OpType,606 const MCSubtargetInfo &STI,607 raw_ostream &O) {608 int32_t SImm = static_cast<int32_t>(Imm);609 if (isInlinableIntLiteral(SImm)) {610 O << SImm;611 return;612 }613 614 switch (OpType) {615 case AMDGPU::OPERAND_REG_IMM_V2INT16:616 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:617 if (printImmediateFloat32(Imm, STI, O))618 return;619 break;620 case AMDGPU::OPERAND_REG_IMM_V2FP16:621 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:622 if (isUInt<16>(Imm) &&623 printImmediateFP16(static_cast<uint16_t>(Imm), STI, O))624 return;625 break;626 case AMDGPU::OPERAND_REG_IMM_V2BF16:627 case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:628 if (isUInt<16>(Imm) &&629 printImmediateBFloat16(static_cast<uint16_t>(Imm), STI, O))630 return;631 break;632 case AMDGPU::OPERAND_REG_IMM_NOINLINE_V2FP16:633 break;634 default:635 llvm_unreachable("bad operand type");636 }637 638 O << formatHex(static_cast<uint64_t>(Imm));639}640 641bool AMDGPUInstPrinter::printImmediateFloat32(uint32_t Imm,642 const MCSubtargetInfo &STI,643 raw_ostream &O) {644 if (Imm == llvm::bit_cast<uint32_t>(0.0f))645 O << "0.0";646 else if (Imm == llvm::bit_cast<uint32_t>(1.0f))647 O << "1.0";648 else if (Imm == llvm::bit_cast<uint32_t>(-1.0f))649 O << "-1.0";650 else if (Imm == llvm::bit_cast<uint32_t>(0.5f))651 O << "0.5";652 else if (Imm == llvm::bit_cast<uint32_t>(-0.5f))653 O << "-0.5";654 else if (Imm == llvm::bit_cast<uint32_t>(2.0f))655 O << "2.0";656 else if (Imm == llvm::bit_cast<uint32_t>(-2.0f))657 O << "-2.0";658 else if (Imm == llvm::bit_cast<uint32_t>(4.0f))659 O << "4.0";660 else if (Imm == llvm::bit_cast<uint32_t>(-4.0f))661 O << "-4.0";662 else if (Imm == 0x3e22f983 &&663 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))664 O << "0.15915494";665 else666 return false;667 668 return true;669}670 671void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,672 const MCSubtargetInfo &STI,673 raw_ostream &O) {674 int32_t SImm = static_cast<int32_t>(Imm);675 if (isInlinableIntLiteral(SImm)) {676 O << SImm;677 return;678 }679 680 if (printImmediateFloat32(Imm, STI, O))681 return;682 683 O << formatHex(static_cast<uint64_t>(Imm));684}685 686void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,687 const MCSubtargetInfo &STI,688 raw_ostream &O, bool IsFP) {689 int64_t SImm = static_cast<int64_t>(Imm);690 if (SImm >= -16 && SImm <= 64) {691 O << SImm;692 return;693 }694 695 if (Imm == llvm::bit_cast<uint64_t>(0.0))696 O << "0.0";697 else if (Imm == llvm::bit_cast<uint64_t>(1.0))698 O << "1.0";699 else if (Imm == llvm::bit_cast<uint64_t>(-1.0))700 O << "-1.0";701 else if (Imm == llvm::bit_cast<uint64_t>(0.5))702 O << "0.5";703 else if (Imm == llvm::bit_cast<uint64_t>(-0.5))704 O << "-0.5";705 else if (Imm == llvm::bit_cast<uint64_t>(2.0))706 O << "2.0";707 else if (Imm == llvm::bit_cast<uint64_t>(-2.0))708 O << "-2.0";709 else if (Imm == llvm::bit_cast<uint64_t>(4.0))710 O << "4.0";711 else if (Imm == llvm::bit_cast<uint64_t>(-4.0))712 O << "-4.0";713 else if (Imm == 0x3fc45f306dc9c882 &&714 STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))715 O << "0.15915494309189532";716 else717 printLiteral64(Imm, O, IsFP);718}719 720void AMDGPUInstPrinter::printLiteral64(uint64_t Imm, raw_ostream &O,721 bool IsFP) {722 if (IsFP && Lo_32(Imm) == 0)723 O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));724 else725 O << formatHex(Imm);726}727 728void AMDGPUInstPrinter::printBLGP(const MCInst *MI, unsigned OpNo,729 const MCSubtargetInfo &STI,730 raw_ostream &O) {731 unsigned Imm = MI->getOperand(OpNo).getImm();732 if (!Imm)733 return;734 735 if (AMDGPU::isGFX940(STI)) {736 switch (MI->getOpcode()) {737 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:738 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:739 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:740 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:741 O << " neg:[" << (Imm & 1) << ',' << ((Imm >> 1) & 1) << ','742 << ((Imm >> 2) & 1) << ']';743 return;744 }745 }746 747 O << " blgp:" << Imm;748}749 750void AMDGPUInstPrinter::printDefaultVccOperand(bool FirstOperand,751 const MCSubtargetInfo &STI,752 raw_ostream &O) {753 if (!FirstOperand)754 O << ", ";755 printRegOperand(STI.hasFeature(AMDGPU::FeatureWavefrontSize32)756 ? AMDGPU::VCC_LO757 : AMDGPU::VCC,758 O, MRI);759 if (FirstOperand)760 O << ", ";761}762 763bool AMDGPUInstPrinter::needsImpliedVcc(const MCInstrDesc &Desc,764 unsigned OpNo) const {765 return OpNo == 0 && (Desc.TSFlags & SIInstrFlags::DPP) &&766 (Desc.TSFlags & SIInstrFlags::VOPC) &&767 !isVOPCAsmOnly(Desc.getOpcode()) &&768 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||769 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO));770}771 772// Print default vcc/vcc_lo operand of VOPC.773void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,774 const MCSubtargetInfo &STI,775 raw_ostream &O) {776 unsigned Opc = MI->getOpcode();777 const MCInstrDesc &Desc = MII.get(Opc);778 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);779 // 0, 1 and 2 are the first printed operands in different cases780 // If there are printed modifiers, printOperandAndFPInputMods or781 // printOperandAndIntInputMods will be called instead782 if ((OpNo == 0 ||783 (OpNo == 1 && (Desc.TSFlags & SIInstrFlags::DPP) && ModIdx != -1)) &&784 (Desc.TSFlags & SIInstrFlags::VOPC) && !isVOPCAsmOnly(Desc.getOpcode()) &&785 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) ||786 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO)))787 printDefaultVccOperand(true, STI, O);788 789 printRegularOperand(MI, OpNo, STI, O);790}791 792// Print operands after vcc or modifier handling.793void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,794 const MCSubtargetInfo &STI,795 raw_ostream &O) {796 const MCInstrDesc &Desc = MII.get(MI->getOpcode());797 798 if (OpNo >= MI->getNumOperands()) {799 O << "/*Missing OP" << OpNo << "*/";800 return;801 }802 803 const MCOperand &Op = MI->getOperand(OpNo);804 if (Op.isReg()) {805 printRegOperand(Op.getReg(), MI->getOpcode(), OpNo, O, MRI);806 807 // Check if operand register class contains register used.808 // Intention: print disassembler message when invalid code is decoded,809 // for example sgpr register used in VReg or VISrc(VReg or imm) operand.810 const MCOperandInfo &OpInfo = Desc.operands()[OpNo];811 if (OpInfo.RegClass != -1) {812 int16_t RCID = MII.getOpRegClassID(813 OpInfo, STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo));814 const MCRegisterClass &RC = MRI.getRegClass(RCID);815 auto Reg = mc2PseudoReg(Op.getReg());816 if (!RC.contains(Reg) && !isInlineValue(Reg)) {817 bool IsWaveSizeOp = OpInfo.isLookupRegClassByHwMode() &&818 (OpInfo.RegClass == AMDGPU::SReg_1 ||819 OpInfo.RegClass == AMDGPU::SReg_1_XEXEC);820 // Suppress this comment for a mismatched wavesize. Some users expect to821 // be able to assemble and disassemble modules with mixed wavesizes, but822 // we do not know the subtarget in different functions in MC.823 //824 // TODO: Should probably print it anyway, maybe a more specific version.825 if (!IsWaveSizeOp) {826 O << "/*Invalid register, operand has \'" << MRI.getRegClassName(&RC)827 << "\' register class*/";828 }829 }830 }831 } else if (Op.isImm()) {832 const uint8_t OpTy = Desc.operands()[OpNo].OperandType;833 switch (OpTy) {834 case AMDGPU::OPERAND_REG_IMM_INT32:835 case AMDGPU::OPERAND_REG_IMM_FP32:836 case AMDGPU::OPERAND_REG_INLINE_C_INT32:837 case AMDGPU::OPERAND_REG_INLINE_C_FP32:838 case AMDGPU::OPERAND_REG_INLINE_AC_INT32:839 case AMDGPU::OPERAND_REG_INLINE_AC_FP32:840 case AMDGPU::OPERAND_REG_IMM_V2INT32:841 case AMDGPU::OPERAND_REG_IMM_V2FP32:842 case MCOI::OPERAND_IMMEDIATE:843 case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:844 printImmediate32(Op.getImm(), STI, O);845 break;846 case AMDGPU::OPERAND_REG_IMM_INT64:847 case AMDGPU::OPERAND_REG_INLINE_C_INT64:848 printImmediate64(Op.getImm(), STI, O, false);849 break;850 case AMDGPU::OPERAND_REG_IMM_FP64:851 case AMDGPU::OPERAND_REG_INLINE_C_FP64:852 case AMDGPU::OPERAND_REG_INLINE_AC_FP64:853 printImmediate64(Op.getImm(), STI, O, true);854 break;855 case AMDGPU::OPERAND_REG_INLINE_C_INT16:856 case AMDGPU::OPERAND_REG_IMM_INT16:857 printImmediateInt16(Op.getImm(), STI, O);858 break;859 case AMDGPU::OPERAND_REG_INLINE_C_FP16:860 case AMDGPU::OPERAND_REG_IMM_FP16:861 printImmediateF16(Op.getImm(), STI, O);862 break;863 case AMDGPU::OPERAND_REG_INLINE_C_BF16:864 case AMDGPU::OPERAND_REG_IMM_BF16:865 printImmediateBF16(Op.getImm(), STI, O);866 break;867 case AMDGPU::OPERAND_REG_IMM_V2INT16:868 case AMDGPU::OPERAND_REG_IMM_V2BF16:869 case AMDGPU::OPERAND_REG_IMM_V2FP16:870 case AMDGPU::OPERAND_REG_IMM_NOINLINE_V2FP16:871 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:872 case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:873 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:874 printImmediateV216(Op.getImm(), OpTy, STI, O);875 break;876 case MCOI::OPERAND_UNKNOWN:877 case MCOI::OPERAND_PCREL:878 O << formatDec(Op.getImm());879 break;880 case MCOI::OPERAND_REGISTER:881 // Disassembler does not fail when operand should not allow immediate882 // operands but decodes them into 32bit immediate operand.883 printImmediate32(Op.getImm(), STI, O);884 O << "/*Invalid immediate*/";885 break;886 default:887 // We hit this for the immediate instruction bits that don't yet have a888 // custom printer.889 llvm_unreachable("unexpected immediate operand type");890 }891 } else if (Op.isExpr()) {892 const MCExpr *Exp = Op.getExpr();893 MAI.printExpr(O, *Exp);894 } else {895 O << "/*INV_OP*/";896 }897 898 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32.899 switch (MI->getOpcode()) {900 default: break;901 902 case AMDGPU::V_CNDMASK_B32_e32_gfx10:903 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10:904 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10:905 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:906 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10:907 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10:908 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10:909 case AMDGPU::V_CNDMASK_B32_dpp8_gfx10:910 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10:911 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10:912 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10:913 case AMDGPU::V_CNDMASK_B32_e32_gfx11:914 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx11:915 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx11:916 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx11:917 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx11:918 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx11:919 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx11:920 case AMDGPU::V_CNDMASK_B32_dpp8_gfx11:921 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx11:922 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx11:923 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx11:924 case AMDGPU::V_CNDMASK_B32_e32_gfx12:925 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx12:926 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx12:927 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx12:928 case AMDGPU::V_CNDMASK_B32_dpp_gfx12:929 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx12:930 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx12:931 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx12:932 case AMDGPU::V_CNDMASK_B32_dpp8_gfx12:933 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx12:934 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx12:935 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx12:936 937 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7:938 case AMDGPU::V_CNDMASK_B32_e32_vi:939 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(),940 AMDGPU::OpName::src1))941 printDefaultVccOperand(OpNo == 0, STI, O);942 break;943 }944 945 if (Desc.TSFlags & SIInstrFlags::MTBUF) {946 int SOffsetIdx =947 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::soffset);948 assert(SOffsetIdx != -1);949 if ((int)OpNo == SOffsetIdx)950 printSymbolicFormat(MI, STI, O);951 }952}953 954void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,955 unsigned OpNo,956 const MCSubtargetInfo &STI,957 raw_ostream &O) {958 const MCInstrDesc &Desc = MII.get(MI->getOpcode());959 if (needsImpliedVcc(Desc, OpNo))960 printDefaultVccOperand(true, STI, O);961 962 unsigned InputModifiers = MI->getOperand(OpNo).getImm();963 964 // Use 'neg(...)' instead of '-' to avoid ambiguity.965 // This is important for integer literals because966 // -1 is not the same value as neg(1).967 bool NegMnemo = false;968 969 if (InputModifiers & SISrcMods::NEG) {970 if (OpNo + 1 < MI->getNumOperands() &&971 (InputModifiers & SISrcMods::ABS) == 0) {972 const MCOperand &Op = MI->getOperand(OpNo + 1);973 NegMnemo = Op.isImm();974 }975 if (NegMnemo) {976 O << "neg(";977 } else {978 O << '-';979 }980 }981 982 if (InputModifiers & SISrcMods::ABS)983 O << '|';984 printRegularOperand(MI, OpNo + 1, STI, O);985 if (InputModifiers & SISrcMods::ABS)986 O << '|';987 988 if (NegMnemo) {989 O << ')';990 }991 992 // Print default vcc/vcc_lo operand of VOP2b.993 switch (MI->getOpcode()) {994 default:995 break;996 997 case AMDGPU::V_CNDMASK_B32_sdwa_gfx10:998 case AMDGPU::V_CNDMASK_B32_dpp_gfx10:999 case AMDGPU::V_CNDMASK_B32_dpp_gfx11:1000 if ((int)OpNo + 1 ==1001 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::src1))1002 printDefaultVccOperand(OpNo == 0, STI, O);1003 break;1004 }1005}1006 1007void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,1008 unsigned OpNo,1009 const MCSubtargetInfo &STI,1010 raw_ostream &O) {1011 const MCInstrDesc &Desc = MII.get(MI->getOpcode());1012 if (needsImpliedVcc(Desc, OpNo))1013 printDefaultVccOperand(true, STI, O);1014 1015 unsigned InputModifiers = MI->getOperand(OpNo).getImm();1016 if (InputModifiers & SISrcMods::SEXT)1017 O << "sext(";1018 printRegularOperand(MI, OpNo + 1, STI, O);1019 if (InputModifiers & SISrcMods::SEXT)1020 O << ')';1021 1022 // Print default vcc/vcc_lo operand of VOP2b.1023 switch (MI->getOpcode()) {1024 default: break;1025 1026 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10:1027 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10:1028 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10:1029 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(),1030 AMDGPU::OpName::src1))1031 printDefaultVccOperand(OpNo == 0, STI, O);1032 break;1033 }1034}1035 1036void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo,1037 const MCSubtargetInfo &STI,1038 raw_ostream &O) {1039 if (!AMDGPU::isGFX10Plus(STI))1040 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10");1041 1042 unsigned Imm = MI->getOperand(OpNo).getImm();1043 O << "dpp8:[" << formatDec(Imm & 0x7);1044 for (size_t i = 1; i < 8; ++i) {1045 O << ',' << formatDec((Imm >> (3 * i)) & 0x7);1046 }1047 O << ']';1048}1049 1050void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,1051 const MCSubtargetInfo &STI,1052 raw_ostream &O) {1053 using namespace AMDGPU::DPP;1054 1055 unsigned Imm = MI->getOperand(OpNo).getImm();1056 const MCInstrDesc &Desc = MII.get(MI->getOpcode());1057 1058 if (!AMDGPU::isLegalDPALU_DPPControl(STI, Imm) &&1059 AMDGPU::isDPALU_DPP(Desc, MII, STI)) {1060 O << " /* DP ALU dpp only supports "1061 << (isGFX12(STI) ? "row_share" : "row_newbcast") << " */";1062 return;1063 }1064 if (Imm <= DppCtrl::QUAD_PERM_LAST) {1065 O << "quad_perm:[";1066 O << formatDec(Imm & 0x3) << ',';1067 O << formatDec((Imm & 0xc) >> 2) << ',';1068 O << formatDec((Imm & 0x30) >> 4) << ',';1069 O << formatDec((Imm & 0xc0) >> 6) << ']';1070 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) &&1071 (Imm <= DppCtrl::ROW_SHL_LAST)) {1072 O << "row_shl:" << formatDec(Imm - DppCtrl::ROW_SHL0);1073 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) &&1074 (Imm <= DppCtrl::ROW_SHR_LAST)) {1075 O << "row_shr:" << formatDec(Imm - DppCtrl::ROW_SHR0);1076 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) &&1077 (Imm <= DppCtrl::ROW_ROR_LAST)) {1078 O << "row_ror:" << formatDec(Imm - DppCtrl::ROW_ROR0);1079 } else if (Imm == DppCtrl::WAVE_SHL1) {1080 if (AMDGPU::isGFX10Plus(STI)) {1081 O << "/* wave_shl is not supported starting from GFX10 */";1082 return;1083 }1084 O << "wave_shl:1";1085 } else if (Imm == DppCtrl::WAVE_ROL1) {1086 if (AMDGPU::isGFX10Plus(STI)) {1087 O << "/* wave_rol is not supported starting from GFX10 */";1088 return;1089 }1090 O << "wave_rol:1";1091 } else if (Imm == DppCtrl::WAVE_SHR1) {1092 if (AMDGPU::isGFX10Plus(STI)) {1093 O << "/* wave_shr is not supported starting from GFX10 */";1094 return;1095 }1096 O << "wave_shr:1";1097 } else if (Imm == DppCtrl::WAVE_ROR1) {1098 if (AMDGPU::isGFX10Plus(STI)) {1099 O << "/* wave_ror is not supported starting from GFX10 */";1100 return;1101 }1102 O << "wave_ror:1";1103 } else if (Imm == DppCtrl::ROW_MIRROR) {1104 O << "row_mirror";1105 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) {1106 O << "row_half_mirror";1107 } else if (Imm == DppCtrl::BCAST15) {1108 if (AMDGPU::isGFX10Plus(STI)) {1109 O << "/* row_bcast is not supported starting from GFX10 */";1110 return;1111 }1112 O << "row_bcast:15";1113 } else if (Imm == DppCtrl::BCAST31) {1114 if (AMDGPU::isGFX10Plus(STI)) {1115 O << "/* row_bcast is not supported starting from GFX10 */";1116 return;1117 }1118 O << "row_bcast:31";1119 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) &&1120 (Imm <= DppCtrl::ROW_SHARE_LAST)) {1121 if (AMDGPU::isGFX90A(STI)) {1122 O << "row_newbcast:";1123 } else if (AMDGPU::isGFX10Plus(STI)) {1124 O << "row_share:";1125 } else {1126 O << " /* row_newbcast/row_share is not supported on ASICs earlier "1127 "than GFX90A/GFX10 */";1128 return;1129 }1130 O << formatDec(Imm - DppCtrl::ROW_SHARE_FIRST);1131 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) &&1132 (Imm <= DppCtrl::ROW_XMASK_LAST)) {1133 if (!AMDGPU::isGFX10Plus(STI)) {1134 O << "/* row_xmask is not supported on ASICs earlier than GFX10 */";1135 return;1136 }1137 O << "row_xmask:" << formatDec(Imm - DppCtrl::ROW_XMASK_FIRST);1138 } else {1139 O << "/* Invalid dpp_ctrl value */";1140 }1141}1142 1143void AMDGPUInstPrinter::printDppBoundCtrl(const MCInst *MI, unsigned OpNo,1144 const MCSubtargetInfo &STI,1145 raw_ostream &O) {1146 unsigned Imm = MI->getOperand(OpNo).getImm();1147 if (Imm) {1148 O << " bound_ctrl:1";1149 }1150}1151 1152void AMDGPUInstPrinter::printDppFI(const MCInst *MI, unsigned OpNo,1153 const MCSubtargetInfo &STI, raw_ostream &O) {1154 using namespace llvm::AMDGPU::DPP;1155 unsigned Imm = MI->getOperand(OpNo).getImm();1156 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) {1157 O << " fi:1";1158 }1159}1160 1161void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,1162 raw_ostream &O) {1163 using namespace llvm::AMDGPU::SDWA;1164 1165 unsigned Imm = MI->getOperand(OpNo).getImm();1166 switch (Imm) {1167 case SdwaSel::BYTE_0: O << "BYTE_0"; break;1168 case SdwaSel::BYTE_1: O << "BYTE_1"; break;1169 case SdwaSel::BYTE_2: O << "BYTE_2"; break;1170 case SdwaSel::BYTE_3: O << "BYTE_3"; break;1171 case SdwaSel::WORD_0: O << "WORD_0"; break;1172 case SdwaSel::WORD_1: O << "WORD_1"; break;1173 case SdwaSel::DWORD: O << "DWORD"; break;1174 default: llvm_unreachable("Invalid SDWA data select operand");1175 }1176}1177 1178void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,1179 const MCSubtargetInfo &STI,1180 raw_ostream &O) {1181 O << "dst_sel:";1182 printSDWASel(MI, OpNo, O);1183}1184 1185void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,1186 const MCSubtargetInfo &STI,1187 raw_ostream &O) {1188 O << "src0_sel:";1189 printSDWASel(MI, OpNo, O);1190}1191 1192void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,1193 const MCSubtargetInfo &STI,1194 raw_ostream &O) {1195 O << "src1_sel:";1196 printSDWASel(MI, OpNo, O);1197}1198 1199void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,1200 const MCSubtargetInfo &STI,1201 raw_ostream &O) {1202 using namespace llvm::AMDGPU::SDWA;1203 1204 O << "dst_unused:";1205 unsigned Imm = MI->getOperand(OpNo).getImm();1206 switch (Imm) {1207 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break;1208 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break;1209 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break;1210 default: llvm_unreachable("Invalid SDWA dest_unused operand");1211 }1212}1213 1214void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,1215 const MCSubtargetInfo &STI, raw_ostream &O,1216 unsigned N) {1217 unsigned Opc = MI->getOpcode();1218 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en);1219 unsigned En = MI->getOperand(EnIdx).getImm();1220 1221 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr);1222 1223 // If compr is set, print as src0, src0, src1, src11224 if (MI->getOperand(ComprIdx).getImm())1225 OpNo = OpNo - N + N / 2;1226 1227 if (En & (1 << N))1228 printRegOperand(MI->getOperand(OpNo).getReg(), Opc, OpNo, O, MRI);1229 else1230 O << "off";1231}1232 1233void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo,1234 const MCSubtargetInfo &STI,1235 raw_ostream &O) {1236 printExpSrcN(MI, OpNo, STI, O, 0);1237}1238 1239void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo,1240 const MCSubtargetInfo &STI,1241 raw_ostream &O) {1242 printExpSrcN(MI, OpNo, STI, O, 1);1243}1244 1245void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo,1246 const MCSubtargetInfo &STI,1247 raw_ostream &O) {1248 printExpSrcN(MI, OpNo, STI, O, 2);1249}1250 1251void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,1252 const MCSubtargetInfo &STI,1253 raw_ostream &O) {1254 printExpSrcN(MI, OpNo, STI, O, 3);1255}1256 1257void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,1258 const MCSubtargetInfo &STI,1259 raw_ostream &O) {1260 using namespace llvm::AMDGPU::Exp;1261 1262 // This is really a 6 bit field.1263 unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);1264 1265 int Index;1266 StringRef TgtName;1267 if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {1268 O << ' ' << TgtName;1269 if (Index >= 0)1270 O << Index;1271 } else {1272 O << " invalid_target_" << Id;1273 }1274}1275 1276static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod,1277 bool IsPacked, bool HasDstSel) {1278 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1);1279 1280 for (int I = 0; I < NumOps; ++I) {1281 if (!!(Ops[I] & Mod) != DefaultValue)1282 return false;1283 }1284 1285 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0)1286 return false;1287 1288 return true;1289}1290 1291void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI,1292 StringRef Name,1293 unsigned Mod,1294 raw_ostream &O) {1295 unsigned Opc = MI->getOpcode();1296 int NumOps = 0;1297 int Ops[3];1298 1299 std::pair<AMDGPU::OpName, AMDGPU::OpName> MOps[] = {1300 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src0},1301 {AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src1},1302 {AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::src2}};1303 int DefaultValue = (Mod == SISrcMods::OP_SEL_1);1304 1305 for (auto [SrcMod, Src] : MOps) {1306 if (!AMDGPU::hasNamedOperand(Opc, Src))1307 break;1308 1309 int ModIdx = AMDGPU::getNamedOperandIdx(Opc, SrcMod);1310 Ops[NumOps++] =1311 (ModIdx != -1) ? MI->getOperand(ModIdx).getImm() : DefaultValue;1312 }1313 1314 // Some instructions, e.g. v_interp_p2_f16 in GFX9, have src0, src2, but no1315 // src1.1316 if (NumOps == 1 && AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src2) &&1317 !AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::src1)) {1318 Ops[NumOps++] = DefaultValue; // Set src1_modifiers to default.1319 int Mod2Idx =1320 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers);1321 assert(Mod2Idx != -1);1322 Ops[NumOps++] = MI->getOperand(Mod2Idx).getImm();1323 }1324 1325 const bool HasDst =1326 (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst) != -1) ||1327 (AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst) != -1);1328 1329 // Print three values of neg/opsel for wmma instructions (prints 0 when there1330 // is no src_modifier operand instead of not printing anything).1331 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsSWMMAC ||1332 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsWMMA) {1333 NumOps = 0;1334 int DefaultValue = Mod == SISrcMods::OP_SEL_1;1335 for (AMDGPU::OpName OpName :1336 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,1337 AMDGPU::OpName::src2_modifiers}) {1338 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName);1339 if (Idx != -1)1340 Ops[NumOps++] = MI->getOperand(Idx).getImm();1341 else1342 Ops[NumOps++] = DefaultValue;1343 }1344 }1345 1346 const bool HasDstSel =1347 HasDst && NumOps > 0 && Mod == SISrcMods::OP_SEL_0 &&1348 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL;1349 1350 const bool IsPacked =1351 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked;1352 1353 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel))1354 return;1355 1356 O << Name;1357 ListSeparator Sep(",");1358 for (int I = 0; I < NumOps; ++I)1359 O << Sep << !!(Ops[I] & Mod);1360 1361 if (HasDstSel) {1362 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL);1363 }1364 1365 O << ']';1366}1367 1368void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned,1369 const MCSubtargetInfo &STI,1370 raw_ostream &O) {1371 unsigned Opc = MI->getOpcode();1372 if (isCvt_F32_Fp8_Bf8_e64(Opc)) {1373 auto SrcMod =1374 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);1375 unsigned Mod = MI->getOperand(SrcMod).getImm();1376 unsigned Index0 = !!(Mod & SISrcMods::OP_SEL_0);1377 unsigned Index1 = !!(Mod & SISrcMods::OP_SEL_1);1378 if (Index0 || Index1)1379 O << " op_sel:[" << Index0 << ',' << Index1 << ']';1380 return;1381 }1382 if (isPermlane16(Opc)) {1383 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);1384 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers);1385 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0);1386 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0);1387 if (FI || BC)1388 O << " op_sel:[" << FI << ',' << BC << ']';1389 return;1390 }1391 1392 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O);1393}1394 1395void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo,1396 const MCSubtargetInfo &STI,1397 raw_ostream &O) {1398 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O);1399}1400 1401void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo,1402 const MCSubtargetInfo &STI,1403 raw_ostream &O) {1404 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O);1405}1406 1407void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo,1408 const MCSubtargetInfo &STI,1409 raw_ostream &O) {1410 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O);1411}1412 1413void AMDGPUInstPrinter::printIndexKey8bit(const MCInst *MI, unsigned OpNo,1414 const MCSubtargetInfo &STI,1415 raw_ostream &O) {1416 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;1417 if (Imm == 0)1418 return;1419 1420 O << " index_key:" << Imm;1421}1422 1423void AMDGPUInstPrinter::printIndexKey16bit(const MCInst *MI, unsigned OpNo,1424 const MCSubtargetInfo &STI,1425 raw_ostream &O) {1426 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;1427 if (Imm == 0)1428 return;1429 1430 O << " index_key:" << Imm;1431}1432 1433void AMDGPUInstPrinter::printIndexKey32bit(const MCInst *MI, unsigned OpNo,1434 const MCSubtargetInfo &STI,1435 raw_ostream &O) {1436 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;1437 if (Imm == 0)1438 return;1439 1440 O << " index_key:" << Imm;1441}1442 1443void AMDGPUInstPrinter::printMatrixFMT(const MCInst *MI, unsigned OpNo,1444 const MCSubtargetInfo &STI,1445 raw_ostream &O, char AorB) {1446 auto Imm = MI->getOperand(OpNo).getImm() & 0x7;1447 if (Imm == 0)1448 return;1449 1450 O << " matrix_" << AorB << "_fmt:";1451 switch (Imm) {1452 default:1453 O << Imm;1454 break;1455 case WMMA::MatrixFMT::MATRIX_FMT_FP8:1456 O << "MATRIX_FMT_FP8";1457 break;1458 case WMMA::MatrixFMT::MATRIX_FMT_BF8:1459 O << "MATRIX_FMT_BF8";1460 break;1461 case WMMA::MatrixFMT::MATRIX_FMT_FP6:1462 O << "MATRIX_FMT_FP6";1463 break;1464 case WMMA::MatrixFMT::MATRIX_FMT_BF6:1465 O << "MATRIX_FMT_BF6";1466 break;1467 case WMMA::MatrixFMT::MATRIX_FMT_FP4:1468 O << "MATRIX_FMT_FP4";1469 break;1470 }1471}1472 1473void AMDGPUInstPrinter::printMatrixAFMT(const MCInst *MI, unsigned OpNo,1474 const MCSubtargetInfo &STI,1475 raw_ostream &O) {1476 printMatrixFMT(MI, OpNo, STI, O, 'a');1477}1478 1479void AMDGPUInstPrinter::printMatrixBFMT(const MCInst *MI, unsigned OpNo,1480 const MCSubtargetInfo &STI,1481 raw_ostream &O) {1482 printMatrixFMT(MI, OpNo, STI, O, 'b');1483}1484 1485void AMDGPUInstPrinter::printMatrixScale(const MCInst *MI, unsigned OpNo,1486 const MCSubtargetInfo &STI,1487 raw_ostream &O, char AorB) {1488 auto Imm = MI->getOperand(OpNo).getImm() & 1;1489 if (Imm == 0)1490 return;1491 1492 O << " matrix_" << AorB << "_scale:";1493 switch (Imm) {1494 default:1495 O << Imm;1496 break;1497 case WMMA::MatrixScale::MATRIX_SCALE_ROW0:1498 O << "MATRIX_SCALE_ROW0";1499 break;1500 case WMMA::MatrixScale::MATRIX_SCALE_ROW1:1501 O << "MATRIX_SCALE_ROW1";1502 break;1503 }1504}1505 1506void AMDGPUInstPrinter::printMatrixAScale(const MCInst *MI, unsigned OpNo,1507 const MCSubtargetInfo &STI,1508 raw_ostream &O) {1509 printMatrixScale(MI, OpNo, STI, O, 'a');1510}1511 1512void AMDGPUInstPrinter::printMatrixBScale(const MCInst *MI, unsigned OpNo,1513 const MCSubtargetInfo &STI,1514 raw_ostream &O) {1515 printMatrixScale(MI, OpNo, STI, O, 'b');1516}1517 1518void AMDGPUInstPrinter::printMatrixScaleFmt(const MCInst *MI, unsigned OpNo,1519 const MCSubtargetInfo &STI,1520 raw_ostream &O, char AorB) {1521 auto Imm = MI->getOperand(OpNo).getImm() & 3;1522 if (Imm == 0)1523 return;1524 1525 O << " matrix_" << AorB << "_scale_fmt:";1526 switch (Imm) {1527 default:1528 O << Imm;1529 break;1530 case WMMA::MatrixScaleFmt::MATRIX_SCALE_FMT_E8:1531 O << "MATRIX_SCALE_FMT_E8";1532 break;1533 case WMMA::MatrixScaleFmt::MATRIX_SCALE_FMT_E5M3:1534 O << "MATRIX_SCALE_FMT_E5M3";1535 break;1536 case WMMA::MatrixScaleFmt::MATRIX_SCALE_FMT_E4M3:1537 O << "MATRIX_SCALE_FMT_E4M3";1538 break;1539 }1540}1541 1542void AMDGPUInstPrinter::printMatrixAScaleFmt(const MCInst *MI, unsigned OpNo,1543 const MCSubtargetInfo &STI,1544 raw_ostream &O) {1545 printMatrixScaleFmt(MI, OpNo, STI, O, 'a');1546}1547 1548void AMDGPUInstPrinter::printMatrixBScaleFmt(const MCInst *MI, unsigned OpNo,1549 const MCSubtargetInfo &STI,1550 raw_ostream &O) {1551 printMatrixScaleFmt(MI, OpNo, STI, O, 'b');1552}1553 1554void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,1555 const MCSubtargetInfo &STI,1556 raw_ostream &O) {1557 unsigned Imm = MI->getOperand(OpNum).getImm();1558 switch (Imm) {1559 case 0:1560 O << "p10";1561 break;1562 case 1:1563 O << "p20";1564 break;1565 case 2:1566 O << "p0";1567 break;1568 default:1569 O << "invalid_param_" << Imm;1570 }1571}1572 1573void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum,1574 const MCSubtargetInfo &STI,1575 raw_ostream &O) {1576 unsigned Attr = MI->getOperand(OpNum).getImm();1577 O << "attr" << Attr;1578}1579 1580void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,1581 const MCSubtargetInfo &STI,1582 raw_ostream &O) {1583 unsigned Chan = MI->getOperand(OpNum).getImm();1584 O << '.' << "xyzw"[Chan & 0x3];1585}1586 1587void AMDGPUInstPrinter::printGPRIdxMode(const MCInst *MI, unsigned OpNo,1588 const MCSubtargetInfo &STI,1589 raw_ostream &O) {1590 using namespace llvm::AMDGPU::VGPRIndexMode;1591 unsigned Val = MI->getOperand(OpNo).getImm();1592 1593 if ((Val & ~ENABLE_MASK) != 0) {1594 O << formatHex(static_cast<uint64_t>(Val));1595 } else {1596 O << "gpr_idx(";1597 ListSeparator Sep(",");1598 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {1599 if (Val & (1 << ModeId))1600 O << Sep << IdSymbolic[ModeId];1601 }1602 O << ')';1603 }1604}1605 1606void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,1607 const MCSubtargetInfo &STI,1608 raw_ostream &O) {1609 printRegularOperand(MI, OpNo, STI, O);1610 O << ", ";1611 printRegularOperand(MI, OpNo + 1, STI, O);1612}1613 1614void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,1615 raw_ostream &O, StringRef Asm,1616 StringRef Default) {1617 const MCOperand &Op = MI->getOperand(OpNo);1618 assert(Op.isImm());1619 if (Op.getImm() == 1) {1620 O << Asm;1621 } else {1622 O << Default;1623 }1624}1625 1626void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,1627 raw_ostream &O, char Asm) {1628 const MCOperand &Op = MI->getOperand(OpNo);1629 assert(Op.isImm());1630 if (Op.getImm() == 1)1631 O << Asm;1632}1633 1634void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,1635 const MCSubtargetInfo &STI,1636 raw_ostream &O) {1637 int Imm = MI->getOperand(OpNo).getImm();1638 if (Imm == SIOutMods::MUL2)1639 O << " mul:2";1640 else if (Imm == SIOutMods::MUL4)1641 O << " mul:4";1642 else if (Imm == SIOutMods::DIV2)1643 O << " div:2";1644}1645 1646void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,1647 const MCSubtargetInfo &STI,1648 raw_ostream &O) {1649 using namespace llvm::AMDGPU::SendMsg;1650 1651 const unsigned Imm16 = MI->getOperand(OpNo).getImm();1652 1653 uint16_t MsgId;1654 uint16_t OpId;1655 uint16_t StreamId;1656 decodeMsg(Imm16, MsgId, OpId, StreamId, STI);1657 1658 StringRef MsgName = getMsgName(MsgId, STI);1659 1660 if (!MsgName.empty() && isValidMsgOp(MsgId, OpId, STI) &&1661 isValidMsgStream(MsgId, OpId, StreamId, STI)) {1662 O << "sendmsg(" << MsgName;1663 if (msgRequiresOp(MsgId, STI)) {1664 O << ", " << getMsgOpName(MsgId, OpId, STI);1665 if (msgSupportsStream(MsgId, OpId, STI)) {1666 O << ", " << StreamId;1667 }1668 }1669 O << ')';1670 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) {1671 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')';1672 } else {1673 O << Imm16; // Unknown imm16 code.1674 }1675}1676 1677static void printSwizzleBitmask(const uint16_t AndMask,1678 const uint16_t OrMask,1679 const uint16_t XorMask,1680 raw_ostream &O) {1681 using namespace llvm::AMDGPU::Swizzle;1682 1683 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask;1684 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask;1685 1686 O << "\"";1687 1688 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) {1689 uint16_t p0 = Probe0 & Mask;1690 uint16_t p1 = Probe1 & Mask;1691 1692 if (p0 == p1) {1693 if (p0 == 0) {1694 O << "0";1695 } else {1696 O << "1";1697 }1698 } else {1699 if (p0 == 0) {1700 O << "p";1701 } else {1702 O << "i";1703 }1704 }1705 }1706 1707 O << "\"";1708}1709 1710void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo,1711 const MCSubtargetInfo &STI,1712 raw_ostream &O) {1713 using namespace llvm::AMDGPU::Swizzle;1714 1715 uint16_t Imm = MI->getOperand(OpNo).getImm();1716 if (Imm == 0) {1717 return;1718 }1719 1720 O << " offset:";1721 1722 // Rotate and FFT modes1723 if (Imm >= ROTATE_MODE_LO && AMDGPU::isGFX9Plus(STI)) {1724 if (Imm >= FFT_MODE_LO) {1725 O << "swizzle(" << IdSymbolic[ID_FFT] << ',' << (Imm & FFT_SWIZZLE_MASK)1726 << ')';1727 } else if (Imm >= ROTATE_MODE_LO) {1728 O << "swizzle(" << IdSymbolic[ID_ROTATE] << ','1729 << ((Imm >> ROTATE_DIR_SHIFT) & ROTATE_DIR_MASK) << ','1730 << ((Imm >> ROTATE_SIZE_SHIFT) & ROTATE_SIZE_MASK) << ')';1731 }1732 return;1733 }1734 1735 // Basic mode1736 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) {1737 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM];1738 for (unsigned I = 0; I < LANE_NUM; ++I) {1739 O << ",";1740 O << formatDec(Imm & LANE_MASK);1741 Imm >>= LANE_SHIFT;1742 }1743 O << ")";1744 1745 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) {1746 1747 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK;1748 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK;1749 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK;1750 1751 if (AndMask == BITMASK_MAX && OrMask == 0 && llvm::popcount(XorMask) == 1) {1752 1753 O << "swizzle(" << IdSymbolic[ID_SWAP];1754 O << ",";1755 O << formatDec(XorMask);1756 O << ")";1757 1758 } else if (AndMask == BITMASK_MAX && OrMask == 0 && XorMask > 0 &&1759 isPowerOf2_64(XorMask + 1)) {1760 1761 O << "swizzle(" << IdSymbolic[ID_REVERSE];1762 O << ",";1763 O << formatDec(XorMask + 1);1764 O << ")";1765 1766 } else {1767 1768 uint16_t GroupSize = BITMASK_MAX - AndMask + 1;1769 if (GroupSize > 1 &&1770 isPowerOf2_64(GroupSize) &&1771 OrMask < GroupSize &&1772 XorMask == 0) {1773 1774 O << "swizzle(" << IdSymbolic[ID_BROADCAST];1775 O << ",";1776 O << formatDec(GroupSize);1777 O << ",";1778 O << formatDec(OrMask);1779 O << ")";1780 1781 } else {1782 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM];1783 O << ",";1784 printSwizzleBitmask(AndMask, OrMask, XorMask, O);1785 O << ")";1786 }1787 }1788 } else {1789 printU16ImmDecOperand(MI, OpNo, O);1790 }1791}1792 1793void AMDGPUInstPrinter::printSWaitCnt(const MCInst *MI, unsigned OpNo,1794 const MCSubtargetInfo &STI,1795 raw_ostream &O) {1796 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU());1797 1798 unsigned SImm16 = MI->getOperand(OpNo).getImm();1799 unsigned Vmcnt, Expcnt, Lgkmcnt;1800 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt);1801 1802 bool IsDefaultVmcnt = Vmcnt == getVmcntBitMask(ISA);1803 bool IsDefaultExpcnt = Expcnt == getExpcntBitMask(ISA);1804 bool IsDefaultLgkmcnt = Lgkmcnt == getLgkmcntBitMask(ISA);1805 bool PrintAll = IsDefaultVmcnt && IsDefaultExpcnt && IsDefaultLgkmcnt;1806 1807 ListSeparator Sep(" ");1808 1809 if (!IsDefaultVmcnt || PrintAll)1810 O << Sep << "vmcnt(" << Vmcnt << ')';1811 1812 if (!IsDefaultExpcnt || PrintAll)1813 O << Sep << "expcnt(" << Expcnt << ')';1814 1815 if (!IsDefaultLgkmcnt || PrintAll)1816 O << Sep << "lgkmcnt(" << Lgkmcnt << ')';1817}1818 1819void AMDGPUInstPrinter::printDepCtr(const MCInst *MI, unsigned OpNo,1820 const MCSubtargetInfo &STI,1821 raw_ostream &O) {1822 using namespace llvm::AMDGPU::DepCtr;1823 1824 uint64_t Imm16 = MI->getOperand(OpNo).getImm() & 0xffff;1825 1826 bool HasNonDefaultVal = false;1827 if (isSymbolicDepCtrEncoding(Imm16, HasNonDefaultVal, STI)) {1828 int Id = 0;1829 StringRef Name;1830 unsigned Val;1831 bool IsDefault;1832 ListSeparator Sep(" ");1833 while (decodeDepCtr(Imm16, Id, Name, Val, IsDefault, STI)) {1834 if (!IsDefault || !HasNonDefaultVal)1835 O << Sep << Name << '(' << Val << ')';1836 }1837 } else {1838 O << formatHex(Imm16);1839 }1840}1841 1842void AMDGPUInstPrinter::printSDelayALU(const MCInst *MI, unsigned OpNo,1843 const MCSubtargetInfo &STI,1844 raw_ostream &O) {1845 const char *BadInstId = "/* invalid instid value */";1846 static const std::array<const char *, 12> InstIds = {1847 "NO_DEP", "VALU_DEP_1", "VALU_DEP_2",1848 "VALU_DEP_3", "VALU_DEP_4", "TRANS32_DEP_1",1849 "TRANS32_DEP_2", "TRANS32_DEP_3", "FMA_ACCUM_CYCLE_1",1850 "SALU_CYCLE_1", "SALU_CYCLE_2", "SALU_CYCLE_3"};1851 1852 const char *BadInstSkip = "/* invalid instskip value */";1853 static const std::array<const char *, 6> InstSkips = {1854 "SAME", "NEXT", "SKIP_1", "SKIP_2", "SKIP_3", "SKIP_4"};1855 1856 unsigned SImm16 = MI->getOperand(OpNo).getImm();1857 const char *Prefix = "";1858 1859 unsigned Value = SImm16 & 0xF;1860 if (Value) {1861 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;1862 O << Prefix << "instid0(" << Name << ')';1863 Prefix = " | ";1864 }1865 1866 Value = (SImm16 >> 4) & 7;1867 if (Value) {1868 const char *Name =1869 Value < InstSkips.size() ? InstSkips[Value] : BadInstSkip;1870 O << Prefix << "instskip(" << Name << ')';1871 Prefix = " | ";1872 }1873 1874 Value = (SImm16 >> 7) & 0xF;1875 if (Value) {1876 const char *Name = Value < InstIds.size() ? InstIds[Value] : BadInstId;1877 O << Prefix << "instid1(" << Name << ')';1878 Prefix = " | ";1879 }1880 1881 if (!*Prefix)1882 O << "0";1883}1884 1885void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,1886 const MCSubtargetInfo &STI, raw_ostream &O) {1887 using namespace llvm::AMDGPU::Hwreg;1888 unsigned Val = MI->getOperand(OpNo).getImm();1889 auto [Id, Offset, Width] = HwregEncoding::decode(Val);1890 StringRef HwRegName = getHwreg(Id, STI);1891 1892 O << "hwreg(";1893 if (!HwRegName.empty()) {1894 O << HwRegName;1895 } else {1896 O << Id;1897 }1898 if (Width != HwregSize::Default || Offset != HwregOffset::Default)1899 O << ", " << Offset << ", " << Width;1900 O << ')';1901}1902 1903void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo,1904 const MCSubtargetInfo &STI,1905 raw_ostream &O) {1906 uint16_t Imm = MI->getOperand(OpNo).getImm();1907 if (Imm == 0) {1908 return;1909 }1910 1911 O << ' ' << formatDec(Imm);1912}1913 1914void AMDGPUInstPrinter::printNamedInt(const MCInst *MI, unsigned OpNo,1915 const MCSubtargetInfo &STI,1916 raw_ostream &O, StringRef Prefix,1917 bool PrintInHex, bool AlwaysPrint) {1918 int64_t V = MI->getOperand(OpNo).getImm();1919 if (AlwaysPrint || V != 0)1920 O << ' ' << Prefix << ':' << (PrintInHex ? formatHex(V) : formatDec(V));1921}1922 1923void AMDGPUInstPrinter::printBitOp3(const MCInst *MI, unsigned OpNo,1924 const MCSubtargetInfo &STI,1925 raw_ostream &O) {1926 uint8_t Imm = MI->getOperand(OpNo).getImm();1927 if (!Imm)1928 return;1929 1930 O << " bitop3:";1931 if (Imm <= 10)1932 O << formatDec(Imm);1933 else1934 O << formatHex(static_cast<uint64_t>(Imm));1935}1936 1937void AMDGPUInstPrinter::printScaleSel(const MCInst *MI, unsigned OpNo,1938 const MCSubtargetInfo &STI,1939 raw_ostream &O) {1940 uint8_t Imm = MI->getOperand(OpNo).getImm();1941 if (!Imm)1942 return;1943 1944 O << " scale_sel:" << formatDec(Imm);1945}1946 1947#include "AMDGPUGenAsmWriter.inc"1948