brintos

brintos / llvm-project-archived public Read only

0
0
Text · 63.1 KiB · b63d71d Raw
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