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