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/ErrorHandling.h" 22 #include "llvm/Support/MathExtras.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include <cassert> 25 26 using namespace llvm; 27 using namespace llvm::AMDGPU; 28 29 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 30 StringRef Annot, const MCSubtargetInfo &STI) { 31 OS.flush(); 32 printInstruction(MI, STI, OS); 33 printAnnotation(OS, Annot); 34 } 35 36 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo, 37 const MCSubtargetInfo &STI, 38 raw_ostream &O) { 39 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf); 40 } 41 42 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo, 43 raw_ostream &O) { 44 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff); 45 } 46 47 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 48 const MCSubtargetInfo &STI, 49 raw_ostream &O) { 50 // It's possible to end up with a 32-bit literal used with a 16-bit operand 51 // with ignored high bits. Print as 32-bit anyway in that case. 52 int64_t Imm = MI->getOperand(OpNo).getImm(); 53 if (isInt<16>(Imm) || isUInt<16>(Imm)) 54 O << formatHex(static_cast<uint64_t>(Imm & 0xffff)); 55 else 56 printU32ImmOperand(MI, OpNo, STI, O); 57 } 58 59 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo, 60 raw_ostream &O) { 61 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf); 62 } 63 64 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo, 65 raw_ostream &O) { 66 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff); 67 } 68 69 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, 70 raw_ostream &O) { 71 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff); 72 } 73 74 void AMDGPUInstPrinter::printS13ImmDecOperand(const MCInst *MI, unsigned OpNo, 75 const MCSubtargetInfo &STI, 76 raw_ostream &O) { 77 // GFX10: Address offset is 12-bit signed byte offset. 78 if (AMDGPU::isGFX10(STI)) { 79 O << formatDec(SignExtend32<12>(MI->getOperand(OpNo).getImm())); 80 } else { 81 O << formatDec(SignExtend32<13>(MI->getOperand(OpNo).getImm())); 82 } 83 } 84 85 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo, 86 const MCSubtargetInfo &STI, 87 raw_ostream &O) { 88 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff); 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::printOffen(const MCInst *MI, unsigned OpNo, 99 raw_ostream &O) { 100 printNamedBit(MI, OpNo, O, "offen"); 101 } 102 103 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo, 104 raw_ostream &O) { 105 printNamedBit(MI, OpNo, O, "idxen"); 106 } 107 108 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo, 109 raw_ostream &O) { 110 printNamedBit(MI, OpNo, O, "addr64"); 111 } 112 113 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo, 114 raw_ostream &O) { 115 if (MI->getOperand(OpNo).getImm()) { 116 O << " offset:"; 117 printU16ImmDecOperand(MI, OpNo, O); 118 } 119 } 120 121 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo, 122 const MCSubtargetInfo &STI, 123 raw_ostream &O) { 124 uint16_t Imm = MI->getOperand(OpNo).getImm(); 125 if (Imm != 0) { 126 O << ((OpNo == 0)? "offset:" : " offset:"); 127 printU16ImmDecOperand(MI, OpNo, O); 128 } 129 } 130 131 void AMDGPUInstPrinter::printOffsetS13(const MCInst *MI, unsigned OpNo, 132 const MCSubtargetInfo &STI, 133 raw_ostream &O) { 134 uint16_t Imm = MI->getOperand(OpNo).getImm(); 135 if (Imm != 0) { 136 O << ((OpNo == 0)? "offset:" : " offset:"); 137 printS13ImmDecOperand(MI, OpNo, STI, O); 138 } 139 } 140 141 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo, 142 const MCSubtargetInfo &STI, 143 raw_ostream &O) { 144 if (MI->getOperand(OpNo).getImm()) { 145 O << " offset0:"; 146 printU8ImmDecOperand(MI, OpNo, O); 147 } 148 } 149 150 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo, 151 const MCSubtargetInfo &STI, 152 raw_ostream &O) { 153 if (MI->getOperand(OpNo).getImm()) { 154 O << " offset1:"; 155 printU8ImmDecOperand(MI, OpNo, O); 156 } 157 } 158 159 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo, 160 const MCSubtargetInfo &STI, 161 raw_ostream &O) { 162 printU32ImmOperand(MI, OpNo, STI, O); 163 } 164 165 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo, 166 const MCSubtargetInfo &STI, 167 raw_ostream &O) { 168 printU32ImmOperand(MI, OpNo, STI, O); 169 } 170 171 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo, 172 const MCSubtargetInfo &STI, 173 raw_ostream &O) { 174 printU32ImmOperand(MI, OpNo, STI, O); 175 } 176 177 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo, 178 const MCSubtargetInfo &STI, raw_ostream &O) { 179 printNamedBit(MI, OpNo, O, "gds"); 180 } 181 182 void AMDGPUInstPrinter::printDLC(const MCInst *MI, unsigned OpNo, 183 const MCSubtargetInfo &STI, raw_ostream &O) { 184 if (AMDGPU::isGFX10(STI)) 185 printNamedBit(MI, OpNo, O, "dlc"); 186 } 187 188 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo, 189 const MCSubtargetInfo &STI, raw_ostream &O) { 190 printNamedBit(MI, OpNo, O, "glc"); 191 } 192 193 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo, 194 const MCSubtargetInfo &STI, raw_ostream &O) { 195 printNamedBit(MI, OpNo, O, "slc"); 196 } 197 198 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo, 199 const MCSubtargetInfo &STI, raw_ostream &O) { 200 printNamedBit(MI, OpNo, O, "tfe"); 201 } 202 203 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo, 204 const MCSubtargetInfo &STI, raw_ostream &O) { 205 if (MI->getOperand(OpNo).getImm()) { 206 O << " dmask:"; 207 printU16ImmOperand(MI, OpNo, STI, O); 208 } 209 } 210 211 void AMDGPUInstPrinter::printDim(const MCInst *MI, unsigned OpNo, 212 const MCSubtargetInfo &STI, raw_ostream &O) { 213 unsigned Dim = MI->getOperand(OpNo).getImm(); 214 O << " dim:SQ_RSRC_IMG_"; 215 216 const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfoByEncoding(Dim); 217 if (DimInfo) 218 O << DimInfo->AsmSuffix; 219 else 220 O << Dim; 221 } 222 223 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo, 224 const MCSubtargetInfo &STI, raw_ostream &O) { 225 printNamedBit(MI, OpNo, O, "unorm"); 226 } 227 228 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo, 229 const MCSubtargetInfo &STI, raw_ostream &O) { 230 printNamedBit(MI, OpNo, O, "da"); 231 } 232 233 void AMDGPUInstPrinter::printR128A16(const MCInst *MI, unsigned OpNo, 234 const MCSubtargetInfo &STI, raw_ostream &O) { 235 if (STI.hasFeature(AMDGPU::FeatureR128A16)) 236 printNamedBit(MI, OpNo, O, "a16"); 237 else 238 printNamedBit(MI, OpNo, O, "r128"); 239 } 240 241 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo, 242 const MCSubtargetInfo &STI, raw_ostream &O) { 243 printNamedBit(MI, OpNo, O, "lwe"); 244 } 245 246 void AMDGPUInstPrinter::printD16(const MCInst *MI, unsigned OpNo, 247 const MCSubtargetInfo &STI, raw_ostream &O) { 248 printNamedBit(MI, OpNo, O, "d16"); 249 } 250 251 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo, 252 const MCSubtargetInfo &STI, 253 raw_ostream &O) { 254 if (MI->getOperand(OpNo).getImm()) 255 O << " compr"; 256 } 257 258 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo, 259 const MCSubtargetInfo &STI, 260 raw_ostream &O) { 261 if (MI->getOperand(OpNo).getImm()) 262 O << " vm"; 263 } 264 265 void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo, 266 const MCSubtargetInfo &STI, 267 raw_ostream &O) { 268 if (unsigned Val = MI->getOperand(OpNo).getImm()) { 269 if (AMDGPU::isGFX10(STI)) 270 O << " format:" << Val; 271 else { 272 O << " dfmt:" << (Val & 15); 273 O << ", nfmt:" << (Val >> 4); 274 } 275 } 276 } 277 278 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O, 279 const MCRegisterInfo &MRI) { 280 switch (RegNo) { 281 case AMDGPU::VCC: 282 O << "vcc"; 283 return; 284 case AMDGPU::SRC_VCCZ: 285 O << "src_vccz"; 286 return; 287 case AMDGPU::SRC_EXECZ: 288 O << "src_execz"; 289 return; 290 case AMDGPU::SRC_SCC: 291 O << "src_scc"; 292 return; 293 case AMDGPU::EXEC: 294 O << "exec"; 295 return; 296 case AMDGPU::M0: 297 O << "m0"; 298 return; 299 case AMDGPU::SGPR_NULL: 300 O << "null"; 301 return; 302 case AMDGPU::FLAT_SCR: 303 O << "flat_scratch"; 304 return; 305 case AMDGPU::XNACK_MASK: 306 O << "xnack_mask"; 307 return; 308 case AMDGPU::SRC_SHARED_BASE: 309 O << "src_shared_base"; 310 return; 311 case AMDGPU::SRC_SHARED_LIMIT: 312 O << "src_shared_limit"; 313 return; 314 case AMDGPU::SRC_PRIVATE_BASE: 315 O << "src_private_base"; 316 return; 317 case AMDGPU::SRC_PRIVATE_LIMIT: 318 O << "src_private_limit"; 319 return; 320 case AMDGPU::SRC_POPS_EXITING_WAVE_ID: 321 O << "src_pops_exiting_wave_id"; 322 return; 323 case AMDGPU::LDS_DIRECT: 324 O << "src_lds_direct"; 325 return; 326 case AMDGPU::VCC_LO: 327 O << "vcc_lo"; 328 return; 329 case AMDGPU::VCC_HI: 330 O << "vcc_hi"; 331 return; 332 case AMDGPU::TBA_LO: 333 O << "tba_lo"; 334 return; 335 case AMDGPU::TBA_HI: 336 O << "tba_hi"; 337 return; 338 case AMDGPU::TMA_LO: 339 O << "tma_lo"; 340 return; 341 case AMDGPU::TMA_HI: 342 O << "tma_hi"; 343 return; 344 case AMDGPU::EXEC_LO: 345 O << "exec_lo"; 346 return; 347 case AMDGPU::EXEC_HI: 348 O << "exec_hi"; 349 return; 350 case AMDGPU::FLAT_SCR_LO: 351 O << "flat_scratch_lo"; 352 return; 353 case AMDGPU::FLAT_SCR_HI: 354 O << "flat_scratch_hi"; 355 return; 356 case AMDGPU::XNACK_MASK_LO: 357 O << "xnack_mask_lo"; 358 return; 359 case AMDGPU::XNACK_MASK_HI: 360 O << "xnack_mask_hi"; 361 return; 362 case AMDGPU::FP_REG: 363 case AMDGPU::SP_REG: 364 case AMDGPU::SCRATCH_WAVE_OFFSET_REG: 365 case AMDGPU::PRIVATE_RSRC_REG: 366 llvm_unreachable("pseudo-register should not ever be emitted"); 367 case AMDGPU::SCC: 368 llvm_unreachable("pseudo scc should not ever be emitted"); 369 default: 370 break; 371 } 372 373 // The low 8 bits of the encoding value is the register index, for both VGPRs 374 // and SGPRs. 375 unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1); 376 377 unsigned NumRegs; 378 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) { 379 O << 'v'; 380 NumRegs = 1; 381 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) { 382 O << 's'; 383 NumRegs = 1; 384 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) { 385 O <<'v'; 386 NumRegs = 2; 387 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) { 388 O << 's'; 389 NumRegs = 2; 390 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) { 391 O << 'v'; 392 NumRegs = 4; 393 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) { 394 O << 's'; 395 NumRegs = 4; 396 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) { 397 O << 'v'; 398 NumRegs = 3; 399 } else if (MRI.getRegClass(AMDGPU::SReg_96RegClassID).contains(RegNo)) { 400 O << 's'; 401 NumRegs = 3; 402 } else if (MRI.getRegClass(AMDGPU::VReg_160RegClassID).contains(RegNo)) { 403 O << 'v'; 404 NumRegs = 5; 405 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) { 406 O << 'v'; 407 NumRegs = 8; 408 } else if (MRI.getRegClass(AMDGPU::SGPR_256RegClassID).contains(RegNo)) { 409 O << 's'; 410 NumRegs = 8; 411 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) { 412 O << 'v'; 413 NumRegs = 16; 414 } else if (MRI.getRegClass(AMDGPU::SGPR_512RegClassID).contains(RegNo)) { 415 O << 's'; 416 NumRegs = 16; 417 } else { 418 O << getRegisterName(RegNo); 419 return; 420 } 421 422 if (NumRegs == 1) { 423 O << RegIdx; 424 return; 425 } 426 427 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; 428 } 429 430 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, 431 const MCSubtargetInfo &STI, raw_ostream &O) { 432 if (OpNo == 0) { 433 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) 434 O << "_e64 "; 435 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) 436 O << "_dpp "; 437 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) 438 O << "_sdwa "; 439 else 440 O << "_e32 "; 441 } 442 443 printOperand(MI, OpNo, STI, O); 444 445 // Print default vcc/vcc_lo operand. 446 switch (MI->getOpcode()) { 447 default: break; 448 449 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10: 450 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10: 451 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10: 452 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10: 453 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10: 454 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10: 455 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10: 456 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10: 457 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10: 458 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10: 459 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10: 460 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10: 461 printDefaultVccOperand(1, STI, O); 462 break; 463 } 464 } 465 466 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo, 467 const MCSubtargetInfo &STI, raw_ostream &O) { 468 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI)) 469 O << " "; 470 else 471 O << "_e32 "; 472 473 printOperand(MI, OpNo, STI, O); 474 } 475 476 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm, 477 const MCSubtargetInfo &STI, 478 raw_ostream &O) { 479 int16_t SImm = static_cast<int16_t>(Imm); 480 if (SImm >= -16 && SImm <= 64) { 481 O << SImm; 482 return; 483 } 484 485 if (Imm == 0x3C00) 486 O<< "1.0"; 487 else if (Imm == 0xBC00) 488 O<< "-1.0"; 489 else if (Imm == 0x3800) 490 O<< "0.5"; 491 else if (Imm == 0xB800) 492 O<< "-0.5"; 493 else if (Imm == 0x4000) 494 O<< "2.0"; 495 else if (Imm == 0xC000) 496 O<< "-2.0"; 497 else if (Imm == 0x4400) 498 O<< "4.0"; 499 else if (Imm == 0xC400) 500 O<< "-4.0"; 501 else if (Imm == 0x3118) { 502 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]); 503 O << "0.15915494"; 504 } else 505 O << formatHex(static_cast<uint64_t>(Imm)); 506 } 507 508 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, 509 const MCSubtargetInfo &STI, 510 raw_ostream &O) { 511 uint16_t Lo16 = static_cast<uint16_t>(Imm); 512 printImmediate16(Lo16, STI, O); 513 } 514 515 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, 516 const MCSubtargetInfo &STI, 517 raw_ostream &O) { 518 int32_t SImm = static_cast<int32_t>(Imm); 519 if (SImm >= -16 && SImm <= 64) { 520 O << SImm; 521 return; 522 } 523 524 if (Imm == FloatToBits(0.0f)) 525 O << "0.0"; 526 else if (Imm == FloatToBits(1.0f)) 527 O << "1.0"; 528 else if (Imm == FloatToBits(-1.0f)) 529 O << "-1.0"; 530 else if (Imm == FloatToBits(0.5f)) 531 O << "0.5"; 532 else if (Imm == FloatToBits(-0.5f)) 533 O << "-0.5"; 534 else if (Imm == FloatToBits(2.0f)) 535 O << "2.0"; 536 else if (Imm == FloatToBits(-2.0f)) 537 O << "-2.0"; 538 else if (Imm == FloatToBits(4.0f)) 539 O << "4.0"; 540 else if (Imm == FloatToBits(-4.0f)) 541 O << "-4.0"; 542 else if (Imm == 0x3e22f983 && 543 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 544 O << "0.15915494"; 545 else 546 O << formatHex(static_cast<uint64_t>(Imm)); 547 } 548 549 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, 550 const MCSubtargetInfo &STI, 551 raw_ostream &O) { 552 int64_t SImm = static_cast<int64_t>(Imm); 553 if (SImm >= -16 && SImm <= 64) { 554 O << SImm; 555 return; 556 } 557 558 if (Imm == DoubleToBits(0.0)) 559 O << "0.0"; 560 else if (Imm == DoubleToBits(1.0)) 561 O << "1.0"; 562 else if (Imm == DoubleToBits(-1.0)) 563 O << "-1.0"; 564 else if (Imm == DoubleToBits(0.5)) 565 O << "0.5"; 566 else if (Imm == DoubleToBits(-0.5)) 567 O << "-0.5"; 568 else if (Imm == DoubleToBits(2.0)) 569 O << "2.0"; 570 else if (Imm == DoubleToBits(-2.0)) 571 O << "-2.0"; 572 else if (Imm == DoubleToBits(4.0)) 573 O << "4.0"; 574 else if (Imm == DoubleToBits(-4.0)) 575 O << "-4.0"; 576 else if (Imm == 0x3fc45f306dc9c882 && 577 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 578 O << "0.15915494309189532"; 579 else { 580 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882); 581 582 // In rare situations, we will have a 32-bit literal in a 64-bit 583 // operand. This is technically allowed for the encoding of s_mov_b64. 584 O << formatHex(static_cast<uint64_t>(Imm)); 585 } 586 } 587 588 void AMDGPUInstPrinter::printDefaultVccOperand(unsigned OpNo, 589 const MCSubtargetInfo &STI, 590 raw_ostream &O) { 591 if (OpNo > 0) 592 O << ", "; 593 printRegOperand(STI.getFeatureBits()[AMDGPU::FeatureWavefrontSize64] ? 594 AMDGPU::VCC : AMDGPU::VCC_LO, O, MRI); 595 if (OpNo == 0) 596 O << ", "; 597 } 598 599 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 600 const MCSubtargetInfo &STI, 601 raw_ostream &O) { 602 // Print default vcc/vcc_lo operand of VOPC. 603 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 604 if (OpNo == 0 && (Desc.TSFlags & SIInstrFlags::VOPC) && 605 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) || 606 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO))) 607 printDefaultVccOperand(OpNo, STI, O); 608 609 if (OpNo >= MI->getNumOperands()) { 610 O << "/*Missing OP" << OpNo << "*/"; 611 return; 612 } 613 614 const MCOperand &Op = MI->getOperand(OpNo); 615 if (Op.isReg()) { 616 printRegOperand(Op.getReg(), O, MRI); 617 } else if (Op.isImm()) { 618 switch (Desc.OpInfo[OpNo].OperandType) { 619 case AMDGPU::OPERAND_REG_IMM_INT32: 620 case AMDGPU::OPERAND_REG_IMM_FP32: 621 case AMDGPU::OPERAND_REG_INLINE_C_INT32: 622 case AMDGPU::OPERAND_REG_INLINE_C_FP32: 623 case MCOI::OPERAND_IMMEDIATE: 624 printImmediate32(Op.getImm(), STI, O); 625 break; 626 case AMDGPU::OPERAND_REG_IMM_INT64: 627 case AMDGPU::OPERAND_REG_IMM_FP64: 628 case AMDGPU::OPERAND_REG_INLINE_C_INT64: 629 case AMDGPU::OPERAND_REG_INLINE_C_FP64: 630 printImmediate64(Op.getImm(), STI, O); 631 break; 632 case AMDGPU::OPERAND_REG_INLINE_C_INT16: 633 case AMDGPU::OPERAND_REG_INLINE_C_FP16: 634 case AMDGPU::OPERAND_REG_IMM_INT16: 635 case AMDGPU::OPERAND_REG_IMM_FP16: 636 printImmediate16(Op.getImm(), STI, O); 637 break; 638 case AMDGPU::OPERAND_REG_IMM_V2INT16: 639 case AMDGPU::OPERAND_REG_IMM_V2FP16: 640 if (!isUInt<16>(Op.getImm()) && 641 STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) { 642 printImmediate32(Op.getImm(), STI, O); 643 break; 644 } 645 LLVM_FALLTHROUGH; 646 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: 647 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: 648 printImmediateV216(Op.getImm(), STI, O); 649 break; 650 case MCOI::OPERAND_UNKNOWN: 651 case MCOI::OPERAND_PCREL: 652 O << formatDec(Op.getImm()); 653 break; 654 case MCOI::OPERAND_REGISTER: 655 // FIXME: This should be removed and handled somewhere else. Seems to come 656 // from a disassembler bug. 657 O << "/*invalid immediate*/"; 658 break; 659 default: 660 // We hit this for the immediate instruction bits that don't yet have a 661 // custom printer. 662 llvm_unreachable("unexpected immediate operand type"); 663 } 664 } else if (Op.isFPImm()) { 665 // We special case 0.0 because otherwise it will be printed as an integer. 666 if (Op.getFPImm() == 0.0) 667 O << "0.0"; 668 else { 669 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 670 int RCID = Desc.OpInfo[OpNo].RegClass; 671 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID)); 672 if (RCBits == 32) 673 printImmediate32(FloatToBits(Op.getFPImm()), STI, O); 674 else if (RCBits == 64) 675 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O); 676 else 677 llvm_unreachable("Invalid register class size"); 678 } 679 } else if (Op.isExpr()) { 680 const MCExpr *Exp = Op.getExpr(); 681 Exp->print(O, &MAI); 682 } else { 683 O << "/*INV_OP*/"; 684 } 685 686 // Print default vcc/vcc_lo operand of v_cndmask_b32_e32. 687 switch (MI->getOpcode()) { 688 default: break; 689 690 case AMDGPU::V_CNDMASK_B32_e32_gfx10: 691 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10: 692 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10: 693 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10: 694 case AMDGPU::V_ADD_CO_CI_U32_dpp_gfx10: 695 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10: 696 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10: 697 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10: 698 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10: 699 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10: 700 701 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7: 702 case AMDGPU::V_CNDMASK_B32_e32_vi: 703 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 704 AMDGPU::OpName::src1)) 705 printDefaultVccOperand(OpNo, STI, O); 706 break; 707 } 708 } 709 710 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 711 unsigned OpNo, 712 const MCSubtargetInfo &STI, 713 raw_ostream &O) { 714 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 715 716 // Use 'neg(...)' instead of '-' to avoid ambiguity. 717 // This is important for integer literals because 718 // -1 is not the same value as neg(1). 719 bool NegMnemo = false; 720 721 if (InputModifiers & SISrcMods::NEG) { 722 if (OpNo + 1 < MI->getNumOperands() && 723 (InputModifiers & SISrcMods::ABS) == 0) { 724 const MCOperand &Op = MI->getOperand(OpNo + 1); 725 NegMnemo = Op.isImm() || Op.isFPImm(); 726 } 727 if (NegMnemo) { 728 O << "neg("; 729 } else { 730 O << '-'; 731 } 732 } 733 734 if (InputModifiers & SISrcMods::ABS) 735 O << '|'; 736 printOperand(MI, OpNo + 1, STI, O); 737 if (InputModifiers & SISrcMods::ABS) 738 O << '|'; 739 740 if (NegMnemo) { 741 O << ')'; 742 } 743 } 744 745 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 746 unsigned OpNo, 747 const MCSubtargetInfo &STI, 748 raw_ostream &O) { 749 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 750 if (InputModifiers & SISrcMods::SEXT) 751 O << "sext("; 752 printOperand(MI, OpNo + 1, STI, O); 753 if (InputModifiers & SISrcMods::SEXT) 754 O << ')'; 755 756 // Print default vcc/vcc_lo operand of VOP2b. 757 switch (MI->getOpcode()) { 758 default: break; 759 760 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10: 761 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10: 762 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10: 763 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 764 AMDGPU::OpName::src1)) 765 printDefaultVccOperand(OpNo, STI, O); 766 break; 767 } 768 } 769 770 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo, 771 const MCSubtargetInfo &STI, 772 raw_ostream &O) { 773 if (!AMDGPU::isGFX10(STI)) 774 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10"); 775 776 unsigned Imm = MI->getOperand(OpNo).getImm(); 777 O << " dpp8:[" << formatDec(Imm & 0x7); 778 for (size_t i = 1; i < 8; ++i) { 779 O << ',' << formatDec((Imm >> (3 * i)) & 0x7); 780 } 781 O << ']'; 782 } 783 784 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 785 const MCSubtargetInfo &STI, 786 raw_ostream &O) { 787 using namespace AMDGPU::DPP; 788 789 unsigned Imm = MI->getOperand(OpNo).getImm(); 790 if (Imm <= DppCtrl::QUAD_PERM_LAST) { 791 O << " quad_perm:["; 792 O << formatDec(Imm & 0x3) << ','; 793 O << formatDec((Imm & 0xc) >> 2) << ','; 794 O << formatDec((Imm & 0x30) >> 4) << ','; 795 O << formatDec((Imm & 0xc0) >> 6) << ']'; 796 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) && 797 (Imm <= DppCtrl::ROW_SHL_LAST)) { 798 O << " row_shl:"; 799 printU4ImmDecOperand(MI, OpNo, O); 800 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) && 801 (Imm <= DppCtrl::ROW_SHR_LAST)) { 802 O << " row_shr:"; 803 printU4ImmDecOperand(MI, OpNo, O); 804 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) && 805 (Imm <= DppCtrl::ROW_ROR_LAST)) { 806 O << " row_ror:"; 807 printU4ImmDecOperand(MI, OpNo, O); 808 } else if (Imm == DppCtrl::WAVE_SHL1) { 809 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 810 O << " /* wave_shl is not supported starting from GFX10 */"; 811 return; 812 } 813 O << " wave_shl:1"; 814 } else if (Imm == DppCtrl::WAVE_ROL1) { 815 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 816 O << " /* wave_rol is not supported starting from GFX10 */"; 817 return; 818 } 819 O << " wave_rol:1"; 820 } else if (Imm == DppCtrl::WAVE_SHR1) { 821 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 822 O << " /* wave_shr is not supported starting from GFX10 */"; 823 return; 824 } 825 O << " wave_shr:1"; 826 } else if (Imm == DppCtrl::WAVE_ROR1) { 827 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 828 O << " /* wave_ror is not supported starting from GFX10 */"; 829 return; 830 } 831 O << " wave_ror:1"; 832 } else if (Imm == DppCtrl::ROW_MIRROR) { 833 O << " row_mirror"; 834 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) { 835 O << " row_half_mirror"; 836 } else if (Imm == DppCtrl::BCAST15) { 837 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 838 O << " /* row_bcast is not supported starting from GFX10 */"; 839 return; 840 } 841 O << " row_bcast:15"; 842 } else if (Imm == DppCtrl::BCAST31) { 843 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 844 O << " /* row_bcast is not supported starting from GFX10 */"; 845 return; 846 } 847 O << " row_bcast:31"; 848 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) && 849 (Imm <= DppCtrl::ROW_SHARE_LAST)) { 850 if (!AMDGPU::isGFX10(STI)) { 851 O << " /* row_share is not supported on ASICs earlier than GFX10 */"; 852 return; 853 } 854 O << " row_share:"; 855 printU4ImmDecOperand(MI, OpNo, O); 856 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) && 857 (Imm <= DppCtrl::ROW_XMASK_LAST)) { 858 if (!AMDGPU::isGFX10(STI)) { 859 O << " /* row_xmask is not supported on ASICs earlier than GFX10 */"; 860 return; 861 } 862 O << "row_xmask:"; 863 printU4ImmDecOperand(MI, OpNo, O); 864 } else { 865 O << " /* Invalid dpp_ctrl value */"; 866 } 867 } 868 869 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 870 const MCSubtargetInfo &STI, 871 raw_ostream &O) { 872 O << " row_mask:"; 873 printU4ImmOperand(MI, OpNo, STI, O); 874 } 875 876 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 877 const MCSubtargetInfo &STI, 878 raw_ostream &O) { 879 O << " bank_mask:"; 880 printU4ImmOperand(MI, OpNo, STI, O); 881 } 882 883 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 884 const MCSubtargetInfo &STI, 885 raw_ostream &O) { 886 unsigned Imm = MI->getOperand(OpNo).getImm(); 887 if (Imm) { 888 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 889 } 890 } 891 892 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo, 893 const MCSubtargetInfo &STI, 894 raw_ostream &O) { 895 using namespace llvm::AMDGPU::DPP; 896 unsigned Imm = MI->getOperand(OpNo).getImm(); 897 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) { 898 O << " fi:1"; 899 } 900 } 901 902 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 903 raw_ostream &O) { 904 using namespace llvm::AMDGPU::SDWA; 905 906 unsigned Imm = MI->getOperand(OpNo).getImm(); 907 switch (Imm) { 908 case SdwaSel::BYTE_0: O << "BYTE_0"; break; 909 case SdwaSel::BYTE_1: O << "BYTE_1"; break; 910 case SdwaSel::BYTE_2: O << "BYTE_2"; break; 911 case SdwaSel::BYTE_3: O << "BYTE_3"; break; 912 case SdwaSel::WORD_0: O << "WORD_0"; break; 913 case SdwaSel::WORD_1: O << "WORD_1"; break; 914 case SdwaSel::DWORD: O << "DWORD"; break; 915 default: llvm_unreachable("Invalid SDWA data select operand"); 916 } 917 } 918 919 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 920 const MCSubtargetInfo &STI, 921 raw_ostream &O) { 922 O << "dst_sel:"; 923 printSDWASel(MI, OpNo, O); 924 } 925 926 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 927 const MCSubtargetInfo &STI, 928 raw_ostream &O) { 929 O << "src0_sel:"; 930 printSDWASel(MI, OpNo, O); 931 } 932 933 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 934 const MCSubtargetInfo &STI, 935 raw_ostream &O) { 936 O << "src1_sel:"; 937 printSDWASel(MI, OpNo, O); 938 } 939 940 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 941 const MCSubtargetInfo &STI, 942 raw_ostream &O) { 943 using namespace llvm::AMDGPU::SDWA; 944 945 O << "dst_unused:"; 946 unsigned Imm = MI->getOperand(OpNo).getImm(); 947 switch (Imm) { 948 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break; 949 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break; 950 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break; 951 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 952 } 953 } 954 955 template <unsigned N> 956 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo, 957 const MCSubtargetInfo &STI, 958 raw_ostream &O) { 959 unsigned Opc = MI->getOpcode(); 960 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en); 961 unsigned En = MI->getOperand(EnIdx).getImm(); 962 963 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr); 964 965 // If compr is set, print as src0, src0, src1, src1 966 if (MI->getOperand(ComprIdx).getImm()) { 967 if (N == 1 || N == 2) 968 --OpNo; 969 else if (N == 3) 970 OpNo -= 2; 971 } 972 973 if (En & (1 << N)) 974 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI); 975 else 976 O << "off"; 977 } 978 979 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo, 980 const MCSubtargetInfo &STI, 981 raw_ostream &O) { 982 printExpSrcN<0>(MI, OpNo, STI, O); 983 } 984 985 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo, 986 const MCSubtargetInfo &STI, 987 raw_ostream &O) { 988 printExpSrcN<1>(MI, OpNo, STI, O); 989 } 990 991 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo, 992 const MCSubtargetInfo &STI, 993 raw_ostream &O) { 994 printExpSrcN<2>(MI, OpNo, STI, O); 995 } 996 997 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo, 998 const MCSubtargetInfo &STI, 999 raw_ostream &O) { 1000 printExpSrcN<3>(MI, OpNo, STI, O); 1001 } 1002 1003 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo, 1004 const MCSubtargetInfo &STI, 1005 raw_ostream &O) { 1006 // This is really a 6 bit field. 1007 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1); 1008 1009 if (Tgt <= 7) 1010 O << " mrt" << Tgt; 1011 else if (Tgt == 8) 1012 O << " mrtz"; 1013 else if (Tgt == 9) 1014 O << " null"; 1015 else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI))) 1016 O << " pos" << Tgt - 12; 1017 else if (AMDGPU::isGFX10(STI) && Tgt == 20) 1018 O << " prim"; 1019 else if (Tgt >= 32 && Tgt <= 63) 1020 O << " param" << Tgt - 32; 1021 else { 1022 // Reserved values 10, 11 1023 O << " invalid_target_" << Tgt; 1024 } 1025 } 1026 1027 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod, 1028 bool IsPacked, bool HasDstSel) { 1029 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1); 1030 1031 for (int I = 0; I < NumOps; ++I) { 1032 if (!!(Ops[I] & Mod) != DefaultValue) 1033 return false; 1034 } 1035 1036 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0) 1037 return false; 1038 1039 return true; 1040 } 1041 1042 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI, 1043 StringRef Name, 1044 unsigned Mod, 1045 raw_ostream &O) { 1046 unsigned Opc = MI->getOpcode(); 1047 int NumOps = 0; 1048 int Ops[3]; 1049 1050 for (int OpName : { AMDGPU::OpName::src0_modifiers, 1051 AMDGPU::OpName::src1_modifiers, 1052 AMDGPU::OpName::src2_modifiers }) { 1053 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName); 1054 if (Idx == -1) 1055 break; 1056 1057 Ops[NumOps++] = MI->getOperand(Idx).getImm(); 1058 } 1059 1060 const bool HasDstSel = 1061 NumOps > 0 && 1062 Mod == SISrcMods::OP_SEL_0 && 1063 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL; 1064 1065 const bool IsPacked = 1066 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked; 1067 1068 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel)) 1069 return; 1070 1071 O << Name; 1072 for (int I = 0; I < NumOps; ++I) { 1073 if (I != 0) 1074 O << ','; 1075 1076 O << !!(Ops[I] & Mod); 1077 } 1078 1079 if (HasDstSel) { 1080 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL); 1081 } 1082 1083 O << ']'; 1084 } 1085 1086 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned, 1087 const MCSubtargetInfo &STI, 1088 raw_ostream &O) { 1089 unsigned Opc = MI->getOpcode(); 1090 if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 || 1091 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) { 1092 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers); 1093 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers); 1094 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0); 1095 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0); 1096 if (FI || BC) 1097 O << " op_sel:[" << FI << ',' << BC << ']'; 1098 return; 1099 } 1100 1101 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O); 1102 } 1103 1104 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo, 1105 const MCSubtargetInfo &STI, 1106 raw_ostream &O) { 1107 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O); 1108 } 1109 1110 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo, 1111 const MCSubtargetInfo &STI, 1112 raw_ostream &O) { 1113 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O); 1114 } 1115 1116 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo, 1117 const MCSubtargetInfo &STI, 1118 raw_ostream &O) { 1119 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O); 1120 } 1121 1122 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 1123 const MCSubtargetInfo &STI, 1124 raw_ostream &O) { 1125 unsigned Imm = MI->getOperand(OpNum).getImm(); 1126 switch (Imm) { 1127 case 0: 1128 O << "p10"; 1129 break; 1130 case 1: 1131 O << "p20"; 1132 break; 1133 case 2: 1134 O << "p0"; 1135 break; 1136 default: 1137 O << "invalid_param_" << Imm; 1138 } 1139 } 1140 1141 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum, 1142 const MCSubtargetInfo &STI, 1143 raw_ostream &O) { 1144 unsigned Attr = MI->getOperand(OpNum).getImm(); 1145 O << "attr" << Attr; 1146 } 1147 1148 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum, 1149 const MCSubtargetInfo &STI, 1150 raw_ostream &O) { 1151 unsigned Chan = MI->getOperand(OpNum).getImm(); 1152 O << '.' << "xyzw"[Chan & 0x3]; 1153 } 1154 1155 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo, 1156 const MCSubtargetInfo &STI, 1157 raw_ostream &O) { 1158 using namespace llvm::AMDGPU::VGPRIndexMode; 1159 unsigned Val = MI->getOperand(OpNo).getImm(); 1160 1161 if ((Val & ~ENABLE_MASK) != 0) { 1162 O << " " << formatHex(static_cast<uint64_t>(Val)); 1163 } else { 1164 O << " gpr_idx("; 1165 bool NeedComma = false; 1166 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) { 1167 if (Val & (1 << ModeId)) { 1168 if (NeedComma) 1169 O << ','; 1170 O << IdSymbolic[ModeId]; 1171 NeedComma = true; 1172 } 1173 } 1174 O << ')'; 1175 } 1176 } 1177 1178 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1179 const MCSubtargetInfo &STI, 1180 raw_ostream &O) { 1181 printOperand(MI, OpNo, STI, O); 1182 O << ", "; 1183 printOperand(MI, OpNo + 1, STI, O); 1184 } 1185 1186 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1187 raw_ostream &O, StringRef Asm, 1188 StringRef Default) { 1189 const MCOperand &Op = MI->getOperand(OpNo); 1190 assert(Op.isImm()); 1191 if (Op.getImm() == 1) { 1192 O << Asm; 1193 } else { 1194 O << Default; 1195 } 1196 } 1197 1198 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1199 raw_ostream &O, char Asm) { 1200 const MCOperand &Op = MI->getOperand(OpNo); 1201 assert(Op.isImm()); 1202 if (Op.getImm() == 1) 1203 O << Asm; 1204 } 1205 1206 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo, 1207 const MCSubtargetInfo &STI, 1208 raw_ostream &O) { 1209 if (MI->getOperand(OpNo).getImm()) 1210 O << " high"; 1211 } 1212 1213 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 1214 const MCSubtargetInfo &STI, 1215 raw_ostream &O) { 1216 if (MI->getOperand(OpNo).getImm()) 1217 O << " clamp"; 1218 } 1219 1220 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 1221 const MCSubtargetInfo &STI, 1222 raw_ostream &O) { 1223 int Imm = MI->getOperand(OpNo).getImm(); 1224 if (Imm == SIOutMods::MUL2) 1225 O << " mul:2"; 1226 else if (Imm == SIOutMods::MUL4) 1227 O << " mul:4"; 1228 else if (Imm == SIOutMods::DIV2) 1229 O << " div:2"; 1230 } 1231 1232 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 1233 const MCSubtargetInfo &STI, 1234 raw_ostream &O) { 1235 using namespace llvm::AMDGPU::SendMsg; 1236 1237 const unsigned Imm16 = MI->getOperand(OpNo).getImm(); 1238 1239 uint16_t MsgId; 1240 uint16_t OpId; 1241 uint16_t StreamId; 1242 decodeMsg(Imm16, MsgId, OpId, StreamId); 1243 1244 if (isValidMsgId(MsgId, STI) && 1245 isValidMsgOp(MsgId, OpId) && 1246 isValidMsgStream(MsgId, OpId, StreamId)) { 1247 O << "sendmsg(" << getMsgName(MsgId); 1248 if (msgRequiresOp(MsgId)) { 1249 O << ", " << getMsgOpName(MsgId, OpId); 1250 if (msgSupportsStream(MsgId, OpId)) { 1251 O << ", " << StreamId; 1252 } 1253 } 1254 O << ')'; 1255 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) { 1256 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')'; 1257 } else { 1258 O << Imm16; // Unknown imm16 code. 1259 } 1260 } 1261 1262 static void printSwizzleBitmask(const uint16_t AndMask, 1263 const uint16_t OrMask, 1264 const uint16_t XorMask, 1265 raw_ostream &O) { 1266 using namespace llvm::AMDGPU::Swizzle; 1267 1268 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask; 1269 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask; 1270 1271 O << "\""; 1272 1273 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) { 1274 uint16_t p0 = Probe0 & Mask; 1275 uint16_t p1 = Probe1 & Mask; 1276 1277 if (p0 == p1) { 1278 if (p0 == 0) { 1279 O << "0"; 1280 } else { 1281 O << "1"; 1282 } 1283 } else { 1284 if (p0 == 0) { 1285 O << "p"; 1286 } else { 1287 O << "i"; 1288 } 1289 } 1290 } 1291 1292 O << "\""; 1293 } 1294 1295 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo, 1296 const MCSubtargetInfo &STI, 1297 raw_ostream &O) { 1298 using namespace llvm::AMDGPU::Swizzle; 1299 1300 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1301 if (Imm == 0) { 1302 return; 1303 } 1304 1305 O << " offset:"; 1306 1307 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) { 1308 1309 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM]; 1310 for (unsigned I = 0; I < LANE_NUM; ++I) { 1311 O << ","; 1312 O << formatDec(Imm & LANE_MASK); 1313 Imm >>= LANE_SHIFT; 1314 } 1315 O << ")"; 1316 1317 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) { 1318 1319 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK; 1320 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK; 1321 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK; 1322 1323 if (AndMask == BITMASK_MAX && 1324 OrMask == 0 && 1325 countPopulation(XorMask) == 1) { 1326 1327 O << "swizzle(" << IdSymbolic[ID_SWAP]; 1328 O << ","; 1329 O << formatDec(XorMask); 1330 O << ")"; 1331 1332 } else if (AndMask == BITMASK_MAX && 1333 OrMask == 0 && XorMask > 0 && 1334 isPowerOf2_64(XorMask + 1)) { 1335 1336 O << "swizzle(" << IdSymbolic[ID_REVERSE]; 1337 O << ","; 1338 O << formatDec(XorMask + 1); 1339 O << ")"; 1340 1341 } else { 1342 1343 uint16_t GroupSize = BITMASK_MAX - AndMask + 1; 1344 if (GroupSize > 1 && 1345 isPowerOf2_64(GroupSize) && 1346 OrMask < GroupSize && 1347 XorMask == 0) { 1348 1349 O << "swizzle(" << IdSymbolic[ID_BROADCAST]; 1350 O << ","; 1351 O << formatDec(GroupSize); 1352 O << ","; 1353 O << formatDec(OrMask); 1354 O << ")"; 1355 1356 } else { 1357 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM]; 1358 O << ","; 1359 printSwizzleBitmask(AndMask, OrMask, XorMask, O); 1360 O << ")"; 1361 } 1362 } 1363 } else { 1364 printU16ImmDecOperand(MI, OpNo, O); 1365 } 1366 } 1367 1368 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1369 const MCSubtargetInfo &STI, 1370 raw_ostream &O) { 1371 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU()); 1372 1373 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1374 unsigned Vmcnt, Expcnt, Lgkmcnt; 1375 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1376 1377 bool NeedSpace = false; 1378 1379 if (Vmcnt != getVmcntBitMask(ISA)) { 1380 O << "vmcnt(" << Vmcnt << ')'; 1381 NeedSpace = true; 1382 } 1383 1384 if (Expcnt != getExpcntBitMask(ISA)) { 1385 if (NeedSpace) 1386 O << ' '; 1387 O << "expcnt(" << Expcnt << ')'; 1388 NeedSpace = true; 1389 } 1390 1391 if (Lgkmcnt != getLgkmcntBitMask(ISA)) { 1392 if (NeedSpace) 1393 O << ' '; 1394 O << "lgkmcnt(" << Lgkmcnt << ')'; 1395 } 1396 } 1397 1398 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1399 const MCSubtargetInfo &STI, raw_ostream &O) { 1400 unsigned Id; 1401 unsigned Offset; 1402 unsigned Width; 1403 1404 using namespace llvm::AMDGPU::Hwreg; 1405 unsigned Val = MI->getOperand(OpNo).getImm(); 1406 decodeHwreg(Val, Id, Offset, Width); 1407 StringRef HwRegName = getHwreg(Id, STI); 1408 1409 O << "hwreg("; 1410 if (!HwRegName.empty()) { 1411 O << HwRegName; 1412 } else { 1413 O << Id; 1414 } 1415 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) { 1416 O << ", " << Offset << ", " << Width; 1417 } 1418 O << ')'; 1419 } 1420 1421 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo, 1422 const MCSubtargetInfo &STI, 1423 raw_ostream &O) { 1424 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1425 if (Imm == 0) { 1426 return; 1427 } 1428 1429 O << ' ' << formatDec(Imm); 1430 } 1431 1432 #include "AMDGPUGenAsmWriter.inc" 1433 1434 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O, 1435 StringRef Annot, const MCSubtargetInfo &STI) { 1436 O.flush(); 1437 printInstruction(MI, O); 1438 printAnnotation(O, Annot); 1439 } 1440 1441 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 1442 raw_ostream &O) { 1443 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|'); 1444 } 1445 1446 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 1447 raw_ostream &O) { 1448 int BankSwizzle = MI->getOperand(OpNo).getImm(); 1449 switch (BankSwizzle) { 1450 case 1: 1451 O << "BS:VEC_021/SCL_122"; 1452 break; 1453 case 2: 1454 O << "BS:VEC_120/SCL_212"; 1455 break; 1456 case 3: 1457 O << "BS:VEC_102/SCL_221"; 1458 break; 1459 case 4: 1460 O << "BS:VEC_201"; 1461 break; 1462 case 5: 1463 O << "BS:VEC_210"; 1464 break; 1465 default: 1466 break; 1467 } 1468 } 1469 1470 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 1471 raw_ostream &O) { 1472 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT"); 1473 } 1474 1475 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, 1476 raw_ostream &O) { 1477 unsigned CT = MI->getOperand(OpNo).getImm(); 1478 switch (CT) { 1479 case 0: 1480 O << 'U'; 1481 break; 1482 case 1: 1483 O << 'N'; 1484 break; 1485 default: 1486 break; 1487 } 1488 } 1489 1490 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1491 raw_ostream &O) { 1492 int KCacheMode = MI->getOperand(OpNo).getImm(); 1493 if (KCacheMode > 0) { 1494 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1495 O << "CB" << KCacheBank << ':'; 1496 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1497 int LineSize = (KCacheMode == 1) ? 16 : 32; 1498 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1499 } 1500 } 1501 1502 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo, 1503 raw_ostream &O) { 1504 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " "); 1505 } 1506 1507 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 1508 raw_ostream &O) { 1509 const MCOperand &Op = MI->getOperand(OpNo); 1510 assert(Op.isImm() || Op.isExpr()); 1511 if (Op.isImm()) { 1512 int64_t Imm = Op.getImm(); 1513 O << Imm << '(' << BitsToFloat(Imm) << ')'; 1514 } 1515 if (Op.isExpr()) { 1516 Op.getExpr()->print(O << '@', &MAI); 1517 } 1518 } 1519 1520 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 1521 raw_ostream &O) { 1522 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-'); 1523 } 1524 1525 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 1526 raw_ostream &O) { 1527 switch (MI->getOperand(OpNo).getImm()) { 1528 default: break; 1529 case 1: 1530 O << " * 2.0"; 1531 break; 1532 case 2: 1533 O << " * 4.0"; 1534 break; 1535 case 3: 1536 O << " / 2.0"; 1537 break; 1538 } 1539 } 1540 1541 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1542 raw_ostream &O) { 1543 printOperand(MI, OpNo, O); 1544 O << ", "; 1545 printOperand(MI, OpNo + 1, O); 1546 } 1547 1548 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 1549 raw_ostream &O) { 1550 if (OpNo >= MI->getNumOperands()) { 1551 O << "/*Missing OP" << OpNo << "*/"; 1552 return; 1553 } 1554 1555 const MCOperand &Op = MI->getOperand(OpNo); 1556 if (Op.isReg()) { 1557 switch (Op.getReg()) { 1558 // This is the default predicate state, so we don't need to print it. 1559 case R600::PRED_SEL_OFF: 1560 break; 1561 1562 default: 1563 O << getRegisterName(Op.getReg()); 1564 break; 1565 } 1566 } else if (Op.isImm()) { 1567 O << Op.getImm(); 1568 } else if (Op.isFPImm()) { 1569 // We special case 0.0 because otherwise it will be printed as an integer. 1570 if (Op.getFPImm() == 0.0) 1571 O << "0.0"; 1572 else { 1573 O << Op.getFPImm(); 1574 } 1575 } else if (Op.isExpr()) { 1576 const MCExpr *Exp = Op.getExpr(); 1577 Exp->print(O, &MAI); 1578 } else { 1579 O << "/*INV_OP*/"; 1580 } 1581 } 1582 1583 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo, 1584 raw_ostream &O) { 1585 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+'); 1586 } 1587 1588 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 1589 raw_ostream &O) { 1590 unsigned Sel = MI->getOperand(OpNo).getImm(); 1591 switch (Sel) { 1592 case 0: 1593 O << 'X'; 1594 break; 1595 case 1: 1596 O << 'Y'; 1597 break; 1598 case 2: 1599 O << 'Z'; 1600 break; 1601 case 3: 1602 O << 'W'; 1603 break; 1604 case 4: 1605 O << '0'; 1606 break; 1607 case 5: 1608 O << '1'; 1609 break; 1610 case 7: 1611 O << '_'; 1612 break; 1613 default: 1614 break; 1615 } 1616 } 1617 1618 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 1619 raw_ostream &O) { 1620 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,"); 1621 } 1622 1623 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 1624 raw_ostream &O) { 1625 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,"); 1626 } 1627 1628 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 1629 raw_ostream &O) { 1630 const MCOperand &Op = MI->getOperand(OpNo); 1631 if (Op.getImm() == 0) { 1632 O << " (MASKED)"; 1633 } 1634 } 1635 1636 #include "R600GenAsmWriter.inc" 1637