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