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