1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 // \file 9 //===----------------------------------------------------------------------===// 10 11 #include "AMDGPUInstPrinter.h" 12 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 13 #include "SIDefines.h" 14 #include "Utils/AMDGPUAsmUtils.h" 15 #include "Utils/AMDGPUBaseInfo.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCInst.h" 18 #include "llvm/MC/MCInstrDesc.h" 19 #include "llvm/MC/MCInstrInfo.h" 20 #include "llvm/MC/MCRegisterInfo.h" 21 #include "llvm/MC/MCSubtargetInfo.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/MathExtras.h" 24 #include "llvm/Support/raw_ostream.h" 25 #include <cassert> 26 27 using namespace llvm; 28 using namespace llvm::AMDGPU; 29 30 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 31 StringRef Annot, const MCSubtargetInfo &STI) { 32 OS.flush(); 33 printInstruction(MI, STI, OS); 34 printAnnotation(OS, Annot); 35 } 36 37 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo, 38 const MCSubtargetInfo &STI, 39 raw_ostream &O) { 40 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf); 41 } 42 43 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo, 44 raw_ostream &O) { 45 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff); 46 } 47 48 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 49 const MCSubtargetInfo &STI, 50 raw_ostream &O) { 51 // It's possible to end up with a 32-bit literal used with a 16-bit operand 52 // with ignored high bits. Print as 32-bit anyway in that case. 53 int64_t Imm = MI->getOperand(OpNo).getImm(); 54 if (isInt<16>(Imm) || isUInt<16>(Imm)) 55 O << formatHex(static_cast<uint64_t>(Imm & 0xffff)); 56 else 57 printU32ImmOperand(MI, OpNo, STI, O); 58 } 59 60 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo, 61 raw_ostream &O) { 62 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf); 63 } 64 65 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo, 66 raw_ostream &O) { 67 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff); 68 } 69 70 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, 71 raw_ostream &O) { 72 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff); 73 } 74 75 void AMDGPUInstPrinter::printS16ImmDecOperand(const MCInst *MI, unsigned OpNo, 76 raw_ostream &O) { 77 O << formatDec(static_cast<int16_t>(MI->getOperand(OpNo).getImm())); 78 } 79 80 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo, 81 const MCSubtargetInfo &STI, 82 raw_ostream &O) { 83 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff); 84 } 85 86 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo, 87 raw_ostream &O, StringRef BitName) { 88 if (MI->getOperand(OpNo).getImm()) { 89 O << ' ' << BitName; 90 } 91 } 92 93 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo, 94 raw_ostream &O) { 95 printNamedBit(MI, OpNo, O, "offen"); 96 } 97 98 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo, 99 raw_ostream &O) { 100 printNamedBit(MI, OpNo, O, "idxen"); 101 } 102 103 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo, 104 raw_ostream &O) { 105 printNamedBit(MI, OpNo, O, "addr64"); 106 } 107 108 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo, 109 raw_ostream &O) { 110 if (MI->getOperand(OpNo).getImm()) { 111 O << " offset:"; 112 printU16ImmDecOperand(MI, OpNo, O); 113 } 114 } 115 116 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo, 117 const MCSubtargetInfo &STI, 118 raw_ostream &O) { 119 uint16_t Imm = MI->getOperand(OpNo).getImm(); 120 if (Imm != 0) { 121 O << ((OpNo == 0)? "offset:" : " offset:"); 122 printU16ImmDecOperand(MI, OpNo, O); 123 } 124 } 125 126 void AMDGPUInstPrinter::printOffsetS13(const MCInst *MI, unsigned OpNo, 127 const MCSubtargetInfo &STI, 128 raw_ostream &O) { 129 uint16_t Imm = MI->getOperand(OpNo).getImm(); 130 if (Imm != 0) { 131 O << ((OpNo == 0)? "offset:" : " offset:"); 132 printS16ImmDecOperand(MI, OpNo, O); 133 } 134 } 135 136 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo, 137 const MCSubtargetInfo &STI, 138 raw_ostream &O) { 139 if (MI->getOperand(OpNo).getImm()) { 140 O << " offset0:"; 141 printU8ImmDecOperand(MI, OpNo, O); 142 } 143 } 144 145 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo, 146 const MCSubtargetInfo &STI, 147 raw_ostream &O) { 148 if (MI->getOperand(OpNo).getImm()) { 149 O << " offset1:"; 150 printU8ImmDecOperand(MI, OpNo, O); 151 } 152 } 153 154 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo, 155 const MCSubtargetInfo &STI, 156 raw_ostream &O) { 157 printU32ImmOperand(MI, OpNo, STI, O); 158 } 159 160 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo, 161 const MCSubtargetInfo &STI, 162 raw_ostream &O) { 163 printU32ImmOperand(MI, OpNo, STI, O); 164 } 165 166 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo, 167 const MCSubtargetInfo &STI, 168 raw_ostream &O) { 169 printU32ImmOperand(MI, OpNo, STI, O); 170 } 171 172 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo, 173 const MCSubtargetInfo &STI, raw_ostream &O) { 174 printNamedBit(MI, OpNo, O, "gds"); 175 } 176 177 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo, 178 const MCSubtargetInfo &STI, raw_ostream &O) { 179 printNamedBit(MI, OpNo, O, "glc"); 180 } 181 182 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo, 183 const MCSubtargetInfo &STI, raw_ostream &O) { 184 printNamedBit(MI, OpNo, O, "slc"); 185 } 186 187 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo, 188 const MCSubtargetInfo &STI, raw_ostream &O) { 189 printNamedBit(MI, OpNo, O, "tfe"); 190 } 191 192 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo, 193 const MCSubtargetInfo &STI, raw_ostream &O) { 194 if (MI->getOperand(OpNo).getImm()) { 195 O << " dmask:"; 196 printU16ImmOperand(MI, OpNo, STI, O); 197 } 198 } 199 200 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo, 201 const MCSubtargetInfo &STI, raw_ostream &O) { 202 printNamedBit(MI, OpNo, O, "unorm"); 203 } 204 205 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo, 206 const MCSubtargetInfo &STI, raw_ostream &O) { 207 printNamedBit(MI, OpNo, O, "da"); 208 } 209 210 void AMDGPUInstPrinter::printR128(const MCInst *MI, unsigned OpNo, 211 const MCSubtargetInfo &STI, raw_ostream &O) { 212 printNamedBit(MI, OpNo, O, "r128"); 213 } 214 215 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo, 216 const MCSubtargetInfo &STI, raw_ostream &O) { 217 printNamedBit(MI, OpNo, O, "lwe"); 218 } 219 220 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo, 221 const MCSubtargetInfo &STI, 222 raw_ostream &O) { 223 if (MI->getOperand(OpNo).getImm()) 224 O << " compr"; 225 } 226 227 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo, 228 const MCSubtargetInfo &STI, 229 raw_ostream &O) { 230 if (MI->getOperand(OpNo).getImm()) 231 O << " vm"; 232 } 233 234 void AMDGPUInstPrinter::printDFMT(const MCInst *MI, unsigned OpNo, 235 const MCSubtargetInfo &STI, 236 raw_ostream &O) { 237 if (MI->getOperand(OpNo).getImm()) { 238 O << " dfmt:"; 239 printU8ImmDecOperand(MI, OpNo, O); 240 } 241 } 242 243 void AMDGPUInstPrinter::printNFMT(const MCInst *MI, unsigned OpNo, 244 const MCSubtargetInfo &STI, 245 raw_ostream &O) { 246 if (MI->getOperand(OpNo).getImm()) { 247 O << " nfmt:"; 248 printU8ImmDecOperand(MI, OpNo, O); 249 } 250 } 251 252 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O, 253 const MCRegisterInfo &MRI) { 254 switch (RegNo) { 255 case AMDGPU::VCC: 256 O << "vcc"; 257 return; 258 case AMDGPU::SCC: 259 O << "scc"; 260 return; 261 case AMDGPU::EXEC: 262 O << "exec"; 263 return; 264 case AMDGPU::M0: 265 O << "m0"; 266 return; 267 case AMDGPU::FLAT_SCR: 268 O << "flat_scratch"; 269 return; 270 case AMDGPU::VCC_LO: 271 O << "vcc_lo"; 272 return; 273 case AMDGPU::VCC_HI: 274 O << "vcc_hi"; 275 return; 276 case AMDGPU::TBA_LO: 277 O << "tba_lo"; 278 return; 279 case AMDGPU::TBA_HI: 280 O << "tba_hi"; 281 return; 282 case AMDGPU::TMA_LO: 283 O << "tma_lo"; 284 return; 285 case AMDGPU::TMA_HI: 286 O << "tma_hi"; 287 return; 288 case AMDGPU::EXEC_LO: 289 O << "exec_lo"; 290 return; 291 case AMDGPU::EXEC_HI: 292 O << "exec_hi"; 293 return; 294 case AMDGPU::FLAT_SCR_LO: 295 O << "flat_scratch_lo"; 296 return; 297 case AMDGPU::FLAT_SCR_HI: 298 O << "flat_scratch_hi"; 299 return; 300 default: 301 break; 302 } 303 304 // The low 8 bits of the encoding value is the register index, for both VGPRs 305 // and SGPRs. 306 unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1); 307 308 unsigned NumRegs; 309 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) { 310 O << 'v'; 311 NumRegs = 1; 312 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) { 313 O << 's'; 314 NumRegs = 1; 315 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) { 316 O <<'v'; 317 NumRegs = 2; 318 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) { 319 O << 's'; 320 NumRegs = 2; 321 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) { 322 O << 'v'; 323 NumRegs = 4; 324 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) { 325 O << 's'; 326 NumRegs = 4; 327 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) { 328 O << 'v'; 329 NumRegs = 3; 330 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) { 331 O << 'v'; 332 NumRegs = 8; 333 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(RegNo)) { 334 O << 's'; 335 NumRegs = 8; 336 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) { 337 O << 'v'; 338 NumRegs = 16; 339 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(RegNo)) { 340 O << 's'; 341 NumRegs = 16; 342 } else if (MRI.getRegClass(AMDGPU::TTMP_64RegClassID).contains(RegNo)) { 343 O << "ttmp"; 344 NumRegs = 2; 345 // Trap temps start at offset 112. TODO: Get this from tablegen. 346 RegIdx -= 112; 347 } else if (MRI.getRegClass(AMDGPU::TTMP_128RegClassID).contains(RegNo)) { 348 O << "ttmp"; 349 NumRegs = 4; 350 // Trap temps start at offset 112. TODO: Get this from tablegen. 351 RegIdx -= 112; 352 } else { 353 O << getRegisterName(RegNo); 354 return; 355 } 356 357 if (NumRegs == 1) { 358 O << RegIdx; 359 return; 360 } 361 362 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; 363 } 364 365 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, 366 const MCSubtargetInfo &STI, raw_ostream &O) { 367 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) 368 O << "_e64 "; 369 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) 370 O << "_dpp "; 371 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) 372 O << "_sdwa "; 373 else 374 O << "_e32 "; 375 376 printOperand(MI, OpNo, STI, O); 377 } 378 379 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm, 380 const MCSubtargetInfo &STI, 381 raw_ostream &O) { 382 int16_t SImm = static_cast<int16_t>(Imm); 383 if (SImm >= -16 && SImm <= 64) { 384 O << SImm; 385 return; 386 } 387 388 if (Imm == 0x3C00) 389 O<< "1.0"; 390 else if (Imm == 0xBC00) 391 O<< "-1.0"; 392 else if (Imm == 0x3800) 393 O<< "0.5"; 394 else if (Imm == 0xB800) 395 O<< "-0.5"; 396 else if (Imm == 0x4000) 397 O<< "2.0"; 398 else if (Imm == 0xC000) 399 O<< "-2.0"; 400 else if (Imm == 0x4400) 401 O<< "4.0"; 402 else if (Imm == 0xC400) 403 O<< "-4.0"; 404 else if (Imm == 0x3118) { 405 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]); 406 O << "0.15915494"; 407 } else 408 O << formatHex(static_cast<uint64_t>(Imm)); 409 } 410 411 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm, 412 const MCSubtargetInfo &STI, 413 raw_ostream &O) { 414 uint16_t Lo16 = static_cast<uint16_t>(Imm); 415 printImmediate16(Lo16, STI, O); 416 } 417 418 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, 419 const MCSubtargetInfo &STI, 420 raw_ostream &O) { 421 int32_t SImm = static_cast<int32_t>(Imm); 422 if (SImm >= -16 && SImm <= 64) { 423 O << SImm; 424 return; 425 } 426 427 if (Imm == FloatToBits(0.0f)) 428 O << "0.0"; 429 else if (Imm == FloatToBits(1.0f)) 430 O << "1.0"; 431 else if (Imm == FloatToBits(-1.0f)) 432 O << "-1.0"; 433 else if (Imm == FloatToBits(0.5f)) 434 O << "0.5"; 435 else if (Imm == FloatToBits(-0.5f)) 436 O << "-0.5"; 437 else if (Imm == FloatToBits(2.0f)) 438 O << "2.0"; 439 else if (Imm == FloatToBits(-2.0f)) 440 O << "-2.0"; 441 else if (Imm == FloatToBits(4.0f)) 442 O << "4.0"; 443 else if (Imm == FloatToBits(-4.0f)) 444 O << "-4.0"; 445 else if (Imm == 0x3e22f983 && 446 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 447 O << "0.15915494"; 448 else 449 O << formatHex(static_cast<uint64_t>(Imm)); 450 } 451 452 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, 453 const MCSubtargetInfo &STI, 454 raw_ostream &O) { 455 int64_t SImm = static_cast<int64_t>(Imm); 456 if (SImm >= -16 && SImm <= 64) { 457 O << SImm; 458 return; 459 } 460 461 if (Imm == DoubleToBits(0.0)) 462 O << "0.0"; 463 else if (Imm == DoubleToBits(1.0)) 464 O << "1.0"; 465 else if (Imm == DoubleToBits(-1.0)) 466 O << "-1.0"; 467 else if (Imm == DoubleToBits(0.5)) 468 O << "0.5"; 469 else if (Imm == DoubleToBits(-0.5)) 470 O << "-0.5"; 471 else if (Imm == DoubleToBits(2.0)) 472 O << "2.0"; 473 else if (Imm == DoubleToBits(-2.0)) 474 O << "-2.0"; 475 else if (Imm == DoubleToBits(4.0)) 476 O << "4.0"; 477 else if (Imm == DoubleToBits(-4.0)) 478 O << "-4.0"; 479 else if (Imm == 0x3fc45f306dc9c882 && 480 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 481 O << "0.15915494"; 482 else { 483 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882); 484 485 // In rare situations, we will have a 32-bit literal in a 64-bit 486 // operand. This is technically allowed for the encoding of s_mov_b64. 487 O << formatHex(static_cast<uint64_t>(Imm)); 488 } 489 } 490 491 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 492 const MCSubtargetInfo &STI, 493 raw_ostream &O) { 494 if (OpNo >= MI->getNumOperands()) { 495 O << "/*Missing OP" << OpNo << "*/"; 496 return; 497 } 498 499 const MCOperand &Op = MI->getOperand(OpNo); 500 if (Op.isReg()) { 501 switch (Op.getReg()) { 502 // This is the default predicate state, so we don't need to print it. 503 case AMDGPU::PRED_SEL_OFF: 504 break; 505 506 default: 507 printRegOperand(Op.getReg(), O, MRI); 508 break; 509 } 510 } else if (Op.isImm()) { 511 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 512 switch (Desc.OpInfo[OpNo].OperandType) { 513 case AMDGPU::OPERAND_REG_IMM_INT32: 514 case AMDGPU::OPERAND_REG_IMM_FP32: 515 case AMDGPU::OPERAND_REG_INLINE_C_INT32: 516 case AMDGPU::OPERAND_REG_INLINE_C_FP32: 517 case MCOI::OPERAND_IMMEDIATE: 518 printImmediate32(Op.getImm(), STI, O); 519 break; 520 case AMDGPU::OPERAND_REG_IMM_INT64: 521 case AMDGPU::OPERAND_REG_IMM_FP64: 522 case AMDGPU::OPERAND_REG_INLINE_C_INT64: 523 case AMDGPU::OPERAND_REG_INLINE_C_FP64: 524 printImmediate64(Op.getImm(), STI, O); 525 break; 526 case AMDGPU::OPERAND_REG_INLINE_C_INT16: 527 case AMDGPU::OPERAND_REG_INLINE_C_FP16: 528 case AMDGPU::OPERAND_REG_IMM_INT16: 529 case AMDGPU::OPERAND_REG_IMM_FP16: 530 printImmediate16(Op.getImm(), STI, O); 531 break; 532 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: 533 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: 534 printImmediateV216(Op.getImm(), STI, O); 535 break; 536 case MCOI::OPERAND_UNKNOWN: 537 case MCOI::OPERAND_PCREL: 538 O << formatDec(Op.getImm()); 539 break; 540 case MCOI::OPERAND_REGISTER: 541 // FIXME: This should be removed and handled somewhere else. Seems to come 542 // from a disassembler bug. 543 O << "/*invalid immediate*/"; 544 break; 545 default: 546 // We hit this for the immediate instruction bits that don't yet have a 547 // custom printer. 548 llvm_unreachable("unexpected immediate operand type"); 549 } 550 } else if (Op.isFPImm()) { 551 // We special case 0.0 because otherwise it will be printed as an integer. 552 if (Op.getFPImm() == 0.0) 553 O << "0.0"; 554 else { 555 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 556 int RCID = Desc.OpInfo[OpNo].RegClass; 557 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID)); 558 if (RCBits == 32) 559 printImmediate32(FloatToBits(Op.getFPImm()), STI, O); 560 else if (RCBits == 64) 561 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O); 562 else 563 llvm_unreachable("Invalid register class size"); 564 } 565 } else if (Op.isExpr()) { 566 const MCExpr *Exp = Op.getExpr(); 567 Exp->print(O, &MAI); 568 } else { 569 O << "/*INV_OP*/"; 570 } 571 } 572 573 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 574 unsigned OpNo, 575 const MCSubtargetInfo &STI, 576 raw_ostream &O) { 577 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 578 579 // Use 'neg(...)' instead of '-' to avoid ambiguity. 580 // This is important for integer literals because 581 // -1 is not the same value as neg(1). 582 bool NegMnemo = false; 583 584 if (InputModifiers & SISrcMods::NEG) { 585 if (OpNo + 1 < MI->getNumOperands() && 586 (InputModifiers & SISrcMods::ABS) == 0) { 587 const MCOperand &Op = MI->getOperand(OpNo + 1); 588 NegMnemo = Op.isImm() || Op.isFPImm(); 589 } 590 if (NegMnemo) { 591 O << "neg("; 592 } else { 593 O << '-'; 594 } 595 } 596 597 if (InputModifiers & SISrcMods::ABS) 598 O << '|'; 599 printOperand(MI, OpNo + 1, STI, O); 600 if (InputModifiers & SISrcMods::ABS) 601 O << '|'; 602 603 if (NegMnemo) { 604 O << ')'; 605 } 606 } 607 608 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 609 unsigned OpNo, 610 const MCSubtargetInfo &STI, 611 raw_ostream &O) { 612 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 613 if (InputModifiers & SISrcMods::SEXT) 614 O << "sext("; 615 printOperand(MI, OpNo + 1, STI, O); 616 if (InputModifiers & SISrcMods::SEXT) 617 O << ')'; 618 } 619 620 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 621 const MCSubtargetInfo &STI, 622 raw_ostream &O) { 623 unsigned Imm = MI->getOperand(OpNo).getImm(); 624 if (Imm <= 0x0ff) { 625 O << " quad_perm:["; 626 O << formatDec(Imm & 0x3) << ','; 627 O << formatDec((Imm & 0xc) >> 2) << ','; 628 O << formatDec((Imm & 0x30) >> 4) << ','; 629 O << formatDec((Imm & 0xc0) >> 6) << ']'; 630 } else if ((Imm >= 0x101) && (Imm <= 0x10f)) { 631 O << " row_shl:"; 632 printU4ImmDecOperand(MI, OpNo, O); 633 } else if ((Imm >= 0x111) && (Imm <= 0x11f)) { 634 O << " row_shr:"; 635 printU4ImmDecOperand(MI, OpNo, O); 636 } else if ((Imm >= 0x121) && (Imm <= 0x12f)) { 637 O << " row_ror:"; 638 printU4ImmDecOperand(MI, OpNo, O); 639 } else if (Imm == 0x130) { 640 O << " wave_shl:1"; 641 } else if (Imm == 0x134) { 642 O << " wave_rol:1"; 643 } else if (Imm == 0x138) { 644 O << " wave_shr:1"; 645 } else if (Imm == 0x13c) { 646 O << " wave_ror:1"; 647 } else if (Imm == 0x140) { 648 O << " row_mirror"; 649 } else if (Imm == 0x141) { 650 O << " row_half_mirror"; 651 } else if (Imm == 0x142) { 652 O << " row_bcast:15"; 653 } else if (Imm == 0x143) { 654 O << " row_bcast:31"; 655 } else { 656 llvm_unreachable("Invalid dpp_ctrl value"); 657 } 658 } 659 660 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 661 const MCSubtargetInfo &STI, 662 raw_ostream &O) { 663 O << " row_mask:"; 664 printU4ImmOperand(MI, OpNo, STI, O); 665 } 666 667 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 668 const MCSubtargetInfo &STI, 669 raw_ostream &O) { 670 O << " bank_mask:"; 671 printU4ImmOperand(MI, OpNo, STI, O); 672 } 673 674 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 675 const MCSubtargetInfo &STI, 676 raw_ostream &O) { 677 unsigned Imm = MI->getOperand(OpNo).getImm(); 678 if (Imm) { 679 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 680 } 681 } 682 683 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 684 raw_ostream &O) { 685 using namespace llvm::AMDGPU::SDWA; 686 687 unsigned Imm = MI->getOperand(OpNo).getImm(); 688 switch (Imm) { 689 case SdwaSel::BYTE_0: O << "BYTE_0"; break; 690 case SdwaSel::BYTE_1: O << "BYTE_1"; break; 691 case SdwaSel::BYTE_2: O << "BYTE_2"; break; 692 case SdwaSel::BYTE_3: O << "BYTE_3"; break; 693 case SdwaSel::WORD_0: O << "WORD_0"; break; 694 case SdwaSel::WORD_1: O << "WORD_1"; break; 695 case SdwaSel::DWORD: O << "DWORD"; break; 696 default: llvm_unreachable("Invalid SDWA data select operand"); 697 } 698 } 699 700 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 701 const MCSubtargetInfo &STI, 702 raw_ostream &O) { 703 O << "dst_sel:"; 704 printSDWASel(MI, OpNo, O); 705 } 706 707 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 708 const MCSubtargetInfo &STI, 709 raw_ostream &O) { 710 O << "src0_sel:"; 711 printSDWASel(MI, OpNo, O); 712 } 713 714 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 715 const MCSubtargetInfo &STI, 716 raw_ostream &O) { 717 O << "src1_sel:"; 718 printSDWASel(MI, OpNo, O); 719 } 720 721 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 722 const MCSubtargetInfo &STI, 723 raw_ostream &O) { 724 using namespace llvm::AMDGPU::SDWA; 725 726 O << "dst_unused:"; 727 unsigned Imm = MI->getOperand(OpNo).getImm(); 728 switch (Imm) { 729 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break; 730 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break; 731 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break; 732 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 733 } 734 } 735 736 template <unsigned N> 737 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo, 738 const MCSubtargetInfo &STI, 739 raw_ostream &O) { 740 unsigned Opc = MI->getOpcode(); 741 int EnIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::en); 742 unsigned En = MI->getOperand(EnIdx).getImm(); 743 744 int ComprIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::compr); 745 746 // If compr is set, print as src0, src0, src1, src1 747 if (MI->getOperand(ComprIdx).getImm()) { 748 if (N == 1 || N == 2) 749 --OpNo; 750 else if (N == 3) 751 OpNo -= 2; 752 } 753 754 if (En & (1 << N)) 755 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI); 756 else 757 O << "off"; 758 } 759 760 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo, 761 const MCSubtargetInfo &STI, 762 raw_ostream &O) { 763 printExpSrcN<0>(MI, OpNo, STI, O); 764 } 765 766 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo, 767 const MCSubtargetInfo &STI, 768 raw_ostream &O) { 769 printExpSrcN<1>(MI, OpNo, STI, O); 770 } 771 772 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo, 773 const MCSubtargetInfo &STI, 774 raw_ostream &O) { 775 printExpSrcN<2>(MI, OpNo, STI, O); 776 } 777 778 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo, 779 const MCSubtargetInfo &STI, 780 raw_ostream &O) { 781 printExpSrcN<3>(MI, OpNo, STI, O); 782 } 783 784 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo, 785 const MCSubtargetInfo &STI, 786 raw_ostream &O) { 787 // This is really a 6 bit field. 788 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1); 789 790 if (Tgt <= 7) 791 O << " mrt" << Tgt; 792 else if (Tgt == 8) 793 O << " mrtz"; 794 else if (Tgt == 9) 795 O << " null"; 796 else if (Tgt >= 12 && Tgt <= 15) 797 O << " pos" << Tgt - 12; 798 else if (Tgt >= 32 && Tgt <= 63) 799 O << " param" << Tgt - 32; 800 else { 801 // Reserved values 10, 11 802 O << " invalid_target_" << Tgt; 803 } 804 } 805 806 static bool allOpsDefaultValue(const int* Ops, int NumOps, int Mod) { 807 int DefaultValue = (Mod == SISrcMods::OP_SEL_1); 808 809 for (int I = 0; I < NumOps; ++I) { 810 if (!!(Ops[I] & Mod) != DefaultValue) 811 return false; 812 } 813 814 return true; 815 } 816 817 static void printPackedModifier(const MCInst *MI, StringRef Name, unsigned Mod, 818 raw_ostream &O) { 819 unsigned Opc = MI->getOpcode(); 820 int NumOps = 0; 821 int Ops[3]; 822 823 for (int OpName : { AMDGPU::OpName::src0_modifiers, 824 AMDGPU::OpName::src1_modifiers, 825 AMDGPU::OpName::src2_modifiers }) { 826 int Idx = AMDGPU::getNamedOperandIdx(Opc, OpName); 827 if (Idx == -1) 828 break; 829 830 Ops[NumOps++] = MI->getOperand(Idx).getImm(); 831 } 832 833 if (allOpsDefaultValue(Ops, NumOps, Mod)) 834 return; 835 836 O << Name; 837 for (int I = 0; I < NumOps; ++I) { 838 if (I != 0) 839 O << ','; 840 841 O << !!(Ops[I] & Mod); 842 } 843 844 O << ']'; 845 } 846 847 void AMDGPUInstPrinter::printOpSel(const MCInst *MI, unsigned, 848 const MCSubtargetInfo &STI, 849 raw_ostream &O) { 850 printPackedModifier(MI, " op_sel:[", SISrcMods::OP_SEL_0, O); 851 } 852 853 void AMDGPUInstPrinter::printOpSelHi(const MCInst *MI, unsigned OpNo, 854 const MCSubtargetInfo &STI, 855 raw_ostream &O) { 856 printPackedModifier(MI, " op_sel_hi:[", SISrcMods::OP_SEL_1, O); 857 } 858 859 void AMDGPUInstPrinter::printNegLo(const MCInst *MI, unsigned OpNo, 860 const MCSubtargetInfo &STI, 861 raw_ostream &O) { 862 printPackedModifier(MI, " neg_lo:[", SISrcMods::NEG, O); 863 } 864 865 void AMDGPUInstPrinter::printNegHi(const MCInst *MI, unsigned OpNo, 866 const MCSubtargetInfo &STI, 867 raw_ostream &O) { 868 printPackedModifier(MI, " neg_hi:[", SISrcMods::NEG_HI, O); 869 } 870 871 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 872 const MCSubtargetInfo &STI, 873 raw_ostream &O) { 874 unsigned Imm = MI->getOperand(OpNum).getImm(); 875 switch (Imm) { 876 case 0: 877 O << "p10"; 878 break; 879 case 1: 880 O << "p20"; 881 break; 882 case 2: 883 O << "p0"; 884 break; 885 default: 886 O << "invalid_param_" << Imm; 887 } 888 } 889 890 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum, 891 const MCSubtargetInfo &STI, 892 raw_ostream &O) { 893 unsigned Attr = MI->getOperand(OpNum).getImm(); 894 O << "attr" << Attr; 895 } 896 897 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum, 898 const MCSubtargetInfo &STI, 899 raw_ostream &O) { 900 unsigned Chan = MI->getOperand(OpNum).getImm(); 901 O << '.' << "xyzw"[Chan & 0x3]; 902 } 903 904 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo, 905 const MCSubtargetInfo &STI, 906 raw_ostream &O) { 907 unsigned Val = MI->getOperand(OpNo).getImm(); 908 if (Val == 0) { 909 O << " 0"; 910 return; 911 } 912 913 if (Val & VGPRIndexMode::DST_ENABLE) 914 O << " dst"; 915 916 if (Val & VGPRIndexMode::SRC0_ENABLE) 917 O << " src0"; 918 919 if (Val & VGPRIndexMode::SRC1_ENABLE) 920 O << " src1"; 921 922 if (Val & VGPRIndexMode::SRC2_ENABLE) 923 O << " src2"; 924 } 925 926 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 927 const MCSubtargetInfo &STI, 928 raw_ostream &O) { 929 printOperand(MI, OpNo, STI, O); 930 O << ", "; 931 printOperand(MI, OpNo + 1, STI, O); 932 } 933 934 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 935 raw_ostream &O, StringRef Asm, 936 StringRef Default) { 937 const MCOperand &Op = MI->getOperand(OpNo); 938 assert(Op.isImm()); 939 if (Op.getImm() == 1) { 940 O << Asm; 941 } else { 942 O << Default; 943 } 944 } 945 946 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 947 raw_ostream &O, char Asm) { 948 const MCOperand &Op = MI->getOperand(OpNo); 949 assert(Op.isImm()); 950 if (Op.getImm() == 1) 951 O << Asm; 952 } 953 954 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 955 const MCSubtargetInfo &STI, raw_ostream &O) { 956 printIfSet(MI, OpNo, O, '|'); 957 } 958 959 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 960 const MCSubtargetInfo &STI, raw_ostream &O) { 961 printIfSet(MI, OpNo, O, "_SAT"); 962 } 963 964 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 965 const MCSubtargetInfo &STI, 966 raw_ostream &O) { 967 if (MI->getOperand(OpNo).getImm()) 968 O << " clamp"; 969 } 970 971 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 972 const MCSubtargetInfo &STI, 973 raw_ostream &O) { 974 int Imm = MI->getOperand(OpNo).getImm(); 975 if (Imm == SIOutMods::MUL2) 976 O << " mul:2"; 977 else if (Imm == SIOutMods::MUL4) 978 O << " mul:4"; 979 else if (Imm == SIOutMods::DIV2) 980 O << " div:2"; 981 } 982 983 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 984 const MCSubtargetInfo &STI, 985 raw_ostream &O) { 986 const MCOperand &Op = MI->getOperand(OpNo); 987 assert(Op.isImm() || Op.isExpr()); 988 if (Op.isImm()) { 989 int64_t Imm = Op.getImm(); 990 O << Imm << '(' << BitsToFloat(Imm) << ')'; 991 } 992 if (Op.isExpr()) { 993 Op.getExpr()->print(O << '@', &MAI); 994 } 995 } 996 997 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, 998 const MCSubtargetInfo &STI, raw_ostream &O) { 999 printIfSet(MI, OpNo, O, "*", " "); 1000 } 1001 1002 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 1003 const MCSubtargetInfo &STI, raw_ostream &O) { 1004 printIfSet(MI, OpNo, O, '-'); 1005 } 1006 1007 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 1008 const MCSubtargetInfo &STI, raw_ostream &O) { 1009 switch (MI->getOperand(OpNo).getImm()) { 1010 default: break; 1011 case 1: 1012 O << " * 2.0"; 1013 break; 1014 case 2: 1015 O << " * 4.0"; 1016 break; 1017 case 3: 1018 O << " / 2.0"; 1019 break; 1020 } 1021 } 1022 1023 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo, 1024 const MCSubtargetInfo &STI, raw_ostream &O) { 1025 printIfSet(MI, OpNo, O, '+'); 1026 } 1027 1028 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 1029 const MCSubtargetInfo &STI, 1030 raw_ostream &O) { 1031 printIfSet(MI, OpNo, O, "ExecMask,"); 1032 } 1033 1034 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 1035 const MCSubtargetInfo &STI, 1036 raw_ostream &O) { 1037 printIfSet(MI, OpNo, O, "Pred,"); 1038 } 1039 1040 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 1041 const MCSubtargetInfo &STI, raw_ostream &O) { 1042 const MCOperand &Op = MI->getOperand(OpNo); 1043 if (Op.getImm() == 0) { 1044 O << " (MASKED)"; 1045 } 1046 } 1047 1048 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo, 1049 raw_ostream &O) { 1050 const char * chans = "XYZW"; 1051 int sel = MI->getOperand(OpNo).getImm(); 1052 1053 int chan = sel & 3; 1054 sel >>= 2; 1055 1056 if (sel >= 512) { 1057 sel -= 512; 1058 int cb = sel >> 12; 1059 sel &= 4095; 1060 O << cb << '[' << sel << ']'; 1061 } else if (sel >= 448) { 1062 sel -= 448; 1063 O << sel; 1064 } else if (sel >= 0){ 1065 O << sel; 1066 } 1067 1068 if (sel >= 0) 1069 O << '.' << chans[chan]; 1070 } 1071 1072 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 1073 const MCSubtargetInfo &STI, 1074 raw_ostream &O) { 1075 int BankSwizzle = MI->getOperand(OpNo).getImm(); 1076 switch (BankSwizzle) { 1077 case 1: 1078 O << "BS:VEC_021/SCL_122"; 1079 break; 1080 case 2: 1081 O << "BS:VEC_120/SCL_212"; 1082 break; 1083 case 3: 1084 O << "BS:VEC_102/SCL_221"; 1085 break; 1086 case 4: 1087 O << "BS:VEC_201"; 1088 break; 1089 case 5: 1090 O << "BS:VEC_210"; 1091 break; 1092 default: 1093 break; 1094 } 1095 } 1096 1097 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 1098 const MCSubtargetInfo &STI, raw_ostream &O) { 1099 unsigned Sel = MI->getOperand(OpNo).getImm(); 1100 switch (Sel) { 1101 case 0: 1102 O << 'X'; 1103 break; 1104 case 1: 1105 O << 'Y'; 1106 break; 1107 case 2: 1108 O << 'Z'; 1109 break; 1110 case 3: 1111 O << 'W'; 1112 break; 1113 case 4: 1114 O << '0'; 1115 break; 1116 case 5: 1117 O << '1'; 1118 break; 1119 case 7: 1120 O << '_'; 1121 break; 1122 default: 1123 break; 1124 } 1125 } 1126 1127 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, 1128 const MCSubtargetInfo &STI, raw_ostream &O) { 1129 unsigned CT = MI->getOperand(OpNo).getImm(); 1130 switch (CT) { 1131 case 0: 1132 O << 'U'; 1133 break; 1134 case 1: 1135 O << 'N'; 1136 break; 1137 default: 1138 break; 1139 } 1140 } 1141 1142 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1143 const MCSubtargetInfo &STI, raw_ostream &O) { 1144 int KCacheMode = MI->getOperand(OpNo).getImm(); 1145 if (KCacheMode > 0) { 1146 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1147 O << "CB" << KCacheBank << ':'; 1148 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1149 int LineSize = (KCacheMode == 1) ? 16 : 32; 1150 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1151 } 1152 } 1153 1154 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 1155 const MCSubtargetInfo &STI, 1156 raw_ostream &O) { 1157 using namespace llvm::AMDGPU::SendMsg; 1158 1159 const unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1160 const unsigned Id = SImm16 & ID_MASK_; 1161 do { 1162 if (Id == ID_INTERRUPT) { 1163 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0. 1164 break; 1165 O << "sendmsg(" << IdSymbolic[Id] << ')'; 1166 return; 1167 } 1168 if (Id == ID_GS || Id == ID_GS_DONE) { 1169 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0. 1170 break; 1171 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_; 1172 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 1173 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only. 1174 break; 1175 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits. 1176 break; 1177 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs]; 1178 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; } 1179 O << ')'; 1180 return; 1181 } 1182 if (Id == ID_SYSMSG) { 1183 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0. 1184 break; 1185 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_; 1186 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown. 1187 break; 1188 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')'; 1189 return; 1190 } 1191 } while (false); 1192 O << SImm16; // Unknown simm16 code. 1193 } 1194 1195 static void printSwizzleBitmask(const uint16_t AndMask, 1196 const uint16_t OrMask, 1197 const uint16_t XorMask, 1198 raw_ostream &O) { 1199 using namespace llvm::AMDGPU::Swizzle; 1200 1201 uint16_t Probe0 = ((0 & AndMask) | OrMask) ^ XorMask; 1202 uint16_t Probe1 = ((BITMASK_MASK & AndMask) | OrMask) ^ XorMask; 1203 1204 O << "\""; 1205 1206 for (unsigned Mask = 1 << (BITMASK_WIDTH - 1); Mask > 0; Mask >>= 1) { 1207 uint16_t p0 = Probe0 & Mask; 1208 uint16_t p1 = Probe1 & Mask; 1209 1210 if (p0 == p1) { 1211 if (p0 == 0) { 1212 O << "0"; 1213 } else { 1214 O << "1"; 1215 } 1216 } else { 1217 if (p0 == 0) { 1218 O << "p"; 1219 } else { 1220 O << "i"; 1221 } 1222 } 1223 } 1224 1225 O << "\""; 1226 } 1227 1228 void AMDGPUInstPrinter::printSwizzle(const MCInst *MI, unsigned OpNo, 1229 const MCSubtargetInfo &STI, 1230 raw_ostream &O) { 1231 using namespace llvm::AMDGPU::Swizzle; 1232 1233 uint16_t Imm = MI->getOperand(OpNo).getImm(); 1234 if (Imm == 0) { 1235 return; 1236 } 1237 1238 O << " offset:"; 1239 1240 if ((Imm & QUAD_PERM_ENC_MASK) == QUAD_PERM_ENC) { 1241 1242 O << "swizzle(" << IdSymbolic[ID_QUAD_PERM]; 1243 for (auto i = 0; i < LANE_NUM; ++i) { 1244 O << ","; 1245 O << formatDec(Imm & LANE_MASK); 1246 Imm >>= LANE_SHIFT; 1247 } 1248 O << ")"; 1249 1250 } else if ((Imm & BITMASK_PERM_ENC_MASK) == BITMASK_PERM_ENC) { 1251 1252 uint16_t AndMask = (Imm >> BITMASK_AND_SHIFT) & BITMASK_MASK; 1253 uint16_t OrMask = (Imm >> BITMASK_OR_SHIFT) & BITMASK_MASK; 1254 uint16_t XorMask = (Imm >> BITMASK_XOR_SHIFT) & BITMASK_MASK; 1255 1256 if (AndMask == BITMASK_MAX && 1257 OrMask == 0 && 1258 countPopulation(XorMask) == 1) { 1259 1260 O << "swizzle(" << IdSymbolic[ID_SWAP]; 1261 O << ","; 1262 O << formatDec(XorMask); 1263 O << ")"; 1264 1265 } else if (AndMask == BITMASK_MAX && 1266 OrMask == 0 && XorMask > 0 && 1267 isPowerOf2_64(XorMask + 1)) { 1268 1269 O << "swizzle(" << IdSymbolic[ID_REVERSE]; 1270 O << ","; 1271 O << formatDec(XorMask + 1); 1272 O << ")"; 1273 1274 } else { 1275 1276 uint16_t GroupSize = BITMASK_MAX - AndMask + 1; 1277 if (GroupSize > 1 && 1278 isPowerOf2_64(GroupSize) && 1279 OrMask < GroupSize && 1280 XorMask == 0) { 1281 1282 O << "swizzle(" << IdSymbolic[ID_BROADCAST]; 1283 O << ","; 1284 O << formatDec(GroupSize); 1285 O << ","; 1286 O << formatDec(OrMask); 1287 O << ")"; 1288 1289 } else { 1290 O << "swizzle(" << IdSymbolic[ID_BITMASK_PERM]; 1291 O << ","; 1292 printSwizzleBitmask(AndMask, OrMask, XorMask, O); 1293 O << ")"; 1294 } 1295 } 1296 } else { 1297 printU16ImmDecOperand(MI, OpNo, O); 1298 } 1299 } 1300 1301 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1302 const MCSubtargetInfo &STI, 1303 raw_ostream &O) { 1304 AMDGPU::IsaInfo::IsaVersion ISA = 1305 AMDGPU::IsaInfo::getIsaVersion(STI.getFeatureBits()); 1306 1307 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1308 unsigned Vmcnt, Expcnt, Lgkmcnt; 1309 decodeWaitcnt(ISA, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1310 1311 bool NeedSpace = false; 1312 1313 if (Vmcnt != getVmcntBitMask(ISA)) { 1314 O << "vmcnt(" << Vmcnt << ')'; 1315 NeedSpace = true; 1316 } 1317 1318 if (Expcnt != getExpcntBitMask(ISA)) { 1319 if (NeedSpace) 1320 O << ' '; 1321 O << "expcnt(" << Expcnt << ')'; 1322 NeedSpace = true; 1323 } 1324 1325 if (Lgkmcnt != getLgkmcntBitMask(ISA)) { 1326 if (NeedSpace) 1327 O << ' '; 1328 O << "lgkmcnt(" << Lgkmcnt << ')'; 1329 } 1330 } 1331 1332 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1333 const MCSubtargetInfo &STI, raw_ostream &O) { 1334 using namespace llvm::AMDGPU::Hwreg; 1335 1336 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1337 const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_; 1338 const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_; 1339 const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1; 1340 1341 O << "hwreg("; 1342 if (ID_SYMBOLIC_FIRST_ <= Id && Id < ID_SYMBOLIC_LAST_) { 1343 O << IdSymbolic[Id]; 1344 } else { 1345 O << Id; 1346 } 1347 if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) { 1348 O << ", " << Offset << ", " << Width; 1349 } 1350 O << ')'; 1351 } 1352 1353 #include "AMDGPUGenAsmWriter.inc" 1354