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 SImm16 = MI->getOperand(OpNo).getImm(); 1238 const unsigned Id = SImm16 & ID_MASK_; 1239 do { 1240 if (Id == ID_INTERRUPT || 1241 (Id == ID_GS_ALLOC_REQ && !AMDGPU::isSI(STI) && !AMDGPU::isCI(STI) && 1242 !AMDGPU::isVI(STI))) { 1243 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0. 1244 break; 1245 O << "sendmsg(" << IdSymbolic[Id] << ')'; 1246 return; 1247 } 1248 if (Id == ID_GS || Id == ID_GS_DONE) { 1249 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0. 1250 break; 1251 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_; 1252 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 1253 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only. 1254 break; 1255 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits. 1256 break; 1257 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs]; 1258 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; } 1259 O << ')'; 1260 return; 1261 } 1262 if (Id == ID_SYSMSG) { 1263 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0. 1264 break; 1265 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_; 1266 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown. 1267 break; 1268 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')'; 1269 return; 1270 } 1271 } while (false); 1272 O << SImm16; // Unknown simm16 code. 1273 } 1274 1275 static void printSwizzleBitmask(const uint16_t AndMask, 1276 const uint16_t OrMask, 1277 const uint16_t XorMask, 1278 raw_ostream &O) { 1279 using namespace llvm::AMDGPU::Swizzle; 1280 1281 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask; 1282 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask; 1283 1284 O << "\""; 1285 1286 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) { 1287 uint16_t p0 = Probe0 & Mask; 1288 uint16_t p1 = Probe1 & Mask; 1289 1290 if (p0 == p1) { 1291 if (p0 == 0) { 1292 O << "0"; 1293 } else { 1294 O << "1"; 1295 } 1296 } else { 1297 if (p0 == 0) { 1298 O << "p"; 1299 } else { 1300 O << "i"; 1301 } 1302 } 1303 } 1304 1305 O << "\""; 1306 } 1307 1308 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo, 1309 const MCSubtargetInfo &STI, 1310 raw_ostream &O) { 1311 using namespace llvm::AMDGPU::Swizzle; 1312 1313 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1314 if (Imm == 0) { 1315 return; 1316 } 1317 1318 O << " offset:"; 1319 1320 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) { 1321 1322 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM]; 1323 for (unsigned I = 0; I < LANE_NUM; ++I) { 1324 O << ","; 1325 O << formatDec(Imm & LANE_MASK); 1326 Imm >>= LANE_SHIFT; 1327 } 1328 O << ")"; 1329 1330 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) { 1331 1332 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK; 1333 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK; 1334 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK; 1335 1336 if (AndMask == BITMASK_MAX && 1337 OrMask == 0 && 1338 countPopulation(XorMask) == 1) { 1339 1340 O << "swizzle(" << IdSymbolic[ID_SWAP]; 1341 O << ","; 1342 O << formatDec(XorMask); 1343 O << ")"; 1344 1345 } else if (AndMask == BITMASK_MAX && 1346 OrMask == 0 && XorMask > 0 && 1347 isPowerOf2_64(XorMask + 1)) { 1348 1349 O << "swizzle(" << IdSymbolic[ID_REVERSE]; 1350 O << ","; 1351 O << formatDec(XorMask + 1); 1352 O << ")"; 1353 1354 } else { 1355 1356 uint16_t GroupSize = BITMASK_MAX - AndMask + 1; 1357 if (GroupSize > 1 && 1358 isPowerOf2_64(GroupSize) && 1359 OrMask < GroupSize && 1360 XorMask == 0) { 1361 1362 O << "swizzle(" << IdSymbolic[ID_BROADCAST]; 1363 O << ","; 1364 O << formatDec(GroupSize); 1365 O << ","; 1366 O << formatDec(OrMask); 1367 O << ")"; 1368 1369 } else { 1370 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM]; 1371 O << ","; 1372 printSwizzleBitmask(AndMask, OrMask, XorMask, O); 1373 O << ")"; 1374 } 1375 } 1376 } else { 1377 printU16ImmDecOperand(MI, OpNo, O); 1378 } 1379 } 1380 1381 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1382 const MCSubtargetInfo &STI, 1383 raw_ostream &O) { 1384 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU()); 1385 1386 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1387 unsigned Vmcnt, Expcnt, Lgkmcnt; 1388 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1389 1390 bool NeedSpace = false; 1391 1392 if (Vmcnt != getVmcntBitMask(ISA)) { 1393 O << "vmcnt(" << Vmcnt << ')'; 1394 NeedSpace = true; 1395 } 1396 1397 if (Expcnt != getExpcntBitMask(ISA)) { 1398 if (NeedSpace) 1399 O << ' '; 1400 O << "expcnt(" << Expcnt << ')'; 1401 NeedSpace = true; 1402 } 1403 1404 if (Lgkmcnt != getLgkmcntBitMask(ISA)) { 1405 if (NeedSpace) 1406 O << ' '; 1407 O << "lgkmcnt(" << Lgkmcnt << ')'; 1408 } 1409 } 1410 1411 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1412 const MCSubtargetInfo &STI, raw_ostream &O) { 1413 unsigned Id; 1414 unsigned Offset; 1415 unsigned Width; 1416 1417 using namespace llvm::AMDGPU::Hwreg; 1418 unsigned Val = MI->getOperand(OpNo).getImm(); 1419 decodeHwreg(Val, Id, Offset, Width); 1420 StringRef HwRegName = getHwreg(Id, STI); 1421 1422 O << "hwreg("; 1423 if (!HwRegName.empty()) { 1424 O << HwRegName; 1425 } else { 1426 O << Id; 1427 } 1428 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) { 1429 O << ", " << Offset << ", " << Width; 1430 } 1431 O << ')'; 1432 } 1433 1434 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo, 1435 const MCSubtargetInfo &STI, 1436 raw_ostream &O) { 1437 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1438 if (Imm == 0) { 1439 return; 1440 } 1441 1442 O << ' ' << formatDec(Imm); 1443 } 1444 1445 #include "AMDGPUGenAsmWriter.inc" 1446 1447 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O, 1448 StringRef Annot, const MCSubtargetInfo &STI) { 1449 O.flush(); 1450 printInstruction(MI, O); 1451 printAnnotation(O, Annot); 1452 } 1453 1454 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 1455 raw_ostream &O) { 1456 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|'); 1457 } 1458 1459 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 1460 raw_ostream &O) { 1461 int BankSwizzle = MI->getOperand(OpNo).getImm(); 1462 switch (BankSwizzle) { 1463 case 1: 1464 O << "BS:VEC_021/SCL_122"; 1465 break; 1466 case 2: 1467 O << "BS:VEC_120/SCL_212"; 1468 break; 1469 case 3: 1470 O << "BS:VEC_102/SCL_221"; 1471 break; 1472 case 4: 1473 O << "BS:VEC_201"; 1474 break; 1475 case 5: 1476 O << "BS:VEC_210"; 1477 break; 1478 default: 1479 break; 1480 } 1481 } 1482 1483 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 1484 raw_ostream &O) { 1485 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT"); 1486 } 1487 1488 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, 1489 raw_ostream &O) { 1490 unsigned CT = MI->getOperand(OpNo).getImm(); 1491 switch (CT) { 1492 case 0: 1493 O << 'U'; 1494 break; 1495 case 1: 1496 O << 'N'; 1497 break; 1498 default: 1499 break; 1500 } 1501 } 1502 1503 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1504 raw_ostream &O) { 1505 int KCacheMode = MI->getOperand(OpNo).getImm(); 1506 if (KCacheMode > 0) { 1507 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1508 O << "CB" << KCacheBank << ':'; 1509 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1510 int LineSize = (KCacheMode == 1) ? 16 : 32; 1511 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1512 } 1513 } 1514 1515 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo, 1516 raw_ostream &O) { 1517 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " "); 1518 } 1519 1520 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 1521 raw_ostream &O) { 1522 const MCOperand &Op = MI->getOperand(OpNo); 1523 assert(Op.isImm() || Op.isExpr()); 1524 if (Op.isImm()) { 1525 int64_t Imm = Op.getImm(); 1526 O << Imm << '(' << BitsToFloat(Imm) << ')'; 1527 } 1528 if (Op.isExpr()) { 1529 Op.getExpr()->print(O << '@', &MAI); 1530 } 1531 } 1532 1533 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 1534 raw_ostream &O) { 1535 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-'); 1536 } 1537 1538 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 1539 raw_ostream &O) { 1540 switch (MI->getOperand(OpNo).getImm()) { 1541 default: break; 1542 case 1: 1543 O << " * 2.0"; 1544 break; 1545 case 2: 1546 O << " * 4.0"; 1547 break; 1548 case 3: 1549 O << " / 2.0"; 1550 break; 1551 } 1552 } 1553 1554 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1555 raw_ostream &O) { 1556 printOperand(MI, OpNo, O); 1557 O << ", "; 1558 printOperand(MI, OpNo + 1, O); 1559 } 1560 1561 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 1562 raw_ostream &O) { 1563 if (OpNo >= MI->getNumOperands()) { 1564 O << "/*Missing OP" << OpNo << "*/"; 1565 return; 1566 } 1567 1568 const MCOperand &Op = MI->getOperand(OpNo); 1569 if (Op.isReg()) { 1570 switch (Op.getReg()) { 1571 // This is the default predicate state, so we don't need to print it. 1572 case R600::PRED_SEL_OFF: 1573 break; 1574 1575 default: 1576 O << getRegisterName(Op.getReg()); 1577 break; 1578 } 1579 } else if (Op.isImm()) { 1580 O << Op.getImm(); 1581 } else if (Op.isFPImm()) { 1582 // We special case 0.0 because otherwise it will be printed as an integer. 1583 if (Op.getFPImm() == 0.0) 1584 O << "0.0"; 1585 else { 1586 O << Op.getFPImm(); 1587 } 1588 } else if (Op.isExpr()) { 1589 const MCExpr *Exp = Op.getExpr(); 1590 Exp->print(O, &MAI); 1591 } else { 1592 O << "/*INV_OP*/"; 1593 } 1594 } 1595 1596 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo, 1597 raw_ostream &O) { 1598 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+'); 1599 } 1600 1601 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 1602 raw_ostream &O) { 1603 unsigned Sel = MI->getOperand(OpNo).getImm(); 1604 switch (Sel) { 1605 case 0: 1606 O << 'X'; 1607 break; 1608 case 1: 1609 O << 'Y'; 1610 break; 1611 case 2: 1612 O << 'Z'; 1613 break; 1614 case 3: 1615 O << 'W'; 1616 break; 1617 case 4: 1618 O << '0'; 1619 break; 1620 case 5: 1621 O << '1'; 1622 break; 1623 case 7: 1624 O << '_'; 1625 break; 1626 default: 1627 break; 1628 } 1629 } 1630 1631 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 1632 raw_ostream &O) { 1633 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,"); 1634 } 1635 1636 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 1637 raw_ostream &O) { 1638 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,"); 1639 } 1640 1641 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 1642 raw_ostream &O) { 1643 const MCOperand &Op = MI->getOperand(OpNo); 1644 if (Op.getImm() == 0) { 1645 O << " (MASKED)"; 1646 } 1647 } 1648 1649 #include "R600GenAsmWriter.inc" 1650