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