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