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