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