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 "SIDefines.h" 13 #include "MCTargetDesc/AMDGPUMCTargetDesc.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::printU32ImmOperand(const MCInst *MI, unsigned OpNo, 76 const MCSubtargetInfo &STI, 77 raw_ostream &O) { 78 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff); 79 } 80 81 void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo, 82 raw_ostream &O, StringRef BitName) { 83 if (MI->getOperand(OpNo).getImm()) { 84 O << ' ' << BitName; 85 } 86 } 87 88 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo, 89 raw_ostream &O) { 90 printNamedBit(MI, OpNo, O, "offen"); 91 } 92 93 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo, 94 raw_ostream &O) { 95 printNamedBit(MI, OpNo, O, "idxen"); 96 } 97 98 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo, 99 raw_ostream &O) { 100 printNamedBit(MI, OpNo, O, "addr64"); 101 } 102 103 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo, 104 raw_ostream &O) { 105 if (MI->getOperand(OpNo).getImm()) { 106 O << " offset:"; 107 printU16ImmDecOperand(MI, OpNo, O); 108 } 109 } 110 111 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo, 112 const MCSubtargetInfo &STI, 113 raw_ostream &O) { 114 uint16_t Imm = MI->getOperand(OpNo).getImm(); 115 if (Imm != 0) { 116 O << " offset:"; 117 printU16ImmDecOperand(MI, OpNo, O); 118 } 119 } 120 121 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo, 122 const MCSubtargetInfo &STI, 123 raw_ostream &O) { 124 if (MI->getOperand(OpNo).getImm()) { 125 O << " offset0:"; 126 printU8ImmDecOperand(MI, OpNo, O); 127 } 128 } 129 130 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo, 131 const MCSubtargetInfo &STI, 132 raw_ostream &O) { 133 if (MI->getOperand(OpNo).getImm()) { 134 O << " offset1:"; 135 printU8ImmDecOperand(MI, OpNo, O); 136 } 137 } 138 139 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo, 140 const MCSubtargetInfo &STI, 141 raw_ostream &O) { 142 printU32ImmOperand(MI, OpNo, STI, O); 143 } 144 145 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo, 146 const MCSubtargetInfo &STI, 147 raw_ostream &O) { 148 printU32ImmOperand(MI, OpNo, STI, O); 149 } 150 151 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo, 152 const MCSubtargetInfo &STI, 153 raw_ostream &O) { 154 printU32ImmOperand(MI, OpNo, STI, O); 155 } 156 157 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo, 158 const MCSubtargetInfo &STI, raw_ostream &O) { 159 printNamedBit(MI, OpNo, O, "gds"); 160 } 161 162 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo, 163 const MCSubtargetInfo &STI, raw_ostream &O) { 164 printNamedBit(MI, OpNo, O, "glc"); 165 } 166 167 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo, 168 const MCSubtargetInfo &STI, raw_ostream &O) { 169 printNamedBit(MI, OpNo, O, "slc"); 170 } 171 172 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo, 173 const MCSubtargetInfo &STI, raw_ostream &O) { 174 printNamedBit(MI, OpNo, O, "tfe"); 175 } 176 177 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo, 178 const MCSubtargetInfo &STI, raw_ostream &O) { 179 if (MI->getOperand(OpNo).getImm()) { 180 O << " dmask:"; 181 printU16ImmOperand(MI, OpNo, STI, O); 182 } 183 } 184 185 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo, 186 const MCSubtargetInfo &STI, raw_ostream &O) { 187 printNamedBit(MI, OpNo, O, "unorm"); 188 } 189 190 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo, 191 const MCSubtargetInfo &STI, raw_ostream &O) { 192 printNamedBit(MI, OpNo, O, "da"); 193 } 194 195 void AMDGPUInstPrinter::printR128(const MCInst *MI, unsigned OpNo, 196 const MCSubtargetInfo &STI, raw_ostream &O) { 197 printNamedBit(MI, OpNo, O, "r128"); 198 } 199 200 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo, 201 const MCSubtargetInfo &STI, raw_ostream &O) { 202 printNamedBit(MI, OpNo, O, "lwe"); 203 } 204 205 void AMDGPUInstPrinter::printExpCompr(const MCInst *MI, unsigned OpNo, 206 const MCSubtargetInfo &STI, 207 raw_ostream &O) { 208 if (MI->getOperand(OpNo).getImm()) 209 O << " compr"; 210 } 211 212 void AMDGPUInstPrinter::printExpVM(const MCInst *MI, unsigned OpNo, 213 const MCSubtargetInfo &STI, 214 raw_ostream &O) { 215 if (MI->getOperand(OpNo).getImm()) 216 O << " vm"; 217 } 218 219 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O, 220 const MCRegisterInfo &MRI) { 221 switch (RegNo) { 222 case AMDGPU::VCC: 223 O << "vcc"; 224 return; 225 case AMDGPU::SCC: 226 O << "scc"; 227 return; 228 case AMDGPU::EXEC: 229 O << "exec"; 230 return; 231 case AMDGPU::M0: 232 O << "m0"; 233 return; 234 case AMDGPU::FLAT_SCR: 235 O << "flat_scratch"; 236 return; 237 case AMDGPU::VCC_LO: 238 O << "vcc_lo"; 239 return; 240 case AMDGPU::VCC_HI: 241 O << "vcc_hi"; 242 return; 243 case AMDGPU::TBA_LO: 244 O << "tba_lo"; 245 return; 246 case AMDGPU::TBA_HI: 247 O << "tba_hi"; 248 return; 249 case AMDGPU::TMA_LO: 250 O << "tma_lo"; 251 return; 252 case AMDGPU::TMA_HI: 253 O << "tma_hi"; 254 return; 255 case AMDGPU::EXEC_LO: 256 O << "exec_lo"; 257 return; 258 case AMDGPU::EXEC_HI: 259 O << "exec_hi"; 260 return; 261 case AMDGPU::FLAT_SCR_LO: 262 O << "flat_scratch_lo"; 263 return; 264 case AMDGPU::FLAT_SCR_HI: 265 O << "flat_scratch_hi"; 266 return; 267 default: 268 break; 269 } 270 271 // The low 8 bits of the encoding value is the register index, for both VGPRs 272 // and SGPRs. 273 unsigned RegIdx = MRI.getEncodingValue(RegNo) & ((1 << 8) - 1); 274 275 unsigned NumRegs; 276 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(RegNo)) { 277 O << 'v'; 278 NumRegs = 1; 279 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(RegNo)) { 280 O << 's'; 281 NumRegs = 1; 282 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(RegNo)) { 283 O <<'v'; 284 NumRegs = 2; 285 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(RegNo)) { 286 O << 's'; 287 NumRegs = 2; 288 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(RegNo)) { 289 O << 'v'; 290 NumRegs = 4; 291 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(RegNo)) { 292 O << 's'; 293 NumRegs = 4; 294 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(RegNo)) { 295 O << 'v'; 296 NumRegs = 3; 297 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(RegNo)) { 298 O << 'v'; 299 NumRegs = 8; 300 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(RegNo)) { 301 O << 's'; 302 NumRegs = 8; 303 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(RegNo)) { 304 O << 'v'; 305 NumRegs = 16; 306 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(RegNo)) { 307 O << 's'; 308 NumRegs = 16; 309 } else if (MRI.getRegClass(AMDGPU::TTMP_64RegClassID).contains(RegNo)) { 310 O << "ttmp"; 311 NumRegs = 2; 312 // Trap temps start at offset 112. TODO: Get this from tablegen. 313 RegIdx -= 112; 314 } else if (MRI.getRegClass(AMDGPU::TTMP_128RegClassID).contains(RegNo)) { 315 O << "ttmp"; 316 NumRegs = 4; 317 // Trap temps start at offset 112. TODO: Get this from tablegen. 318 RegIdx -= 112; 319 } else { 320 O << getRegisterName(RegNo); 321 return; 322 } 323 324 if (NumRegs == 1) { 325 O << RegIdx; 326 return; 327 } 328 329 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; 330 } 331 332 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, 333 const MCSubtargetInfo &STI, raw_ostream &O) { 334 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) 335 O << "_e64 "; 336 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) 337 O << "_dpp "; 338 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) 339 O << "_sdwa "; 340 else 341 O << "_e32 "; 342 343 printOperand(MI, OpNo, STI, O); 344 } 345 346 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm, 347 const MCSubtargetInfo &STI, 348 raw_ostream &O) { 349 int16_t SImm = static_cast<int16_t>(Imm); 350 if (SImm >= -16 && SImm <= 64) { 351 O << SImm; 352 return; 353 } 354 355 if (Imm == 0x3C00) 356 O<< "1.0"; 357 else if (Imm == 0xBC00) 358 O<< "-1.0"; 359 else if (Imm == 0x3800) 360 O<< "0.5"; 361 else if (Imm == 0xB800) 362 O<< "-0.5"; 363 else if (Imm == 0x4000) 364 O<< "2.0"; 365 else if (Imm == 0xC000) 366 O<< "-2.0"; 367 else if (Imm == 0x4400) 368 O<< "4.0"; 369 else if (Imm == 0xC400) 370 O<< "-4.0"; 371 else if (Imm == 0x3118) { 372 assert(STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]); 373 O << "0.15915494"; 374 } else 375 O << formatHex(static_cast<uint64_t>(Imm)); 376 } 377 378 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, 379 const MCSubtargetInfo &STI, 380 raw_ostream &O) { 381 int32_t SImm = static_cast<int32_t>(Imm); 382 if (SImm >= -16 && SImm <= 64) { 383 O << SImm; 384 return; 385 } 386 387 if (Imm == FloatToBits(0.0f)) 388 O << "0.0"; 389 else if (Imm == FloatToBits(1.0f)) 390 O << "1.0"; 391 else if (Imm == FloatToBits(-1.0f)) 392 O << "-1.0"; 393 else if (Imm == FloatToBits(0.5f)) 394 O << "0.5"; 395 else if (Imm == FloatToBits(-0.5f)) 396 O << "-0.5"; 397 else if (Imm == FloatToBits(2.0f)) 398 O << "2.0"; 399 else if (Imm == FloatToBits(-2.0f)) 400 O << "-2.0"; 401 else if (Imm == FloatToBits(4.0f)) 402 O << "4.0"; 403 else if (Imm == FloatToBits(-4.0f)) 404 O << "-4.0"; 405 else if (Imm == 0x3e22f983 && 406 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 407 O << "0.15915494"; 408 else 409 O << formatHex(static_cast<uint64_t>(Imm)); 410 } 411 412 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, 413 const MCSubtargetInfo &STI, 414 raw_ostream &O) { 415 int64_t SImm = static_cast<int64_t>(Imm); 416 if (SImm >= -16 && SImm <= 64) { 417 O << SImm; 418 return; 419 } 420 421 if (Imm == DoubleToBits(0.0)) 422 O << "0.0"; 423 else if (Imm == DoubleToBits(1.0)) 424 O << "1.0"; 425 else if (Imm == DoubleToBits(-1.0)) 426 O << "-1.0"; 427 else if (Imm == DoubleToBits(0.5)) 428 O << "0.5"; 429 else if (Imm == DoubleToBits(-0.5)) 430 O << "-0.5"; 431 else if (Imm == DoubleToBits(2.0)) 432 O << "2.0"; 433 else if (Imm == DoubleToBits(-2.0)) 434 O << "-2.0"; 435 else if (Imm == DoubleToBits(4.0)) 436 O << "4.0"; 437 else if (Imm == DoubleToBits(-4.0)) 438 O << "-4.0"; 439 else if (Imm == 0x3fc45f306dc9c882 && 440 STI.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm]) 441 O << "0.15915494"; 442 else { 443 assert(isUInt<32>(Imm) || Imm == 0x3fc45f306dc9c882); 444 445 // In rare situations, we will have a 32-bit literal in a 64-bit 446 // operand. This is technically allowed for the encoding of s_mov_b64. 447 O << formatHex(static_cast<uint64_t>(Imm)); 448 } 449 } 450 451 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 452 const MCSubtargetInfo &STI, 453 raw_ostream &O) { 454 if (OpNo >= MI->getNumOperands()) { 455 O << "/*Missing OP" << OpNo << "*/"; 456 return; 457 } 458 459 const MCOperand &Op = MI->getOperand(OpNo); 460 if (Op.isReg()) { 461 switch (Op.getReg()) { 462 // This is the default predicate state, so we don't need to print it. 463 case AMDGPU::PRED_SEL_OFF: 464 break; 465 466 default: 467 printRegOperand(Op.getReg(), O, MRI); 468 break; 469 } 470 } else if (Op.isImm()) { 471 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 472 switch (Desc.OpInfo[OpNo].OperandType) { 473 case AMDGPU::OPERAND_REG_IMM_INT32: 474 case AMDGPU::OPERAND_REG_IMM_FP32: 475 case AMDGPU::OPERAND_REG_INLINE_C_INT32: 476 case AMDGPU::OPERAND_REG_INLINE_C_FP32: 477 case MCOI::OPERAND_IMMEDIATE: 478 printImmediate32(Op.getImm(), STI, O); 479 break; 480 case AMDGPU::OPERAND_REG_IMM_INT64: 481 case AMDGPU::OPERAND_REG_IMM_FP64: 482 case AMDGPU::OPERAND_REG_INLINE_C_INT64: 483 case AMDGPU::OPERAND_REG_INLINE_C_FP64: 484 printImmediate64(Op.getImm(), STI, O); 485 break; 486 case AMDGPU::OPERAND_REG_INLINE_C_INT16: 487 case AMDGPU::OPERAND_REG_INLINE_C_FP16: 488 case AMDGPU::OPERAND_REG_IMM_INT16: 489 case AMDGPU::OPERAND_REG_IMM_FP16: 490 printImmediate16(Op.getImm(), STI, O); 491 break; 492 case MCOI::OPERAND_UNKNOWN: 493 case MCOI::OPERAND_PCREL: 494 O << formatDec(Op.getImm()); 495 break; 496 case MCOI::OPERAND_REGISTER: 497 // FIXME: This should be removed and handled somewhere else. Seems to come 498 // from a disassembler bug. 499 O << "/*invalid immediate*/"; 500 break; 501 default: 502 // We hit this for the immediate instruction bits that don't yet have a 503 // custom printer. 504 llvm_unreachable("unexpected immediate operand type"); 505 } 506 } else if (Op.isFPImm()) { 507 // We special case 0.0 because otherwise it will be printed as an integer. 508 if (Op.getFPImm() == 0.0) 509 O << "0.0"; 510 else { 511 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 512 int RCID = Desc.OpInfo[OpNo].RegClass; 513 unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID)); 514 if (RCBits == 32) 515 printImmediate32(FloatToBits(Op.getFPImm()), STI, O); 516 else if (RCBits == 64) 517 printImmediate64(DoubleToBits(Op.getFPImm()), STI, O); 518 else 519 llvm_unreachable("Invalid register class size"); 520 } 521 } else if (Op.isExpr()) { 522 const MCExpr *Exp = Op.getExpr(); 523 Exp->print(O, &MAI); 524 } else { 525 O << "/*INV_OP*/"; 526 } 527 } 528 529 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 530 unsigned OpNo, 531 const MCSubtargetInfo &STI, 532 raw_ostream &O) { 533 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 534 if (InputModifiers & SISrcMods::NEG) 535 O << '-'; 536 if (InputModifiers & SISrcMods::ABS) 537 O << '|'; 538 printOperand(MI, OpNo + 1, STI, O); 539 if (InputModifiers & SISrcMods::ABS) 540 O << '|'; 541 } 542 543 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 544 unsigned OpNo, 545 const MCSubtargetInfo &STI, 546 raw_ostream &O) { 547 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 548 if (InputModifiers & SISrcMods::SEXT) 549 O << "sext("; 550 printOperand(MI, OpNo + 1, STI, O); 551 if (InputModifiers & SISrcMods::SEXT) 552 O << ')'; 553 } 554 555 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 556 const MCSubtargetInfo &STI, 557 raw_ostream &O) { 558 unsigned Imm = MI->getOperand(OpNo).getImm(); 559 if (Imm <= 0x0ff) { 560 O << " quad_perm:["; 561 O << formatDec(Imm & 0x3) << ','; 562 O << formatDec((Imm & 0xc) >> 2) << ','; 563 O << formatDec((Imm & 0x30) >> 4) << ','; 564 O << formatDec((Imm & 0xc0) >> 6) << ']'; 565 } else if ((Imm >= 0x101) && (Imm <= 0x10f)) { 566 O << " row_shl:"; 567 printU4ImmDecOperand(MI, OpNo, O); 568 } else if ((Imm >= 0x111) && (Imm <= 0x11f)) { 569 O << " row_shr:"; 570 printU4ImmDecOperand(MI, OpNo, O); 571 } else if ((Imm >= 0x121) && (Imm <= 0x12f)) { 572 O << " row_ror:"; 573 printU4ImmDecOperand(MI, OpNo, O); 574 } else if (Imm == 0x130) { 575 O << " wave_shl:1"; 576 } else if (Imm == 0x134) { 577 O << " wave_rol:1"; 578 } else if (Imm == 0x138) { 579 O << " wave_shr:1"; 580 } else if (Imm == 0x13c) { 581 O << " wave_ror:1"; 582 } else if (Imm == 0x140) { 583 O << " row_mirror"; 584 } else if (Imm == 0x141) { 585 O << " row_half_mirror"; 586 } else if (Imm == 0x142) { 587 O << " row_bcast:15"; 588 } else if (Imm == 0x143) { 589 O << " row_bcast:31"; 590 } else { 591 llvm_unreachable("Invalid dpp_ctrl value"); 592 } 593 } 594 595 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 596 const MCSubtargetInfo &STI, 597 raw_ostream &O) { 598 O << " row_mask:"; 599 printU4ImmOperand(MI, OpNo, STI, O); 600 } 601 602 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 603 const MCSubtargetInfo &STI, 604 raw_ostream &O) { 605 O << " bank_mask:"; 606 printU4ImmOperand(MI, OpNo, STI, O); 607 } 608 609 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 610 const MCSubtargetInfo &STI, 611 raw_ostream &O) { 612 unsigned Imm = MI->getOperand(OpNo).getImm(); 613 if (Imm) { 614 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 615 } 616 } 617 618 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 619 raw_ostream &O) { 620 using namespace llvm::AMDGPU::SDWA; 621 622 unsigned Imm = MI->getOperand(OpNo).getImm(); 623 switch (Imm) { 624 case SdwaSel::BYTE_0: O << "BYTE_0"; break; 625 case SdwaSel::BYTE_1: O << "BYTE_1"; break; 626 case SdwaSel::BYTE_2: O << "BYTE_2"; break; 627 case SdwaSel::BYTE_3: O << "BYTE_3"; break; 628 case SdwaSel::WORD_0: O << "WORD_0"; break; 629 case SdwaSel::WORD_1: O << "WORD_1"; break; 630 case SdwaSel::DWORD: O << "DWORD"; break; 631 default: llvm_unreachable("Invalid SDWA data select operand"); 632 } 633 } 634 635 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 636 const MCSubtargetInfo &STI, 637 raw_ostream &O) { 638 O << "dst_sel:"; 639 printSDWASel(MI, OpNo, O); 640 } 641 642 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 643 const MCSubtargetInfo &STI, 644 raw_ostream &O) { 645 O << "src0_sel:"; 646 printSDWASel(MI, OpNo, O); 647 } 648 649 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 650 const MCSubtargetInfo &STI, 651 raw_ostream &O) { 652 O << "src1_sel:"; 653 printSDWASel(MI, OpNo, O); 654 } 655 656 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 657 const MCSubtargetInfo &STI, 658 raw_ostream &O) { 659 using namespace llvm::AMDGPU::SDWA; 660 661 O << "dst_unused:"; 662 unsigned Imm = MI->getOperand(OpNo).getImm(); 663 switch (Imm) { 664 case DstUnused::UNUSED_PAD: O << "UNUSED_PAD"; break; 665 case DstUnused::UNUSED_SEXT: O << "UNUSED_SEXT"; break; 666 case DstUnused::UNUSED_PRESERVE: O << "UNUSED_PRESERVE"; break; 667 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 668 } 669 } 670 671 template <unsigned N> 672 void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo, 673 const MCSubtargetInfo &STI, 674 raw_ostream &O) { 675 int EnIdx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::en); 676 unsigned En = MI->getOperand(EnIdx).getImm(); 677 678 // FIXME: What do we do with compr? The meaning of en changes depending on if 679 // compr is set. 680 681 if (En & (1 << N)) 682 printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI); 683 else 684 O << "off"; 685 } 686 687 void AMDGPUInstPrinter::printExpSrc0(const MCInst *MI, unsigned OpNo, 688 const MCSubtargetInfo &STI, 689 raw_ostream &O) { 690 printExpSrcN<0>(MI, OpNo, STI, O); 691 } 692 693 void AMDGPUInstPrinter::printExpSrc1(const MCInst *MI, unsigned OpNo, 694 const MCSubtargetInfo &STI, 695 raw_ostream &O) { 696 printExpSrcN<1>(MI, OpNo, STI, O); 697 } 698 699 void AMDGPUInstPrinter::printExpSrc2(const MCInst *MI, unsigned OpNo, 700 const MCSubtargetInfo &STI, 701 raw_ostream &O) { 702 printExpSrcN<2>(MI, OpNo, STI, O); 703 } 704 705 void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo, 706 const MCSubtargetInfo &STI, 707 raw_ostream &O) { 708 printExpSrcN<3>(MI, OpNo, STI, O); 709 } 710 711 void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo, 712 const MCSubtargetInfo &STI, 713 raw_ostream &O) { 714 // This is really a 6 bit field. 715 uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1); 716 717 if (Tgt <= 7) 718 O << " mrt" << Tgt; 719 else if (Tgt == 8) 720 O << " mrtz"; 721 else if (Tgt == 9) 722 O << " null"; 723 else if (Tgt >= 12 && Tgt <= 15) 724 O << " pos" << Tgt - 12; 725 else if (Tgt >= 32 && Tgt <= 63) 726 O << " param" << Tgt - 32; 727 else { 728 // Reserved values 10, 11 729 O << " invalid_target_" << Tgt; 730 } 731 } 732 733 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 734 const MCSubtargetInfo &STI, 735 raw_ostream &O) { 736 unsigned Imm = MI->getOperand(OpNum).getImm(); 737 switch (Imm) { 738 case 0: 739 O << "p10"; 740 break; 741 case 1: 742 O << "p20"; 743 break; 744 case 2: 745 O << "p0"; 746 break; 747 default: 748 O << "invalid_param_" << Imm; 749 } 750 } 751 752 void AMDGPUInstPrinter::printInterpAttr(const MCInst *MI, unsigned OpNum, 753 const MCSubtargetInfo &STI, 754 raw_ostream &O) { 755 unsigned Attr = MI->getOperand(OpNum).getImm(); 756 O << "attr" << Attr; 757 } 758 759 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum, 760 const MCSubtargetInfo &STI, 761 raw_ostream &O) { 762 unsigned Chan = MI->getOperand(OpNum).getImm(); 763 O << '.' << "xyzw"[Chan & 0x3]; 764 } 765 766 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo, 767 const MCSubtargetInfo &STI, 768 raw_ostream &O) { 769 unsigned Val = MI->getOperand(OpNo).getImm(); 770 if (Val == 0) { 771 O << " 0"; 772 return; 773 } 774 775 if (Val & VGPRIndexMode::DST_ENABLE) 776 O << " dst"; 777 778 if (Val & VGPRIndexMode::SRC0_ENABLE) 779 O << " src0"; 780 781 if (Val & VGPRIndexMode::SRC1_ENABLE) 782 O << " src1"; 783 784 if (Val & VGPRIndexMode::SRC2_ENABLE) 785 O << " src2"; 786 } 787 788 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 789 const MCSubtargetInfo &STI, 790 raw_ostream &O) { 791 printOperand(MI, OpNo, STI, O); 792 O << ", "; 793 printOperand(MI, OpNo + 1, STI, O); 794 } 795 796 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 797 raw_ostream &O, StringRef Asm, 798 StringRef Default) { 799 const MCOperand &Op = MI->getOperand(OpNo); 800 assert(Op.isImm()); 801 if (Op.getImm() == 1) { 802 O << Asm; 803 } else { 804 O << Default; 805 } 806 } 807 808 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 809 raw_ostream &O, char Asm) { 810 const MCOperand &Op = MI->getOperand(OpNo); 811 assert(Op.isImm()); 812 if (Op.getImm() == 1) 813 O << Asm; 814 } 815 816 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 817 const MCSubtargetInfo &STI, raw_ostream &O) { 818 printIfSet(MI, OpNo, O, '|'); 819 } 820 821 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 822 const MCSubtargetInfo &STI, raw_ostream &O) { 823 printIfSet(MI, OpNo, O, "_SAT"); 824 } 825 826 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 827 const MCSubtargetInfo &STI, 828 raw_ostream &O) { 829 if (MI->getOperand(OpNo).getImm()) 830 O << " clamp"; 831 } 832 833 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 834 const MCSubtargetInfo &STI, 835 raw_ostream &O) { 836 int Imm = MI->getOperand(OpNo).getImm(); 837 if (Imm == SIOutMods::MUL2) 838 O << " mul:2"; 839 else if (Imm == SIOutMods::MUL4) 840 O << " mul:4"; 841 else if (Imm == SIOutMods::DIV2) 842 O << " div:2"; 843 } 844 845 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 846 const MCSubtargetInfo &STI, 847 raw_ostream &O) { 848 const MCOperand &Op = MI->getOperand(OpNo); 849 assert(Op.isImm() || Op.isExpr()); 850 if (Op.isImm()) { 851 int64_t Imm = Op.getImm(); 852 O << Imm << '(' << BitsToFloat(Imm) << ')'; 853 } 854 if (Op.isExpr()) { 855 Op.getExpr()->print(O << '@', &MAI); 856 } 857 } 858 859 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, 860 const MCSubtargetInfo &STI, raw_ostream &O) { 861 printIfSet(MI, OpNo, O, "*", " "); 862 } 863 864 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 865 const MCSubtargetInfo &STI, raw_ostream &O) { 866 printIfSet(MI, OpNo, O, '-'); 867 } 868 869 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 870 const MCSubtargetInfo &STI, raw_ostream &O) { 871 switch (MI->getOperand(OpNo).getImm()) { 872 default: break; 873 case 1: 874 O << " * 2.0"; 875 break; 876 case 2: 877 O << " * 4.0"; 878 break; 879 case 3: 880 O << " / 2.0"; 881 break; 882 } 883 } 884 885 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo, 886 const MCSubtargetInfo &STI, raw_ostream &O) { 887 printIfSet(MI, OpNo, O, '+'); 888 } 889 890 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 891 const MCSubtargetInfo &STI, 892 raw_ostream &O) { 893 printIfSet(MI, OpNo, O, "ExecMask,"); 894 } 895 896 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 897 const MCSubtargetInfo &STI, 898 raw_ostream &O) { 899 printIfSet(MI, OpNo, O, "Pred,"); 900 } 901 902 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 903 const MCSubtargetInfo &STI, raw_ostream &O) { 904 const MCOperand &Op = MI->getOperand(OpNo); 905 if (Op.getImm() == 0) { 906 O << " (MASKED)"; 907 } 908 } 909 910 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo, 911 raw_ostream &O) { 912 const char * chans = "XYZW"; 913 int sel = MI->getOperand(OpNo).getImm(); 914 915 int chan = sel & 3; 916 sel >>= 2; 917 918 if (sel >= 512) { 919 sel -= 512; 920 int cb = sel >> 12; 921 sel &= 4095; 922 O << cb << '[' << sel << ']'; 923 } else if (sel >= 448) { 924 sel -= 448; 925 O << sel; 926 } else if (sel >= 0){ 927 O << sel; 928 } 929 930 if (sel >= 0) 931 O << '.' << chans[chan]; 932 } 933 934 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 935 const MCSubtargetInfo &STI, 936 raw_ostream &O) { 937 int BankSwizzle = MI->getOperand(OpNo).getImm(); 938 switch (BankSwizzle) { 939 case 1: 940 O << "BS:VEC_021/SCL_122"; 941 break; 942 case 2: 943 O << "BS:VEC_120/SCL_212"; 944 break; 945 case 3: 946 O << "BS:VEC_102/SCL_221"; 947 break; 948 case 4: 949 O << "BS:VEC_201"; 950 break; 951 case 5: 952 O << "BS:VEC_210"; 953 break; 954 default: 955 break; 956 } 957 } 958 959 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 960 const MCSubtargetInfo &STI, raw_ostream &O) { 961 unsigned Sel = MI->getOperand(OpNo).getImm(); 962 switch (Sel) { 963 case 0: 964 O << 'X'; 965 break; 966 case 1: 967 O << 'Y'; 968 break; 969 case 2: 970 O << 'Z'; 971 break; 972 case 3: 973 O << 'W'; 974 break; 975 case 4: 976 O << '0'; 977 break; 978 case 5: 979 O << '1'; 980 break; 981 case 7: 982 O << '_'; 983 break; 984 default: 985 break; 986 } 987 } 988 989 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, 990 const MCSubtargetInfo &STI, raw_ostream &O) { 991 unsigned CT = MI->getOperand(OpNo).getImm(); 992 switch (CT) { 993 case 0: 994 O << 'U'; 995 break; 996 case 1: 997 O << 'N'; 998 break; 999 default: 1000 break; 1001 } 1002 } 1003 1004 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 1005 const MCSubtargetInfo &STI, raw_ostream &O) { 1006 int KCacheMode = MI->getOperand(OpNo).getImm(); 1007 if (KCacheMode > 0) { 1008 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 1009 O << "CB" << KCacheBank << ':'; 1010 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 1011 int LineSize = (KCacheMode == 1) ? 16 : 32; 1012 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 1013 } 1014 } 1015 1016 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 1017 const MCSubtargetInfo &STI, 1018 raw_ostream &O) { 1019 using namespace llvm::AMDGPU::SendMsg; 1020 1021 const unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1022 const unsigned Id = SImm16 & ID_MASK_; 1023 do { 1024 if (Id == ID_INTERRUPT) { 1025 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0. 1026 break; 1027 O << "sendmsg(" << IdSymbolic[Id] << ')'; 1028 return; 1029 } 1030 if (Id == ID_GS || Id == ID_GS_DONE) { 1031 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0. 1032 break; 1033 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_; 1034 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 1035 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only. 1036 break; 1037 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits. 1038 break; 1039 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs]; 1040 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; } 1041 O << ')'; 1042 return; 1043 } 1044 if (Id == ID_SYSMSG) { 1045 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0. 1046 break; 1047 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_; 1048 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown. 1049 break; 1050 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')'; 1051 return; 1052 } 1053 } while (false); 1054 O << SImm16; // Unknown simm16 code. 1055 } 1056 1057 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 1058 const MCSubtargetInfo &STI, 1059 raw_ostream &O) { 1060 IsaVersion IV = getIsaVersion(STI.getFeatureBits()); 1061 1062 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1063 unsigned Vmcnt, Expcnt, Lgkmcnt; 1064 decodeWaitcnt(IV, SImm16, Vmcnt, Expcnt, Lgkmcnt); 1065 1066 bool NeedSpace = false; 1067 1068 if (Vmcnt != getVmcntBitMask(IV)) { 1069 O << "vmcnt(" << Vmcnt << ')'; 1070 NeedSpace = true; 1071 } 1072 1073 if (Expcnt != getExpcntBitMask(IV)) { 1074 if (NeedSpace) 1075 O << ' '; 1076 O << "expcnt(" << Expcnt << ')'; 1077 NeedSpace = true; 1078 } 1079 1080 if (Lgkmcnt != getLgkmcntBitMask(IV)) { 1081 if (NeedSpace) 1082 O << ' '; 1083 O << "lgkmcnt(" << Lgkmcnt << ')'; 1084 } 1085 } 1086 1087 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 1088 const MCSubtargetInfo &STI, raw_ostream &O) { 1089 using namespace llvm::AMDGPU::Hwreg; 1090 1091 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 1092 const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_; 1093 const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_; 1094 const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1; 1095 1096 O << "hwreg("; 1097 if (ID_SYMBOLIC_FIRST_ <= Id && Id < ID_SYMBOLIC_LAST_) { 1098 O << IdSymbolic[Id]; 1099 } else { 1100 O << Id; 1101 } 1102 if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) { 1103 O << ", " << Offset << ", " << Width; 1104 } 1105 O << ')'; 1106 } 1107 1108 #include "AMDGPUGenAsmWriter.inc" 1109