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