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