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_ADD_CO_CI_U32_dpp_gfx10: 603 case AMDGPU::V_SUB_CO_CI_U32_dpp_gfx10: 604 case AMDGPU::V_SUBREV_CO_CI_U32_dpp_gfx10: 605 case AMDGPU::V_ADD_CO_CI_U32_dpp8_gfx10: 606 case AMDGPU::V_SUB_CO_CI_U32_dpp8_gfx10: 607 case AMDGPU::V_SUBREV_CO_CI_U32_dpp8_gfx10: 608 609 case AMDGPU::V_CNDMASK_B32_e32_gfx6_gfx7: 610 case AMDGPU::V_CNDMASK_B32_e32_vi: 611 if ((int)OpNo == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 612 AMDGPU::OpName::src1)) 613 printDefaultVccOperand(OpNo, STI, O); 614 break; 615 } 616 } 617 618 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 619 unsigned OpNo, 620 const MCSubtargetInfo &STI, 621 raw_ostream &O) { 622 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 623 624 // Use 'neg(...)' instead of '-' to avoid ambiguity. 625 // This is important for integer literals because 626 // -1 is not the same value as neg(1). 627 bool NegMnemo = false; 628 629 if (InputModifiers & SISrcMods::NEG) { 630 if (OpNo + 1 < MI->getNumOperands() && 631 (InputModifiers & SISrcMods::ABS) == 0) { 632 const MCOperand &Op = MI->getOperand(OpNo + 1); 633 NegMnemo = Op.isImm() || Op.isFPImm(); 634 } 635 if (NegMnemo) { 636 O << "neg("; 637 } else { 638 O << '-'; 639 } 640 } 641 642 if (InputModifiers & SISrcMods::ABS) 643 O << '|'; 644 printOperand(MI, OpNo + 1, STI, O); 645 if (InputModifiers & SISrcMods::ABS) 646 O << '|'; 647 648 if (NegMnemo) { 649 O << ')'; 650 } 651 } 652 653 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 654 unsigned OpNo, 655 const MCSubtargetInfo &STI, 656 raw_ostream &O) { 657 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 658 if (InputModifiers & SISrcMods::SEXT) 659 O << "sext("; 660 printOperand(MI, OpNo + 1, STI, O); 661 if (InputModifiers & SISrcMods::SEXT) 662 O << ')'; 663 664 // Print default vcc/vcc_lo operand of VOP2b. 665 switch (MI->getOpcode()) { 666 default: break; 667 668 case AMDGPU::V_ADD_CO_CI_U32_sdwa_gfx10: 669 case AMDGPU::V_SUB_CO_CI_U32_sdwa_gfx10: 670 case AMDGPU::V_SUBREV_CO_CI_U32_sdwa_gfx10: 671 if ((int)OpNo + 1 == AMDGPU::getNamedOperandIdx(MI->getOpcode(), 672 AMDGPU::OpName::src1)) 673 printDefaultVccOperand(OpNo, STI, O); 674 break; 675 } 676 } 677 678 void AMDGPUInstPrinter::printDPP8(const MCInst *MI, unsigned OpNo, 679 const MCSubtargetInfo &STI, 680 raw_ostream &O) { 681 if (!AMDGPU::isGFX10(STI)) 682 llvm_unreachable("dpp8 is not supported on ASICs earlier than GFX10"); 683 684 unsigned Imm = MI->getOperand(OpNo).getImm(); 685 O << " dpp8:[" << formatDec(Imm & 0x7); 686 for (size_t i = 1; i < 8; ++i) { 687 O << ',' << formatDec((Imm >> (3 * i)) & 0x7); 688 } 689 O << ']'; 690 } 691 692 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 693 const MCSubtargetInfo &STI, 694 raw_ostream &O) { 695 using namespace AMDGPU::DPP; 696 697 unsigned Imm = MI->getOperand(OpNo).getImm(); 698 if (Imm <= DppCtrl::QUAD_PERM_LAST) { 699 O << " quad_perm:["; 700 O << formatDec(Imm & 0x3) << ','; 701 O << formatDec((Imm & 0xc) >> 2) << ','; 702 O << formatDec((Imm & 0x30) >> 4) << ','; 703 O << formatDec((Imm & 0xc0) >> 6) << ']'; 704 } else if ((Imm >= DppCtrl::ROW_SHL_FIRST) && 705 (Imm <= DppCtrl::ROW_SHL_LAST)) { 706 O << " row_shl:"; 707 printU4ImmDecOperand(MI, OpNo, O); 708 } else if ((Imm >= DppCtrl::ROW_SHR_FIRST) && 709 (Imm <= DppCtrl::ROW_SHR_LAST)) { 710 O << " row_shr:"; 711 printU4ImmDecOperand(MI, OpNo, O); 712 } else if ((Imm >= DppCtrl::ROW_ROR_FIRST) && 713 (Imm <= DppCtrl::ROW_ROR_LAST)) { 714 O << " row_ror:"; 715 printU4ImmDecOperand(MI, OpNo, O); 716 } else if (Imm == DppCtrl::WAVE_SHL1) { 717 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 718 O << " /* wave_shl is not supported starting from GFX10 */"; 719 return; 720 } 721 O << " wave_shl:1"; 722 } else if (Imm == DppCtrl::WAVE_ROL1) { 723 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 724 O << " /* wave_rol is not supported starting from GFX10 */"; 725 return; 726 } 727 O << " wave_rol:1"; 728 } else if (Imm == DppCtrl::WAVE_SHR1) { 729 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 730 O << " /* wave_shr is not supported starting from GFX10 */"; 731 return; 732 } 733 O << " wave_shr:1"; 734 } else if (Imm == DppCtrl::WAVE_ROR1) { 735 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 736 O << " /* wave_ror is not supported starting from GFX10 */"; 737 return; 738 } 739 O << " wave_ror:1"; 740 } else if (Imm == DppCtrl::ROW_MIRROR) { 741 O << " row_mirror"; 742 } else if (Imm == DppCtrl::ROW_HALF_MIRROR) { 743 O << " row_half_mirror"; 744 } else if (Imm == DppCtrl::BCAST15) { 745 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 746 O << " /* row_bcast is not supported starting from GFX10 */"; 747 return; 748 } 749 O << " row_bcast:15"; 750 } else if (Imm == DppCtrl::BCAST31) { 751 if (!AMDGPU::isVI(STI) && !AMDGPU::isGFX9(STI)) { 752 O << " /* row_bcast is not supported starting from GFX10 */"; 753 return; 754 } 755 O << " row_bcast:31"; 756 } else if ((Imm >= DppCtrl::ROW_SHARE_FIRST) && 757 (Imm <= DppCtrl::ROW_SHARE_LAST)) { 758 if (!AMDGPU::isGFX10(STI)) { 759 O << " /* row_share is not supported on ASICs earlier than GFX10 */"; 760 return; 761 } 762 O << " row_share:"; 763 printU4ImmDecOperand(MI, OpNo, O); 764 } else if ((Imm >= DppCtrl::ROW_XMASK_FIRST) && 765 (Imm <= DppCtrl::ROW_XMASK_LAST)) { 766 if (!AMDGPU::isGFX10(STI)) { 767 O << " /* row_xmask is not supported on ASICs earlier than GFX10 */"; 768 return; 769 } 770 O << "row_xmask:"; 771 printU4ImmDecOperand(MI, OpNo, O); 772 } else { 773 O << " /* Invalid dpp_ctrl value */"; 774 } 775 } 776 777 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 778 const MCSubtargetInfo &STI, 779 raw_ostream &O) { 780 O << " row_mask:"; 781 printU4ImmOperand(MI, OpNo, STI, O); 782 } 783 784 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 785 const MCSubtargetInfo &STI, 786 raw_ostream &O) { 787 O << " bank_mask:"; 788 printU4ImmOperand(MI, OpNo, STI, O); 789 } 790 791 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 792 const MCSubtargetInfo &STI, 793 raw_ostream &O) { 794 unsigned Imm = MI->getOperand(OpNo).getImm(); 795 if (Imm) { 796 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 797 } 798 } 799 800 void AMDGPUInstPrinter::printFI(const MCInst *MI, unsigned OpNo, 801 const MCSubtargetInfo &STI, 802 raw_ostream &O) { 803 using namespace llvm::AMDGPU::DPP; 804 unsigned Imm = MI->getOperand(OpNo).getImm(); 805 if (Imm == DPP_FI_1 || Imm == DPP8_FI_1) { 806 O << " fi:1"; 807 } 808 } 809 810 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 811 raw_ostream &O) { 812 using namespace llvm::AMDGPU::SDWA; 813 814 unsigned Imm = MI->getOperand(OpNo).getImm(); 815 switch (Imm) { 816 case SdwaSel::BYTE_0: O << "BYTE_0"; break; 817 case SdwaSel::BYTE_1: O << "BYTE_1"; break; 818 case SdwaSel::BYTE_2: O << "BYTE_2"; break; 819 case SdwaSel::BYTE_3: O << "BYTE_3"; break; 820 case SdwaSel::WORD_0: O << "WORD_0"; break; 821 case SdwaSel::WORD_1: O << "WORD_1"; break; 822 case SdwaSel::DWORD: O << "DWORD"; break; 823 default: llvm_unreachable("Invalid SDWA data select operand"); 824 } 825 } 826 827 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 828 const MCSubtargetInfo &STI, 829 raw_ostream &O) { 830 O << "dst_sel:"; 831 printSDWASel(MI, OpNo, O); 832 } 833 834 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 835 const MCSubtargetInfo &STI, 836 raw_ostream &O) { 837 O << "src0_sel:"; 838 printSDWASel(MI, OpNo, O); 839 } 840 841 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 842 const MCSubtargetInfo &STI, 843 raw_ostream &O) { 844 O << "src1_sel:"; 845 printSDWASel(MI, OpNo, O); 846 } 847 848 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 849 const MCSubtargetInfo &STI, 850 raw_ostream &O) { 851 using namespace llvm::AMDGPU::SDWA; 852 853 O << "dst_unused:"; 854 unsigned Imm = MI->getOperand(OpNo).getImm(); 855 switch (Imm) { 856 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break; 857 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break; 858 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break; 859 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 860 } 861 } 862 863 template <unsigned N> 864 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo, 865 const MCSubtargetInfo &STI, 866 raw_ostream &O) { 867 unsigned Opc = MI->getOpcode(); 868 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en); 869 unsigned En = MI->getOperand(EnIdx).getImm(); 870 871 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr); 872 873 // If compr is set, print as src0, src0, src1, src1 874 if (MI->getOperand(ComprIdx).getImm()) { 875 if (N == 1 || N == 2) 876 --OpNo; 877 else if (N == 3) 878 OpNo -= 2; 879 } 880 881 if (En & (1 << N)) 882 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI); 883 else 884 O << "off"; 885 } 886 887 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo, 888 const MCSubtargetInfo &STI, 889 raw_ostream &O) { 890 printExpSrcN<0>(MI, OpNo, STI, O); 891 } 892 893 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo, 894 const MCSubtargetInfo &STI, 895 raw_ostream &O) { 896 printExpSrcN<1>(MI, OpNo, STI, O); 897 } 898 899 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo, 900 const MCSubtargetInfo &STI, 901 raw_ostream &O) { 902 printExpSrcN<2>(MI, OpNo, STI, O); 903 } 904 905 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo, 906 const MCSubtargetInfo &STI, 907 raw_ostream &O) { 908 printExpSrcN<3>(MI, OpNo, STI, O); 909 } 910 911 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo, 912 const MCSubtargetInfo &STI, 913 raw_ostream &O) { 914 // This is really a 6 bit field. 915 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1); 916 917 if (Tgt <= 7) 918 O << " mrt" << Tgt; 919 else if (Tgt == 8) 920 O << " mrtz"; 921 else if (Tgt == 9) 922 O << " null"; 923 else if ((Tgt >= 12 && Tgt <= 15) || (Tgt == 16 && AMDGPU::isGFX10(STI))) 924 O << " pos" << Tgt - 12; 925 else if (AMDGPU::isGFX10(STI) && Tgt == 20) 926 O << " prim"; 927 else if (Tgt >= 32 && Tgt <= 63) 928 O << " param" << Tgt - 32; 929 else { 930 // Reserved values 10, 11 931 O << " invalid_target_" << Tgt; 932 } 933 } 934 935 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod, 936 bool IsPacked, bool HasDstSel) { 937 int DefaultValue = IsPacked && (Mod == SISrcMods::OP_SEL_1); 938 939 for (int I = 0; I < NumOps; ++I) { 940 if (!!(Ops[I] & Mod) != DefaultValue) 941 return false; 942 } 943 944 if (HasDstSel && (Ops[0] & SISrcMods::DST_OP_SEL) != 0) 945 return false; 946 947 return true; 948 } 949 950 void AMDGPUInstPrinter::printPackedModifier(const MCInst *MI, 951 StringRef Name, 952 unsigned Mod, 953 raw_ostream &O) { 954 unsigned Opc = MI->getOpcode(); 955 int NumOps = 0; 956 int Ops[3]; 957 958 for (int OpName : { AMDGPU::OpName::src0_modifiers, 959 AMDGPU::OpName::src1_modifiers, 960 AMDGPU::OpName::src2_modifiers }) { 961 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName); 962 if (Idx == -1) 963 break; 964 965 Ops[NumOps++] = MI->getOperand(Idx).getImm(); 966 } 967 968 const bool HasDstSel = 969 NumOps > 0 && 970 Mod == SISrcMods::OP_SEL_0 && 971 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3_OPSEL; 972 973 const bool IsPacked = 974 MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::IsPacked; 975 976 if (allOpsDefaultValue(Ops, NumOps, Mod, IsPacked, HasDstSel)) 977 return; 978 979 O << Name; 980 for (int I = 0; I < NumOps; ++I) { 981 if (I != 0) 982 O << ','; 983 984 O << !!(Ops[I] & Mod); 985 } 986 987 if (HasDstSel) { 988 O << ',' << !!(Ops[0] & SISrcMods::DST_OP_SEL); 989 } 990 991 O << ']'; 992 } 993 994 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned, 995 const MCSubtargetInfo &STI, 996 raw_ostream &O) { 997 unsigned Opc = MI->getOpcode(); 998 if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 || 999 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) { 1000 auto FIN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers); 1001 auto BCN = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1_modifiers); 1002 unsigned FI = !!(MI->getOperand(FIN).getImm() & SISrcMods::OP_SEL_0); 1003 unsigned BC = !!(MI->getOperand(BCN).getImm() & SISrcMods::OP_SEL_0); 1004 if (FI || BC) 1005 O << " op_sel:[" << FI << ',' << BC << ']'; 1006 return; 1007 } 1008 1009 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O); 1010 } 1011 1012 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo, 1013 const MCSubtargetInfo &STI, 1014 raw_ostream &O) { 1015 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O); 1016 } 1017 1018 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo, 1019 const MCSubtargetInfo &STI, 1020 raw_ostream &O) { 1021 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O); 1022 } 1023 1024 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo, 1025 const MCSubtargetInfo &STI, 1026 raw_ostream &O) { 1027 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O); 1028 } 1029 1030 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 1031 const MCSubtargetInfo &STI, 1032 raw_ostream &O) { 1033 unsigned Imm = MI->getOperand(OpNum).getImm(); 1034 switch (Imm) { 1035 case 0: 1036 O << "p10"; 1037 break; 1038 case 1: 1039 O << "p20"; 1040 break; 1041 case 2: 1042 O << "p0"; 1043 break; 1044 default: 1045 O << "invalid_param_" << Imm; 1046 } 1047 } 1048 1049 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum, 1050 const MCSubtargetInfo &STI, 1051 raw_ostream &O) { 1052 unsigned Attr = MI->getOperand(OpNum).getImm(); 1053 O << "attr" << Attr; 1054 } 1055 1056 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum, 1057 const MCSubtargetInfo &STI, 1058 raw_ostream &O) { 1059 unsigned Chan = MI->getOperand(OpNum).getImm(); 1060 O << '.' << "xyzw"[Chan & 0x3]; 1061 } 1062 1063 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo, 1064 const MCSubtargetInfo &STI, 1065 raw_ostream &O) { 1066 using namespace llvm::AMDGPU::VGPRIndexMode; 1067 unsigned Val = MI->getOperand(OpNo).getImm(); 1068 1069 if ((Val & ~ENABLE_MASK) != 0) { 1070 O << " " << formatHex(static_cast<uint64_t>(Val)); 1071 } else { 1072 O << " gpr_idx("; 1073 bool NeedComma = false; 1074 for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) { 1075 if (Val & (1 << ModeId)) { 1076 if (NeedComma) 1077 O << ','; 1078 O << IdSymbolic[ModeId]; 1079 NeedComma = true; 1080 } 1081 } 1082 O << ')'; 1083 } 1084 } 1085 1086 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1087 const MCSubtargetInfo &STI, 1088 raw_ostream &O) { 1089 printOperand(MI, OpNo, STI, O); 1090 O << ", "; 1091 printOperand(MI, OpNo + 1, STI, O); 1092 } 1093 1094 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1095 raw_ostream &O, StringRef Asm, 1096 StringRef Default) { 1097 const MCOperand &Op = MI->getOperand(OpNo); 1098 assert(Op.isImm()); 1099 if (Op.getImm() == 1) { 1100 O << Asm; 1101 } else { 1102 O << Default; 1103 } 1104 } 1105 1106 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 1107 raw_ostream &O, char Asm) { 1108 const MCOperand &Op = MI->getOperand(OpNo); 1109 assert(Op.isImm()); 1110 if (Op.getImm() == 1) 1111 O << Asm; 1112 } 1113 1114 void AMDGPUInstPrinter::printHigh(const MCInst *MI, unsigned OpNo, 1115 const MCSubtargetInfo &STI, 1116 raw_ostream &O) { 1117 if (MI->getOperand(OpNo).getImm()) 1118 O << " high"; 1119 } 1120 1121 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 1122 const MCSubtargetInfo &STI, 1123 raw_ostream &O) { 1124 if (MI->getOperand(OpNo).getImm()) 1125 O << " clamp"; 1126 } 1127 1128 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 1129 const MCSubtargetInfo &STI, 1130 raw_ostream &O) { 1131 int Imm = MI->getOperand(OpNo).getImm(); 1132 if (Imm == SIOutMods::MUL2) 1133 O << " mul:2"; 1134 else if (Imm == SIOutMods::MUL4) 1135 O << " mul:4"; 1136 else if (Imm == SIOutMods::DIV2) 1137 O << " div:2"; 1138 } 1139 1140 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 1141 const MCSubtargetInfo &STI, 1142 raw_ostream &O) { 1143 using namespace llvm::AMDGPU::SendMsg; 1144 1145 const unsigned Imm16 = MI->getOperand(OpNo).getImm(); 1146 1147 uint16_t MsgId; 1148 uint16_t OpId; 1149 uint16_t StreamId; 1150 decodeMsg(Imm16, MsgId, OpId, StreamId); 1151 1152 if (isValidMsgId(MsgId, STI) && 1153 isValidMsgOp(MsgId, OpId) && 1154 isValidMsgStream(MsgId, OpId, StreamId)) { 1155 O << "sendmsg(" << getMsgName(MsgId); 1156 if (msgRequiresOp(MsgId)) { 1157 O << ", " << getMsgOpName(MsgId, OpId); 1158 if (msgSupportsStream(MsgId, OpId)) { 1159 O << ", " << StreamId; 1160 } 1161 } 1162 O << ')'; 1163 } else if (encodeMsg(MsgId, OpId, StreamId) == Imm16) { 1164 O << "sendmsg(" << MsgId << ", " << OpId << ", " << StreamId << ')'; 1165 } else { 1166 O << Imm16; // Unknown imm16 code. 1167 } 1168 } 1169 1170 static void printSwizzleBitmask(const uint16_t AndMask, 1171 const uint16_t OrMask, 1172 const uint16_t XorMask, 1173 raw_ostream &O) { 1174 using namespace llvm::AMDGPU::Swizzle; 1175 1176 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask; 1177 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask; 1178 1179 O << "\""; 1180 1181 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) { 1182 uint16_t p0 = Probe0 & Mask; 1183 uint16_t p1 = Probe1 & Mask; 1184 1185 if (p0 == p1) { 1186 if (p0 == 0) { 1187 O << "0"; 1188 } else { 1189 O << "1"; 1190 } 1191 } else { 1192 if (p0 == 0) { 1193 O << "p"; 1194 } else { 1195 O << "i"; 1196 } 1197 } 1198 } 1199 1200 O << "\""; 1201 } 1202 1203 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo, 1204 const MCSubtargetInfo &STI, 1205 raw_ostream &O) { 1206 using namespace llvm::AMDGPU::Swizzle; 1207 1208 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1209 if (Imm == 0) { 1210 return; 1211 } 1212 1213 O << " offset:"; 1214 1215 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) { 1216 1217 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM]; 1218 for (unsigned I = 0; I < LANE_NUM; ++I) { 1219 O << ","; 1220 O << formatDec(Imm & LANE_MASK); 1221 Imm >>= LANE_SHIFT; 1222 } 1223 O << ")"; 1224 1225 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) { 1226 1227 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK; 1228 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK; 1229 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK; 1230 1231 if (AndMask == BITMASK_MAX && 1232 OrMask == 0 && 1233 countPopulation(XorMask) == 1) { 1234 1235 O << "swizzle(" << IdSymbolic[ID_SWAP]; 1236 O << ","; 1237 O << formatDec(XorMask); 1238 O << ")"; 1239 1240 } else if (AndMask == BITMASK_MAX && 1241 OrMask == 0 && XorMask > 0 && 1242 isPowerOf2_64(XorMask + 1)) { 1243 1244 O << "swizzle(" << IdSymbolic[ID_REVERSE]; 1245 O << ","; 1246 O << formatDec(XorMask + 1); 1247 O << ")"; 1248 1249 } else { 1250 1251 uint16_t GroupSize = BITMASK_MAX - AndMask + 1; 1252 if (GroupSize > 1 && 1253 isPowerOf2_64(GroupSize) && 1254 OrMask < GroupSize && 1255 XorMask == 0) { 1256 1257 O << "swizzle(" << IdSymbolic[ID_BROADCAST]; 1258 O << ","; 1259 O << formatDec(GroupSize); 1260 O << ","; 1261 O << formatDec(OrMask); 1262 O << ")"; 1263 1264 } else { 1265 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM]; 1266 O << ","; 1267 printSwizzleBitmask(AndMask, OrMask, XorMask, O); 1268 O << ")"; 1269 } 1270 } 1271 } else { 1272 printU16ImmDecOperand(MI, OpNo, O); 1273 } 1274 } 1275 1276 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1277 const MCSubtargetInfo &STI, 1278 raw_ostream &O) { 1279 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(STI.getCPU()); 1280 1281 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1282 unsigned Vmcnt, Expcnt, Lgkmcnt; 1283 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1284 1285 bool NeedSpace = false; 1286 1287 if (Vmcnt != getVmcntBitMask(ISA)) { 1288 O << "vmcnt(" << Vmcnt << ')'; 1289 NeedSpace = true; 1290 } 1291 1292 if (Expcnt != getExpcntBitMask(ISA)) { 1293 if (NeedSpace) 1294 O << ' '; 1295 O << "expcnt(" << Expcnt << ')'; 1296 NeedSpace = true; 1297 } 1298 1299 if (Lgkmcnt != getLgkmcntBitMask(ISA)) { 1300 if (NeedSpace) 1301 O << ' '; 1302 O << "lgkmcnt(" << Lgkmcnt << ')'; 1303 } 1304 } 1305 1306 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1307 const MCSubtargetInfo &STI, raw_ostream &O) { 1308 unsigned Id; 1309 unsigned Offset; 1310 unsigned Width; 1311 1312 using namespace llvm::AMDGPU::Hwreg; 1313 unsigned Val = MI->getOperand(OpNo).getImm(); 1314 decodeHwreg(Val, Id, Offset, Width); 1315 StringRef HwRegName = getHwreg(Id, STI); 1316 1317 O << "hwreg("; 1318 if (!HwRegName.empty()) { 1319 O << HwRegName; 1320 } else { 1321 O << Id; 1322 } 1323 if (Width != WIDTH_DEFAULT_ || Offset != OFFSET_DEFAULT_) { 1324 O << ", " << Offset << ", " << Width; 1325 } 1326 O << ')'; 1327 } 1328 1329 void AMDGPUInstPrinter::printEndpgm(const MCInst *MI, unsigned OpNo, 1330 const MCSubtargetInfo &STI, 1331 raw_ostream &O) { 1332 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1333 if (Imm == 0) { 1334 return; 1335 } 1336 1337 O << ' ' << formatDec(Imm); 1338 } 1339 1340 #include "AMDGPUGenAsmWriter.inc" 1341 1342 void R600InstPrinter::printInst(const MCInst *MI, raw_ostream &O, 1343 StringRef Annot, const MCSubtargetInfo &STI) { 1344 O.flush(); 1345 printInstruction(MI, O); 1346 printAnnotation(O, Annot); 1347 } 1348 1349 void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 1350 raw_ostream &O) { 1351 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|'); 1352 } 1353 1354 void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 1355 raw_ostream &O) { 1356 int BankSwizzle = MI->getOperand(OpNo).getImm(); 1357 switch (BankSwizzle) { 1358 case 1: 1359 O << "BS:VEC_021/SCL_122"; 1360 break; 1361 case 2: 1362 O << "BS:VEC_120/SCL_212"; 1363 break; 1364 case 3: 1365 O << "BS:VEC_102/SCL_221"; 1366 break; 1367 case 4: 1368 O << "BS:VEC_201"; 1369 break; 1370 case 5: 1371 O << "BS:VEC_210"; 1372 break; 1373 default: 1374 break; 1375 } 1376 } 1377 1378 void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 1379 raw_ostream &O) { 1380 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT"); 1381 } 1382 1383 void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, 1384 raw_ostream &O) { 1385 unsigned CT = MI->getOperand(OpNo).getImm(); 1386 switch (CT) { 1387 case 0: 1388 O << 'U'; 1389 break; 1390 case 1: 1391 O << 'N'; 1392 break; 1393 default: 1394 break; 1395 } 1396 } 1397 1398 void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1399 raw_ostream &O) { 1400 int KCacheMode = MI->getOperand(OpNo).getImm(); 1401 if (KCacheMode > 0) { 1402 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1403 O << "CB" << KCacheBank << ':'; 1404 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1405 int LineSize = (KCacheMode == 1) ? 16 : 32; 1406 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1407 } 1408 } 1409 1410 void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo, 1411 raw_ostream &O) { 1412 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " "); 1413 } 1414 1415 void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 1416 raw_ostream &O) { 1417 const MCOperand &Op = MI->getOperand(OpNo); 1418 assert(Op.isImm() || Op.isExpr()); 1419 if (Op.isImm()) { 1420 int64_t Imm = Op.getImm(); 1421 O << Imm << '(' << BitsToFloat(Imm) << ')'; 1422 } 1423 if (Op.isExpr()) { 1424 Op.getExpr()->print(O << '@', &MAI); 1425 } 1426 } 1427 1428 void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 1429 raw_ostream &O) { 1430 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-'); 1431 } 1432 1433 void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 1434 raw_ostream &O) { 1435 switch (MI->getOperand(OpNo).getImm()) { 1436 default: break; 1437 case 1: 1438 O << " * 2.0"; 1439 break; 1440 case 2: 1441 O << " * 4.0"; 1442 break; 1443 case 3: 1444 O << " / 2.0"; 1445 break; 1446 } 1447 } 1448 1449 void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 1450 raw_ostream &O) { 1451 printOperand(MI, OpNo, O); 1452 O << ", "; 1453 printOperand(MI, OpNo + 1, O); 1454 } 1455 1456 void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 1457 raw_ostream &O) { 1458 if (OpNo >= MI->getNumOperands()) { 1459 O << "/*Missing OP" << OpNo << "*/"; 1460 return; 1461 } 1462 1463 const MCOperand &Op = MI->getOperand(OpNo); 1464 if (Op.isReg()) { 1465 switch (Op.getReg()) { 1466 // This is the default predicate state, so we don't need to print it. 1467 case R600::PRED_SEL_OFF: 1468 break; 1469 1470 default: 1471 O << getRegisterName(Op.getReg()); 1472 break; 1473 } 1474 } else if (Op.isImm()) { 1475 O << Op.getImm(); 1476 } else if (Op.isFPImm()) { 1477 // We special case 0.0 because otherwise it will be printed as an integer. 1478 if (Op.getFPImm() == 0.0) 1479 O << "0.0"; 1480 else { 1481 O << Op.getFPImm(); 1482 } 1483 } else if (Op.isExpr()) { 1484 const MCExpr *Exp = Op.getExpr(); 1485 Exp->print(O, &MAI); 1486 } else { 1487 O << "/*INV_OP*/"; 1488 } 1489 } 1490 1491 void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo, 1492 raw_ostream &O) { 1493 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+'); 1494 } 1495 1496 void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 1497 raw_ostream &O) { 1498 unsigned Sel = MI->getOperand(OpNo).getImm(); 1499 switch (Sel) { 1500 case 0: 1501 O << 'X'; 1502 break; 1503 case 1: 1504 O << 'Y'; 1505 break; 1506 case 2: 1507 O << 'Z'; 1508 break; 1509 case 3: 1510 O << 'W'; 1511 break; 1512 case 4: 1513 O << '0'; 1514 break; 1515 case 5: 1516 O << '1'; 1517 break; 1518 case 7: 1519 O << '_'; 1520 break; 1521 default: 1522 break; 1523 } 1524 } 1525 1526 void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 1527 raw_ostream &O) { 1528 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,"); 1529 } 1530 1531 void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 1532 raw_ostream &O) { 1533 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,"); 1534 } 1535 1536 void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 1537 raw_ostream &O) { 1538 const MCOperand &Op = MI->getOperand(OpNo); 1539 if (Op.getImm() == 0) { 1540 O << " (MASKED)"; 1541 } 1542 } 1543 1544 #include "R600GenAsmWriter.inc" 1545