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::SCC: 285 O << "scc"; 286 return; 287 case AMDGPU::EXEC: 288 O << "exec"; 289 return; 290 case AMDGPU::M0: 291 O << "m0"; 292 return; 293 case AMDGPU::SGPR_NULL: 294 O << "null"; 295 return; 296 case AMDGPU::FLAT_SCR: 297 O << "flat_scratch"; 298 return; 299 case AMDGPU::XNACK_MASK: 300 O << "xnack_mask"; 301 return; 302 case AMDGPU::SRC_SHARED_BASE: 303 O << "src_shared_base"; 304 return; 305 case AMDGPU::SRC_SHARED_LIMIT: 306 O << "src_shared_limit"; 307 return; 308 case AMDGPU::SRC_PRIVATE_BASE: 309 O << "src_private_base"; 310 return; 311 case AMDGPU::SRC_PRIVATE_LIMIT: 312 O << "src_private_limit"; 313 return; 314 case AMDGPU::SRC_POPS_EXITING_WAVE_ID: 315 O << "src_pops_exiting_wave_id"; 316 return; 317 case AMDGPU::LDS_DIRECT: 318 O << "src_lds_direct"; 319 return; 320 case AMDGPU::VCC_LO: 321 O << "vcc_lo"; 322 return; 323 case AMDGPU::VCC_HI: 324 O << "vcc_hi"; 325 return; 326 case AMDGPU::TBA_LO: 327 O << "tba_lo"; 328 return; 329 case AMDGPU::TBA_HI: 330 O << "tba_hi"; 331 return; 332 case AMDGPU::TMA_LO: 333 O << "tma_lo"; 334 return; 335 case AMDGPU::TMA_HI: 336 O << "tma_hi"; 337 return; 338 case AMDGPU::EXEC_LO: 339 O << "exec_lo"; 340 return; 341 case AMDGPU::EXEC_HI: 342 O << "exec_hi"; 343 return; 344 case AMDGPU::FLAT_SCR_LO: 345 O << "flat_scratch_lo"; 346 return; 347 case AMDGPU::FLAT_SCR_HI: 348 O << "flat_scratch_hi"; 349 return; 350 case AMDGPU::XNACK_MASK_LO: 351 O << "xnack_mask_lo"; 352 return; 353 case AMDGPU::XNACK_MASK_HI: 354 O << "xnack_mask_hi"; 355 return; 356 case AMDGPU::FP_REG: 357 case AMDGPU::SP_REG: 358 case AMDGPU::SCRATCH_WAVE_OFFSET_REG: 359 case AMDGPU::PRIVATE_RSRC_REG: 360 llvm_unreachable("pseudo-register should not ever be emitted"); 361 default: 362 break; 363 } 364 365 // The low 8 bits of the encoding value is the register index, for both VGPRs 366 // and SGPRs. 367 unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1); 368 369 unsigned NumRegs; 370 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) { 371 O << 'v'; 372 NumRegs = 1; 373 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) { 374 O << 's'; 375 NumRegs = 1; 376 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) { 377 O <<'v'; 378 NumRegs = 2; 379 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) { 380 O << 's'; 381 NumRegs = 2; 382 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) { 383 O << 'v'; 384 NumRegs = 4; 385 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) { 386 O << 's'; 387 NumRegs = 4; 388 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) { 389 O << 'v'; 390 NumRegs = 3; 391 } else if (MRI.getRegClass(AMDGPU::SReg_96RegClassID).contains(RegNo)) { 392 O << 's'; 393 NumRegs = 3; 394 } else if (MRI.getRegClass(AMDGPU::VReg_160RegClassID).contains(RegNo)) { 395 O << 'v'; 396 NumRegs = 5; 397 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) { 398 O << 'v'; 399 NumRegs = 8; 400 } else if (MRI.getRegClass(AMDGPU::SGPR_256RegClassID).contains(RegNo)) { 401 O << 's'; 402 NumRegs = 8; 403 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) { 404 O << 'v'; 405 NumRegs = 16; 406 } else if (MRI.getRegClass(AMDGPU::SGPR_512RegClassID).contains(RegNo)) { 407 O << 's'; 408 NumRegs = 16; 409 } else { 410 O << getRegisterName(RegNo); 411 return; 412 } 413 414 if (NumRegs == 1) { 415 O << RegIdx; 416 return; 417 } 418 419 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; 420 } 421 422 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, 423 const MCSubtargetInfo &STI, raw_ostream &O) { 424 if (OpNo == 0) { 425 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) 426 O << "_e64 "; 427 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) 428 O << "_dpp "; 429 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) 430 O << "_sdwa "; 431 else 432 O << "_e32 "; 433 } 434 435 printOperand(MI, OpNo, STI, O); 436 437 switch (MI->getOpcode()) { 438 default: break; 439 440 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10: 441 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10: 442 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10: 443 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10: 444 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10: 445 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10: 446 printDefaultVccOperand(1, STI, O); 447 break; 448 } 449 } 450 451 void AMDGPUInstPrinter::printVINTRPDst(const MCInst *MI, unsigned OpNo, 452 const MCSubtargetInfo &STI, raw_ostream &O) { 453 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI)) 454 O << " "; 455 else 456 O << "_e32 "; 457 458 printOperand(MI, OpNo, STI, O); 459 } 460 461 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm, 462 const MCSubtargetInfo &STI, 463 raw_ostream &O) { 464 int16_t SImm = static_cast<int16_t>(Imm); 465 if (SImm >= -16 && SImm <= 64) { 466 O << SImm; 467 return; 468 } 469 470 if (Imm == 0x3C00) 471 O<< "1.0"; 472 else if (Imm == 0xBC00) 473 O<< "-1.0"; 474 else if (Imm == 0x3800) 475 O<< "0.5"; 476 else if (Imm == 0xB800) 477 O<< "-0.5"; 478 else if (Imm == 0x4000) 479 O<< "2.0"; 480 else if (Imm == 0xC000) 481 O<< "-2.0"; 482 else if (Imm == 0x4400) 483 O<< "4.0"; 484 else if (Imm == 0xC400) 485 O<< "-4.0"; 486 else if (Imm == 0x3118) { 487 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]); 488 O << "0.15915494"; 489 } else 490 O << formatHex(static_cast<uint64_t>(Imm)); 491 } 492 493 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, 494 const MCSubtargetInfo &STI, 495 raw_ostream &O) { 496 uint16_t Lo16 = static_cast<uint16_t>(Imm); 497 printImmediate16(Lo16, STI, O); 498 } 499 500 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, 501 const MCSubtargetInfo &STI, 502 raw_ostream &O) { 503 int32_t SImm = static_cast<int32_t>(Imm); 504 if (SImm >= -16 && SImm <= 64) { 505 O << SImm; 506 return; 507 } 508 509 if (Imm == FloatToBits(0.0f)) 510 O << "0.0"; 511 else if (Imm == FloatToBits(1.0f)) 512 O << "1.0"; 513 else if (Imm == FloatToBits(-1.0f)) 514 O << "-1.0"; 515 else if (Imm == FloatToBits(0.5f)) 516 O << "0.5"; 517 else if (Imm == FloatToBits(-0.5f)) 518 O << "-0.5"; 519 else if (Imm == FloatToBits(2.0f)) 520 O << "2.0"; 521 else if (Imm == FloatToBits(-2.0f)) 522 O << "-2.0"; 523 else if (Imm == FloatToBits(4.0f)) 524 O << "4.0"; 525 else if (Imm == FloatToBits(-4.0f)) 526 O << "-4.0"; 527 else if (Imm == 0x3e22f983 && 528 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 529 O << "0.15915494"; 530 else 531 O << formatHex(static_cast<uint64_t>(Imm)); 532 } 533 534 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, 535 const MCSubtargetInfo &STI, 536 raw_ostream &O) { 537 int64_t SImm = static_cast<int64_t>(Imm); 538 if (SImm >= -16 && SImm <= 64) { 539 O << SImm; 540 return; 541 } 542 543 if (Imm == DoubleToBits(0.0)) 544 O << "0.0"; 545 else if (Imm == DoubleToBits(1.0)) 546 O << "1.0"; 547 else if (Imm == DoubleToBits(-1.0)) 548 O << "-1.0"; 549 else if (Imm == DoubleToBits(0.5)) 550 O << "0.5"; 551 else if (Imm == DoubleToBits(-0.5)) 552 O << "-0.5"; 553 else if (Imm == DoubleToBits(2.0)) 554 O << "2.0"; 555 else if (Imm == DoubleToBits(-2.0)) 556 O << "-2.0"; 557 else if (Imm == DoubleToBits(4.0)) 558 O << "4.0"; 559 else if (Imm == DoubleToBits(-4.0)) 560 O << "-4.0"; 561 else if (Imm == 0x3fc45f306dc9c882 && 562 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 563 O << "0.15915494309189532"; 564 else { 565 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882); 566 567 // In rare situations, we will have a 32-bit literal in a 64-bit 568 // operand. This is technically allowed for the encoding of s_mov_b64. 569 O << formatHex(static_cast<uint64_t>(Imm)); 570 } 571 } 572 573 void AMDGPUInstPrinter::printDefaultVccOperand(unsigned OpNo, 574 const MCSubtargetInfo &STI, 575 raw_ostream &O) { 576 if (OpNo > 0) 577 O << ", "; 578 printRegOperand(AMDGPU::VCC, O, MRI); 579 if (OpNo == 0) 580 O << ", "; 581 } 582 583 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 584 const MCSubtargetInfo &STI, 585 raw_ostream &O) { 586 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 587 if (OpNo == 0 && (Desc.TSFlags & SIInstrFlags::VOPC) && 588 (Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC) || 589 Desc.hasImplicitDefOfPhysReg(AMDGPU::VCC_LO))) 590 printDefaultVccOperand(OpNo, STI, O); 591 592 if (OpNo >= MI->getNumOperands()) { 593 O << "/*Missing OP" << OpNo << "*/"; 594 return; 595 } 596 597 const MCOperand &Op = MI->getOperand(OpNo); 598 if (Op.isReg()) { 599 printRegOperand(Op.getReg(), O, MRI); 600 } else if (Op.isImm()) { 601 switch (Desc.OpInfo[OpNo].OperandType) { 602 case AMDGPU::OPERAND_REG_IMM_INT32: 603 case AMDGPU::OPERAND_REG_IMM_FP32: 604 case AMDGPU::OPERAND_REG_INLINE_C_INT32: 605 case AMDGPU::OPERAND_REG_INLINE_C_FP32: 606 case MCOI::OPERAND_IMMEDIATE: 607 printImmediate32(Op.getImm(), STI, O); 608 break; 609 case AMDGPU::OPERAND_REG_IMM_INT64: 610 case AMDGPU::OPERAND_REG_IMM_FP64: 611 case AMDGPU::OPERAND_REG_INLINE_C_INT64: 612 case AMDGPU::OPERAND_REG_INLINE_C_FP64: 613 printImmediate64(Op.getImm(), STI, O); 614 break; 615 case AMDGPU::OPERAND_REG_INLINE_C_INT16: 616 case AMDGPU::OPERAND_REG_INLINE_C_FP16: 617 case AMDGPU::OPERAND_REG_IMM_INT16: 618 case AMDGPU::OPERAND_REG_IMM_FP16: 619 printImmediate16(Op.getImm(), STI, O); 620 break; 621 case AMDGPU::OPERAND_REG_IMM_V2INT16: 622 case AMDGPU::OPERAND_REG_IMM_V2FP16: 623 if (!isUInt<16>(Op.getImm()) && 624 STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) { 625 printImmediate32(Op.getImm(), STI, O); 626 break; 627 } 628 LLVM_FALLTHROUGH; 629 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: 630 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: 631 printImmediateV216(Op.getImm(), STI, O); 632 break; 633 case MCOI::OPERAND_UNKNOWN: 634 case MCOI::OPERAND_PCREL: 635 O << formatDec(Op.getImm()); 636 break; 637 case MCOI::OPERAND_REGISTER: 638 // FIXME: This should be removed and handled somewhere else. Seems to come 639 // from a disassembler bug. 640 O << "/*invalid immediate*/"; 641 break; 642 default: 643 // We hit this for the immediate instruction bits that don't yet have a 644 // custom printer. 645 llvm_unreachable("unexpected immediate operand type"); 646 } 647 } else if (Op.isFPImm()) { 648 // We special case 0.0 because otherwise it will be printed as an integer. 649 if (Op.getFPImm() == 0.0) 650 O << "0.0"; 651 else { 652 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 653 int RCID = Desc.OpInfo[OpNo].RegClass; 654 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID)); 655 if (RCBits == 32) 656 printImmediate32(FloatToBits(Op.getFPImm()), STI, O); 657 else if (RCBits == 64) 658 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O); 659 else 660 llvm_unreachable("Invalid register class size"); 661 } 662 } else if (Op.isExpr()) { 663 const MCExpr *Exp = Op.getExpr(); 664 Exp->print(O, &MAI); 665 } else { 666 O << "/*INV_OP*/"; 667 } 668 669 switch (MI->getOpcode()) { 670 default: break; 671 672 case AMDGPU::V_CNDMASK_B32_e32_gfx10: 673 case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10: 674 case AMDGPU::V_SUB_CO_CI_U32_e32_gfx10: 675 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10: 676 677 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7: 678 case AMDGPU::V_CNDMASK_B32_e32_vi: 679 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 680 AMDGPU::OpName::src1)) 681 printDefaultVccOperand(OpNo, STI, O); 682 break; 683 } 684 } 685 686 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 687 unsigned OpNo, 688 const MCSubtargetInfo &STI, 689 raw_ostream &O) { 690 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 691 692 // Use 'neg(...)' instead of '-' to avoid ambiguity. 693 // This is important for integer literals because 694 // -1 is not the same value as neg(1). 695 bool NegMnemo = false; 696 697 if (InputModifiers & SISrcMods::NEG) { 698 if (OpNo + 1 < MI->getNumOperands() && 699 (InputModifiers & SISrcMods::ABS) == 0) { 700 const MCOperand &Op = MI->getOperand(OpNo + 1); 701 NegMnemo = Op.isImm() || Op.isFPImm(); 702 } 703 if (NegMnemo) { 704 O << "neg("; 705 } else { 706 O << '-'; 707 } 708 } 709 710 if (InputModifiers & SISrcMods::ABS) 711 O << '|'; 712 printOperand(MI, OpNo + 1, STI, O); 713 if (InputModifiers & SISrcMods::ABS) 714 O << '|'; 715 716 if (NegMnemo) { 717 O << ')'; 718 } 719 } 720 721 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 722 unsigned OpNo, 723 const MCSubtargetInfo &STI, 724 raw_ostream &O) { 725 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 726 if (InputModifiers & SISrcMods::SEXT) 727 O << "sext("; 728 printOperand(MI, OpNo + 1, STI, O); 729 if (InputModifiers & SISrcMods::SEXT) 730 O << ')'; 731 732 switch (MI->getOpcode()) { 733 default: break; 734 735 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10: 736 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10: 737 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10: 738 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 739 AMDGPU::OpName::src1)) 740 printDefaultVccOperand(OpNo, STI, O); 741 break; 742 } 743 } 744 745 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 746 const MCSubtargetInfo &STI, 747 raw_ostream &O) { 748 using namespace AMDGPU::DPP; 749 750 unsigned Imm = MI->getOperand(OpNo).getImm(); 751 if (Imm <= DppCtrl::QUAD_PERM_LAST) { 752 O << " quad_perm:["; 753 O << formatDec(Imm & 0x3) << ','; 754 O << formatDec((Imm & 0xc) >> 2) << ','; 755 O << formatDec((Imm & 0x30) >> 4) << ','; 756 O << formatDec((Imm & 0xc0) >> 6) << ']'; 757 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) && 758 (Imm <= DppCtrl::ROW_SHL_LAST)) { 759 O << " row_shl:"; 760 printU4ImmDecOperand(MI, OpNo, O); 761 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) && 762 (Imm <= DppCtrl::ROW_SHR_LAST)) { 763 O << " row_shr:"; 764 printU4ImmDecOperand(MI, OpNo, O); 765 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) && 766 (Imm <= DppCtrl::ROW_ROR_LAST)) { 767 O << " row_ror:"; 768 printU4ImmDecOperand(MI, OpNo, O); 769 } else if (Imm == DppCtrl::WAVE_SHL1) { 770 O << " wave_shl:1"; 771 } else if (Imm == DppCtrl::WAVE_ROL1) { 772 O << " wave_rol:1"; 773 } else if (Imm == DppCtrl::WAVE_SHR1) { 774 O << " wave_shr:1"; 775 } else if (Imm == DppCtrl::WAVE_ROR1) { 776 O << " wave_ror:1"; 777 } else if (Imm == DppCtrl::ROW_MIRROR) { 778 O << " row_mirror"; 779 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) { 780 O << " row_half_mirror"; 781 } else if (Imm == DppCtrl::BCAST15) { 782 O << " row_bcast:15"; 783 } else if (Imm == DppCtrl::BCAST31) { 784 O << " row_bcast:31"; 785 } else { 786 O << " /* Invalid dpp_ctrl value */"; 787 } 788 } 789 790 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 791 const MCSubtargetInfo &STI, 792 raw_ostream &O) { 793 O << " row_mask:"; 794 printU4ImmOperand(MI, OpNo, STI, O); 795 } 796 797 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 798 const MCSubtargetInfo &STI, 799 raw_ostream &O) { 800 O << " bank_mask:"; 801 printU4ImmOperand(MI, OpNo, STI, O); 802 } 803 804 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 805 const MCSubtargetInfo &STI, 806 raw_ostream &O) { 807 unsigned Imm = MI->getOperand(OpNo).getImm(); 808 if (Imm) { 809 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 810 } 811 } 812 813 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 814 raw_ostream &O) { 815 using namespace llvm::AMDGPU::SDWA; 816 817 unsigned Imm = MI->getOperand(OpNo).getImm(); 818 switch (Imm) { 819 case SdwaSel::BYTE_0: O << "BYTE_0"; break; 820 case SdwaSel::BYTE_1: O << "BYTE_1"; break; 821 case SdwaSel::BYTE_2: O << "BYTE_2"; break; 822 case SdwaSel::BYTE_3: O << "BYTE_3"; break; 823 case SdwaSel::WORD_0: O << "WORD_0"; break; 824 case SdwaSel::WORD_1: O << "WORD_1"; break; 825 case SdwaSel::DWORD: O << "DWORD"; break; 826 default: llvm_unreachable("Invalid SDWA data select operand"); 827 } 828 } 829 830 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 831 const MCSubtargetInfo &STI, 832 raw_ostream &O) { 833 O << "dst_sel:"; 834 printSDWASel(MI, OpNo, O); 835 } 836 837 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 838 const MCSubtargetInfo &STI, 839 raw_ostream &O) { 840 O << "src0_sel:"; 841 printSDWASel(MI, OpNo, O); 842 } 843 844 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 845 const MCSubtargetInfo &STI, 846 raw_ostream &O) { 847 O << "src1_sel:"; 848 printSDWASel(MI, OpNo, O); 849 } 850 851 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 852 const MCSubtargetInfo &STI, 853 raw_ostream &O) { 854 using namespace llvm::AMDGPU::SDWA; 855 856 O << "dst_unused:"; 857 unsigned Imm = MI->getOperand(OpNo).getImm(); 858 switch (Imm) { 859 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break; 860 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break; 861 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break; 862 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 863 } 864 } 865 866 template <unsigned N> 867 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo, 868 const MCSubtargetInfo &STI, 869 raw_ostream &O) { 870 unsigned Opc = MI->getOpcode(); 871 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en); 872 unsigned En = MI->getOperand(EnIdx).getImm(); 873 874 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr); 875 876 // If compr is set, print as src0, src0, src1, src1 877 if (MI->getOperand(ComprIdx).getImm()) { 878 if (N == 1 || N == 2) 879 --OpNo; 880 else if (N == 3) 881 OpNo -= 2; 882 } 883 884 if (En & (1 << N)) 885 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI); 886 else 887 O << "off"; 888 } 889 890 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo, 891 const MCSubtargetInfo &STI, 892 raw_ostream &O) { 893 printExpSrcN<0>(MI, OpNo, STI, O); 894 } 895 896 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo, 897 const MCSubtargetInfo &STI, 898 raw_ostream &O) { 899 printExpSrcN<1>(MI, OpNo, STI, O); 900 } 901 902 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo, 903 const MCSubtargetInfo &STI, 904 raw_ostream &O) { 905 printExpSrcN<2>(MI, OpNo, STI, O); 906 } 907 908 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo, 909 const MCSubtargetInfo &STI, 910 raw_ostream &O) { 911 printExpSrcN<3>(MI, OpNo, STI, O); 912 } 913 914 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo, 915 const MCSubtargetInfo &STI, 916 raw_ostream &O) { 917 // This is really a 6 bit field. 918 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1); 919 920 if (Tgt <= 7) 921 O << " mrt" << Tgt; 922 else if (Tgt == 8) 923 O << " mrtz"; 924 else if (Tgt == 9) 925 O << " null"; 926 else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI))) 927 O << " pos" << Tgt - 12; 928 else if (AMDGPU::isGFX10(STI) && Tgt == 20) 929 O << " prim"; 930 else if (Tgt >= 32 && Tgt <= 63) 931 O << " param" << Tgt - 32; 932 else { 933 // Reserved values 10, 11 934 O << " invalid_target_" << Tgt; 935 } 936 } 937 938 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod, 939 bool IsPacked, bool HasDstSel) { 940 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1); 941 942 for (int I = 0; I < NumOps; ++I) { 943 if (!!(Ops[I] & Mod) != DefaultValue) 944 return false; 945 } 946 947 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0) 948 return false; 949 950 return true; 951 } 952 953 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI, 954 StringRef Name, 955 unsigned Mod, 956 raw_ostream &O) { 957 unsigned Opc = MI->getOpcode(); 958 int NumOps = 0; 959 int Ops[3]; 960 961 for (int OpName : { AMDGPU::OpName::src0_modifiers, 962 AMDGPU::OpName::src1_modifiers, 963 AMDGPU::OpName::src2_modifiers }) { 964 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName); 965 if (Idx == -1) 966 break; 967 968 Ops[NumOps++] = MI->getOperand(Idx).getImm(); 969 } 970 971 const bool HasDstSel = 972 NumOps > 0 && 973 Mod == SISrcMods::OP_SEL_0 && 974 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL; 975 976 const bool IsPacked = 977 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked; 978 979 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel)) 980 return; 981 982 O << Name; 983 for (int I = 0; I < NumOps; ++I) { 984 if (I != 0) 985 O << ','; 986 987 O << !!(Ops[I] & Mod); 988 } 989 990 if (HasDstSel) { 991 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL); 992 } 993 994 O << ']'; 995 } 996 997 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned, 998 const MCSubtargetInfo &STI, 999 raw_ostream &O) { 1000 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O); 1001 } 1002 1003 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo, 1004 const MCSubtargetInfo &STI, 1005 raw_ostream &O) { 1006 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O); 1007 } 1008 1009 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo, 1010 const MCSubtargetInfo &STI, 1011 raw_ostream &O) { 1012 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O); 1013 } 1014 1015 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo, 1016 const MCSubtargetInfo &STI, 1017 raw_ostream &O) { 1018 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O); 1019 } 1020 1021 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 1022 const MCSubtargetInfo &STI, 1023 raw_ostream &O) { 1024 unsigned Imm = MI->getOperand(OpNum).getImm(); 1025 switch (Imm) { 1026 case 0: 1027 O << "p10"; 1028 break; 1029 case 1: 1030 O << "p20"; 1031 break; 1032 case 2: 1033 O << "p0"; 1034 break; 1035 default: 1036 O << "invalid_param_" << Imm; 1037 } 1038 } 1039 1040 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum, 1041 const MCSubtargetInfo &STI, 1042 raw_ostream &O) { 1043 unsigned Attr = MI->getOperand(OpNum).getImm(); 1044 O << "attr" << Attr; 1045 } 1046 1047 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum, 1048 const MCSubtargetInfo &STI, 1049 raw_ostream &O) { 1050 unsigned Chan = MI->getOperand(OpNum).getImm(); 1051 O << '.' << "xyzw"[Chan & 0x3]; 1052 } 1053 1054 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo, 1055 const MCSubtargetInfo &STI, 1056 raw_ostream &O) { 1057 using namespace llvm::AMDGPU::VGPRIndexMode; 1058 unsigned Val = MI->getOperand(OpNo).getImm(); 1059 1060 if ((Val & ~ENABLE_MASK) != 0) { 1061 O << " " << formatHex(static_cast<uint64_t>(Val)); 1062 } else { 1063 O << " gpr_idx("; 1064 bool NeedComma = false; 1065 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) { 1066 if (Val & (1 << ModeId)) { 1067 if (NeedComma) 1068 O << ','; 1069 O << IdSymbolic[ModeId]; 1070 NeedComma = true; 1071 } 1072 } 1073 O << ')'; 1074 } 1075 } 1076 1077 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1078 const MCSubtargetInfo &STI, 1079 raw_ostream &O) { 1080 printOperand(MI, OpNo, STI, O); 1081 O << ", "; 1082 printOperand(MI, OpNo + 1, STI, O); 1083 } 1084 1085 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1086 raw_ostream &O, StringRef Asm, 1087 StringRef Default) { 1088 const MCOperand &Op = MI->getOperand(OpNo); 1089 assert(Op.isImm()); 1090 if (Op.getImm() == 1) { 1091 O << Asm; 1092 } else { 1093 O << Default; 1094 } 1095 } 1096 1097 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1098 raw_ostream &O, char Asm) { 1099 const MCOperand &Op = MI->getOperand(OpNo); 1100 assert(Op.isImm()); 1101 if (Op.getImm() == 1) 1102 O << Asm; 1103 } 1104 1105 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo, 1106 const MCSubtargetInfo &STI, 1107 raw_ostream &O) { 1108 if (MI->getOperand(OpNo).getImm()) 1109 O << " high"; 1110 } 1111 1112 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 1113 const MCSubtargetInfo &STI, 1114 raw_ostream &O) { 1115 if (MI->getOperand(OpNo).getImm()) 1116 O << " clamp"; 1117 } 1118 1119 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 1120 const MCSubtargetInfo &STI, 1121 raw_ostream &O) { 1122 int Imm = MI->getOperand(OpNo).getImm(); 1123 if (Imm == SIOutMods::MUL2) 1124 O << " mul:2"; 1125 else if (Imm == SIOutMods::MUL4) 1126 O << " mul:4"; 1127 else if (Imm == SIOutMods::DIV2) 1128 O << " div:2"; 1129 } 1130 1131 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 1132 const MCSubtargetInfo &STI, 1133 raw_ostream &O) { 1134 using namespace llvm::AMDGPU::SendMsg; 1135 1136 const unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1137 const unsigned Id = SImm16 & ID_MASK_; 1138 do { 1139 if (Id == ID_INTERRUPT || 1140 (Id == ID_GS_ALLOC_REQ && !AMDGPU::isSI(STI) && !AMDGPU::isCI(STI) && 1141 !AMDGPU::isVI(STI))) { 1142 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0. 1143 break; 1144 O << "sendmsg(" << IdSymbolic[Id] << ')'; 1145 return; 1146 } 1147 if (Id == ID_GS || Id == ID_GS_DONE) { 1148 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0. 1149 break; 1150 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_; 1151 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 1152 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only. 1153 break; 1154 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits. 1155 break; 1156 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs]; 1157 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; } 1158 O << ')'; 1159 return; 1160 } 1161 if (Id == ID_SYSMSG) { 1162 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0. 1163 break; 1164 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_; 1165 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown. 1166 break; 1167 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')'; 1168 return; 1169 } 1170 } while (false); 1171 O << SImm16; // Unknown simm16 code. 1172 } 1173 1174 static void printSwizzleBitmask(const uint16_t AndMask, 1175 const uint16_t OrMask, 1176 const uint16_t XorMask, 1177 raw_ostream &O) { 1178 using namespace llvm::AMDGPU::Swizzle; 1179 1180 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask; 1181 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask; 1182 1183 O << "\""; 1184 1185 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) { 1186 uint16_t p0 = Probe0 & Mask; 1187 uint16_t p1 = Probe1 & Mask; 1188 1189 if (p0 == p1) { 1190 if (p0 == 0) { 1191 O << "0"; 1192 } else { 1193 O << "1"; 1194 } 1195 } else { 1196 if (p0 == 0) { 1197 O << "p"; 1198 } else { 1199 O << "i"; 1200 } 1201 } 1202 } 1203 1204 O << "\""; 1205 } 1206 1207 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo, 1208 const MCSubtargetInfo &STI, 1209 raw_ostream &O) { 1210 using namespace llvm::AMDGPU::Swizzle; 1211 1212 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1213 if (Imm == 0) { 1214 return; 1215 } 1216 1217 O << " offset:"; 1218 1219 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) { 1220 1221 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM]; 1222 for (unsigned I = 0; I < LANE_NUM; ++I) { 1223 O << ","; 1224 O << formatDec(Imm & LANE_MASK); 1225 Imm >>= LANE_SHIFT; 1226 } 1227 O << ")"; 1228 1229 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) { 1230 1231 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK; 1232 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK; 1233 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK; 1234 1235 if (AndMask == BITMASK_MAX && 1236 OrMask == 0 && 1237 countPopulation(XorMask) == 1) { 1238 1239 O << "swizzle(" << IdSymbolic[ID_SWAP]; 1240 O << ","; 1241 O << formatDec(XorMask); 1242 O << ")"; 1243 1244 } else if (AndMask == BITMASK_MAX && 1245 OrMask == 0 && XorMask > 0 && 1246 isPowerOf2_64(XorMask + 1)) { 1247 1248 O << "swizzle(" << IdSymbolic[ID_REVERSE]; 1249 O << ","; 1250 O << formatDec(XorMask + 1); 1251 O << ")"; 1252 1253 } else { 1254 1255 uint16_t GroupSize = BITMASK_MAX - AndMask + 1; 1256 if (GroupSize > 1 && 1257 isPowerOf2_64(GroupSize) && 1258 OrMask < GroupSize && 1259 XorMask == 0) { 1260 1261 O << "swizzle(" << IdSymbolic[ID_BROADCAST]; 1262 O << ","; 1263 O << formatDec(GroupSize); 1264 O << ","; 1265 O << formatDec(OrMask); 1266 O << ")"; 1267 1268 } else { 1269 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM]; 1270 O << ","; 1271 printSwizzleBitmask(AndMask, OrMask, XorMask, O); 1272 O << ")"; 1273 } 1274 } 1275 } else { 1276 printU16ImmDecOperand(MI, OpNo, O); 1277 } 1278 } 1279 1280 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1281 const MCSubtargetInfo &STI, 1282 raw_ostream &O) { 1283 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU()); 1284 1285 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1286 unsigned Vmcnt, Expcnt, Lgkmcnt; 1287 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1288 1289 bool NeedSpace = false; 1290 1291 if (Vmcnt != getVmcntBitMask(ISA)) { 1292 O << "vmcnt(" << Vmcnt << ')'; 1293 NeedSpace = true; 1294 } 1295 1296 if (Expcnt != getExpcntBitMask(ISA)) { 1297 if (NeedSpace) 1298 O << ' '; 1299 O << "expcnt(" << Expcnt << ')'; 1300 NeedSpace = true; 1301 } 1302 1303 if (Lgkmcnt != getLgkmcntBitMask(ISA)) { 1304 if (NeedSpace) 1305 O << ' '; 1306 O << "lgkmcnt(" << Lgkmcnt << ')'; 1307 } 1308 } 1309 1310 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1311 const MCSubtargetInfo &STI, raw_ostream &O) { 1312 using namespace llvm::AMDGPU::Hwreg; 1313 1314 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1315 const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_; 1316 const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_; 1317 const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1; 1318 1319 O << "hwreg("; 1320 unsigned Last = ID_SYMBOLIC_LAST_; 1321 if (AMDGPU::isSI(STI) || AMDGPU::isCI(STI) || AMDGPU::isVI(STI)) 1322 Last = ID_SYMBOLIC_FIRST_GFX9_; 1323 else if (AMDGPU::isGFX9(STI)) 1324 Last = ID_SYMBOLIC_FIRST_GFX10_; 1325 if (ID_SYMBOLIC_FIRST_ <= Id && Id < Last && IdSymbolic[Id]) { 1326 O << IdSymbolic[Id]; 1327 } else { 1328 O << Id; 1329 } 1330 if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) { 1331 O << ", " << Offset << ", " << Width; 1332 } 1333 O << ')'; 1334 } 1335 1336 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo, 1337 const MCSubtargetInfo &STI, 1338 raw_ostream &O) { 1339 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1340 if (Imm == 0) { 1341 return; 1342 } 1343 1344 O << formatDec(Imm); 1345 } 1346 1347 #include "AMDGPUGenAsmWriter.inc" 1348 1349 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O, 1350 StringRef Annot, const MCSubtargetInfo &STI) { 1351 O.flush(); 1352 printInstruction(MI, O); 1353 printAnnotation(O, Annot); 1354 } 1355 1356 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 1357 raw_ostream &O) { 1358 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|'); 1359 } 1360 1361 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 1362 raw_ostream &O) { 1363 int BankSwizzle = MI->getOperand(OpNo).getImm(); 1364 switch (BankSwizzle) { 1365 case 1: 1366 O << "BS:VEC_021/SCL_122"; 1367 break; 1368 case 2: 1369 O << "BS:VEC_120/SCL_212"; 1370 break; 1371 case 3: 1372 O << "BS:VEC_102/SCL_221"; 1373 break; 1374 case 4: 1375 O << "BS:VEC_201"; 1376 break; 1377 case 5: 1378 O << "BS:VEC_210"; 1379 break; 1380 default: 1381 break; 1382 } 1383 } 1384 1385 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 1386 raw_ostream &O) { 1387 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT"); 1388 } 1389 1390 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, 1391 raw_ostream &O) { 1392 unsigned CT = MI->getOperand(OpNo).getImm(); 1393 switch (CT) { 1394 case 0: 1395 O << 'U'; 1396 break; 1397 case 1: 1398 O << 'N'; 1399 break; 1400 default: 1401 break; 1402 } 1403 } 1404 1405 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1406 raw_ostream &O) { 1407 int KCacheMode = MI->getOperand(OpNo).getImm(); 1408 if (KCacheMode > 0) { 1409 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1410 O << "CB" << KCacheBank << ':'; 1411 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1412 int LineSize = (KCacheMode == 1) ? 16 : 32; 1413 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1414 } 1415 } 1416 1417 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo, 1418 raw_ostream &O) { 1419 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " "); 1420 } 1421 1422 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 1423 raw_ostream &O) { 1424 const MCOperand &Op = MI->getOperand(OpNo); 1425 assert(Op.isImm() || Op.isExpr()); 1426 if (Op.isImm()) { 1427 int64_t Imm = Op.getImm(); 1428 O << Imm << '(' << BitsToFloat(Imm) << ')'; 1429 } 1430 if (Op.isExpr()) { 1431 Op.getExpr()->print(O << '@', &MAI); 1432 } 1433 } 1434 1435 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 1436 raw_ostream &O) { 1437 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-'); 1438 } 1439 1440 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 1441 raw_ostream &O) { 1442 switch (MI->getOperand(OpNo).getImm()) { 1443 default: break; 1444 case 1: 1445 O << " * 2.0"; 1446 break; 1447 case 2: 1448 O << " * 4.0"; 1449 break; 1450 case 3: 1451 O << " / 2.0"; 1452 break; 1453 } 1454 } 1455 1456 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1457 raw_ostream &O) { 1458 printOperand(MI, OpNo, O); 1459 O << ", "; 1460 printOperand(MI, OpNo + 1, O); 1461 } 1462 1463 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 1464 raw_ostream &O) { 1465 if (OpNo >= MI->getNumOperands()) { 1466 O << "/*Missing OP" << OpNo << "*/"; 1467 return; 1468 } 1469 1470 const MCOperand &Op = MI->getOperand(OpNo); 1471 if (Op.isReg()) { 1472 switch (Op.getReg()) { 1473 // This is the default predicate state, so we don't need to print it. 1474 case R600::PRED_SEL_OFF: 1475 break; 1476 1477 default: 1478 O << getRegisterName(Op.getReg()); 1479 break; 1480 } 1481 } else if (Op.isImm()) { 1482 O << Op.getImm(); 1483 } else if (Op.isFPImm()) { 1484 // We special case 0.0 because otherwise it will be printed as an integer. 1485 if (Op.getFPImm() == 0.0) 1486 O << "0.0"; 1487 else { 1488 O << Op.getFPImm(); 1489 } 1490 } else if (Op.isExpr()) { 1491 const MCExpr *Exp = Op.getExpr(); 1492 Exp->print(O, &MAI); 1493 } else { 1494 O << "/*INV_OP*/"; 1495 } 1496 } 1497 1498 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo, 1499 raw_ostream &O) { 1500 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+'); 1501 } 1502 1503 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 1504 raw_ostream &O) { 1505 unsigned Sel = MI->getOperand(OpNo).getImm(); 1506 switch (Sel) { 1507 case 0: 1508 O << 'X'; 1509 break; 1510 case 1: 1511 O << 'Y'; 1512 break; 1513 case 2: 1514 O << 'Z'; 1515 break; 1516 case 3: 1517 O << 'W'; 1518 break; 1519 case 4: 1520 O << '0'; 1521 break; 1522 case 5: 1523 O << '1'; 1524 break; 1525 case 7: 1526 O << '_'; 1527 break; 1528 default: 1529 break; 1530 } 1531 } 1532 1533 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 1534 raw_ostream &O) { 1535 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,"); 1536 } 1537 1538 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 1539 raw_ostream &O) { 1540 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,"); 1541 } 1542 1543 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 1544 raw_ostream &O) { 1545 const MCOperand &Op = MI->getOperand(OpNo); 1546 if (Op.getImm() == 0) { 1547 O << " (MASKED)"; 1548 } 1549 } 1550 1551 #include "R600GenAsmWriter.inc" 1552