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