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