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 "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCInst.h" 17 #include "llvm/MC/MCInstrInfo.h" 18 #include "llvm/MC/MCRegisterInfo.h" 19 #include "llvm/Support/MathExtras.h" 20 #include "llvm/Support/raw_ostream.h" 21 22 #include <string> 23 24 using namespace llvm; 25 26 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 27 StringRef Annot, const MCSubtargetInfo &STI) { 28 OS.flush(); 29 printInstruction(MI, OS); 30 31 printAnnotation(OS, Annot); 32 } 33 34 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo, 35 raw_ostream &O) { 36 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf); 37 } 38 39 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo, 40 raw_ostream &O) { 41 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff); 42 } 43 44 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, 45 raw_ostream &O) { 46 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffff); 47 } 48 49 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo, 50 raw_ostream &O) { 51 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff); 52 } 53 54 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo, 55 raw_ostream &O) { 56 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf); 57 } 58 59 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo, 60 raw_ostream &O) { 61 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff); 62 } 63 64 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, 65 raw_ostream &O) { 66 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff); 67 } 68 69 void AMDGPUInstPrinter::printNamedBit(const MCInst* MI, unsigned OpNo, 70 raw_ostream& O, StringRef BitName) { 71 if (MI->getOperand(OpNo).getImm()) { 72 O << ' ' << BitName; 73 } 74 } 75 76 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo, 77 raw_ostream &O) { 78 printNamedBit(MI, OpNo, O, "offen"); 79 } 80 81 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo, 82 raw_ostream &O) { 83 printNamedBit(MI, OpNo, O, "idxen"); 84 } 85 86 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo, 87 raw_ostream &O) { 88 printNamedBit(MI, OpNo, O, "addr64"); 89 } 90 91 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo, 92 raw_ostream &O) { 93 if (MI->getOperand(OpNo).getImm()) { 94 O << " offset:"; 95 printU16ImmDecOperand(MI, OpNo, O); 96 } 97 } 98 99 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo, 100 raw_ostream &O) { 101 uint16_t Imm = MI->getOperand(OpNo).getImm(); 102 if (Imm != 0) { 103 O << " offset:"; 104 printU16ImmDecOperand(MI, OpNo, O); 105 } 106 } 107 108 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo, 109 raw_ostream &O) { 110 if (MI->getOperand(OpNo).getImm()) { 111 O << " offset0:"; 112 printU8ImmDecOperand(MI, OpNo, O); 113 } 114 } 115 116 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo, 117 raw_ostream &O) { 118 if (MI->getOperand(OpNo).getImm()) { 119 O << " offset1:"; 120 printU8ImmDecOperand(MI, OpNo, O); 121 } 122 } 123 124 void AMDGPUInstPrinter::printSMRDOffset(const MCInst *MI, unsigned OpNo, 125 raw_ostream &O) { 126 printU32ImmOperand(MI, OpNo, O); 127 } 128 129 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo, 130 raw_ostream &O) { 131 printU32ImmOperand(MI, OpNo, O); 132 } 133 134 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo, 135 raw_ostream &O) { 136 printNamedBit(MI, OpNo, O, "gds"); 137 } 138 139 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo, 140 raw_ostream &O) { 141 printNamedBit(MI, OpNo, O, "glc"); 142 } 143 144 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo, 145 raw_ostream &O) { 146 printNamedBit(MI, OpNo, O, "slc"); 147 } 148 149 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo, 150 raw_ostream &O) { 151 printNamedBit(MI, OpNo, O, "tfe"); 152 } 153 154 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo, 155 raw_ostream &O) { 156 if (MI->getOperand(OpNo).getImm()) { 157 O << " dmask:"; 158 printU16ImmOperand(MI, OpNo, O); 159 } 160 } 161 162 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo, 163 raw_ostream &O) { 164 printNamedBit(MI, OpNo, O, "unorm"); 165 } 166 167 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo, 168 raw_ostream &O) { 169 printNamedBit(MI, OpNo, O, "da"); 170 } 171 172 void AMDGPUInstPrinter::printR128(const MCInst *MI, unsigned OpNo, 173 raw_ostream &O) { 174 printNamedBit(MI, OpNo, O, "r128"); 175 } 176 177 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo, 178 raw_ostream &O) { 179 printNamedBit(MI, OpNo, O, "lwe"); 180 } 181 182 void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O, 183 const MCRegisterInfo &MRI) { 184 switch (reg) { 185 case AMDGPU::VCC: 186 O << "vcc"; 187 return; 188 case AMDGPU::SCC: 189 O << "scc"; 190 return; 191 case AMDGPU::EXEC: 192 O << "exec"; 193 return; 194 case AMDGPU::M0: 195 O << "m0"; 196 return; 197 case AMDGPU::FLAT_SCR: 198 O << "flat_scratch"; 199 return; 200 case AMDGPU::VCC_LO: 201 O << "vcc_lo"; 202 return; 203 case AMDGPU::VCC_HI: 204 O << "vcc_hi"; 205 return; 206 case AMDGPU::TBA_LO: 207 O << "tba_lo"; 208 return; 209 case AMDGPU::TBA_HI: 210 O << "tba_hi"; 211 return; 212 case AMDGPU::TMA_LO: 213 O << "tma_lo"; 214 return; 215 case AMDGPU::TMA_HI: 216 O << "tma_hi"; 217 return; 218 case AMDGPU::EXEC_LO: 219 O << "exec_lo"; 220 return; 221 case AMDGPU::EXEC_HI: 222 O << "exec_hi"; 223 return; 224 case AMDGPU::FLAT_SCR_LO: 225 O << "flat_scratch_lo"; 226 return; 227 case AMDGPU::FLAT_SCR_HI: 228 O << "flat_scratch_hi"; 229 return; 230 default: 231 break; 232 } 233 234 // The low 8 bits of the encoding value is the register index, for both VGPRs 235 // and SGPRs. 236 unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1); 237 238 unsigned NumRegs; 239 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) { 240 O << 'v'; 241 NumRegs = 1; 242 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) { 243 O << 's'; 244 NumRegs = 1; 245 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) { 246 O <<'v'; 247 NumRegs = 2; 248 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(reg)) { 249 O << 's'; 250 NumRegs = 2; 251 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) { 252 O << 'v'; 253 NumRegs = 4; 254 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(reg)) { 255 O << 's'; 256 NumRegs = 4; 257 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) { 258 O << 'v'; 259 NumRegs = 3; 260 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) { 261 O << 'v'; 262 NumRegs = 8; 263 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) { 264 O << 's'; 265 NumRegs = 8; 266 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) { 267 O << 'v'; 268 NumRegs = 16; 269 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) { 270 O << 's'; 271 NumRegs = 16; 272 } else if (MRI.getRegClass(AMDGPU::TTMP_64RegClassID).contains(reg)) { 273 O << "ttmp"; 274 NumRegs = 2; 275 RegIdx -= 112; // Trap temps start at offset 112. TODO: Get this from tablegen. 276 } else if (MRI.getRegClass(AMDGPU::TTMP_128RegClassID).contains(reg)) { 277 O << "ttmp"; 278 NumRegs = 4; 279 RegIdx -= 112; // Trap temps start at offset 112. TODO: Get this from tablegen. 280 } else { 281 O << getRegisterName(reg); 282 return; 283 } 284 285 if (NumRegs == 1) { 286 O << RegIdx; 287 return; 288 } 289 290 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']'; 291 } 292 293 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, 294 raw_ostream &O) { 295 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) 296 O << "_e64 "; 297 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) 298 O << "_dpp "; 299 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) 300 O << "_sdwa "; 301 else 302 O << "_e32 "; 303 304 printOperand(MI, OpNo, O); 305 } 306 307 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, raw_ostream &O) { 308 int32_t SImm = static_cast<int32_t>(Imm); 309 if (SImm >= -16 && SImm <= 64) { 310 O << SImm; 311 return; 312 } 313 314 if (Imm == FloatToBits(0.0f)) 315 O << "0.0"; 316 else if (Imm == FloatToBits(1.0f)) 317 O << "1.0"; 318 else if (Imm == FloatToBits(-1.0f)) 319 O << "-1.0"; 320 else if (Imm == FloatToBits(0.5f)) 321 O << "0.5"; 322 else if (Imm == FloatToBits(-0.5f)) 323 O << "-0.5"; 324 else if (Imm == FloatToBits(2.0f)) 325 O << "2.0"; 326 else if (Imm == FloatToBits(-2.0f)) 327 O << "-2.0"; 328 else if (Imm == FloatToBits(4.0f)) 329 O << "4.0"; 330 else if (Imm == FloatToBits(-4.0f)) 331 O << "-4.0"; 332 else 333 O << formatHex(static_cast<uint64_t>(Imm)); 334 } 335 336 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) { 337 int64_t SImm = static_cast<int64_t>(Imm); 338 if (SImm >= -16 && SImm <= 64) { 339 O << SImm; 340 return; 341 } 342 343 if (Imm == DoubleToBits(0.0)) 344 O << "0.0"; 345 else if (Imm == DoubleToBits(1.0)) 346 O << "1.0"; 347 else if (Imm == DoubleToBits(-1.0)) 348 O << "-1.0"; 349 else if (Imm == DoubleToBits(0.5)) 350 O << "0.5"; 351 else if (Imm == DoubleToBits(-0.5)) 352 O << "-0.5"; 353 else if (Imm == DoubleToBits(2.0)) 354 O << "2.0"; 355 else if (Imm == DoubleToBits(-2.0)) 356 O << "-2.0"; 357 else if (Imm == DoubleToBits(4.0)) 358 O << "4.0"; 359 else if (Imm == DoubleToBits(-4.0)) 360 O << "-4.0"; 361 else { 362 assert(isUInt<32>(Imm)); 363 364 // In rare situations, we will have a 32-bit literal in a 64-bit 365 // operand. This is technically allowed for the encoding of s_mov_b64. 366 O << formatHex(static_cast<uint64_t>(Imm)); 367 } 368 } 369 370 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 371 raw_ostream &O) { 372 373 const MCOperand &Op = MI->getOperand(OpNo); 374 if (Op.isReg()) { 375 switch (Op.getReg()) { 376 // This is the default predicate state, so we don't need to print it. 377 case AMDGPU::PRED_SEL_OFF: 378 break; 379 380 default: 381 printRegOperand(Op.getReg(), O, MRI); 382 break; 383 } 384 } else if (Op.isImm()) { 385 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 386 int RCID = Desc.OpInfo[OpNo].RegClass; 387 if (RCID != -1) { 388 const MCRegisterClass &ImmRC = MRI.getRegClass(RCID); 389 if (ImmRC.getSize() == 4) 390 printImmediate32(Op.getImm(), O); 391 else if (ImmRC.getSize() == 8) 392 printImmediate64(Op.getImm(), O); 393 else 394 llvm_unreachable("Invalid register class size"); 395 } else if (Desc.OpInfo[OpNo].OperandType == MCOI::OPERAND_IMMEDIATE) { 396 printImmediate32(Op.getImm(), O); 397 } else { 398 // We hit this for the immediate instruction bits that don't yet have a 399 // custom printer. 400 // TODO: Eventually this should be unnecessary. 401 O << formatDec(Op.getImm()); 402 } 403 } else if (Op.isFPImm()) { 404 // We special case 0.0 because otherwise it will be printed as an integer. 405 if (Op.getFPImm() == 0.0) 406 O << "0.0"; 407 else { 408 const MCInstrDesc &Desc = MII.get(MI->getOpcode()); 409 const MCRegisterClass &ImmRC = MRI.getRegClass(Desc.OpInfo[OpNo].RegClass); 410 411 if (ImmRC.getSize() == 4) 412 printImmediate32(FloatToBits(Op.getFPImm()), O); 413 else if (ImmRC.getSize() == 8) 414 printImmediate64(DoubleToBits(Op.getFPImm()), O); 415 else 416 llvm_unreachable("Invalid register class size"); 417 } 418 } else if (Op.isExpr()) { 419 const MCExpr *Exp = Op.getExpr(); 420 Exp->print(O, &MAI); 421 } else { 422 O << "/*INV_OP*/"; 423 } 424 } 425 426 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI, 427 unsigned OpNo, 428 raw_ostream &O) { 429 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 430 if (InputModifiers & SISrcMods::NEG) 431 O << '-'; 432 if (InputModifiers & SISrcMods::ABS) 433 O << '|'; 434 printOperand(MI, OpNo + 1, O); 435 if (InputModifiers & SISrcMods::ABS) 436 O << '|'; 437 } 438 439 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI, 440 unsigned OpNo, 441 raw_ostream &O) { 442 unsigned InputModifiers = MI->getOperand(OpNo).getImm(); 443 if (InputModifiers & SISrcMods::SEXT) 444 O << "sext("; 445 printOperand(MI, OpNo + 1, O); 446 if (InputModifiers & SISrcMods::SEXT) 447 O << ')'; 448 } 449 450 451 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo, 452 raw_ostream &O) { 453 unsigned Imm = MI->getOperand(OpNo).getImm(); 454 if (Imm <= 0x0ff) { 455 O << " quad_perm:["; 456 O << formatDec(Imm & 0x3) << ','; 457 O << formatDec((Imm & 0xc) >> 2) << ','; 458 O << formatDec((Imm & 0x30) >> 4) << ','; 459 O << formatDec((Imm & 0xc0) >> 6) << ']'; 460 } else if ((Imm >= 0x101) && (Imm <= 0x10f)) { 461 O << " row_shl:"; 462 printU4ImmDecOperand(MI, OpNo, O); 463 } else if ((Imm >= 0x111) && (Imm <= 0x11f)) { 464 O << " row_shr:"; 465 printU4ImmDecOperand(MI, OpNo, O); 466 } else if ((Imm >= 0x121) && (Imm <= 0x12f)) { 467 O << " row_ror:"; 468 printU4ImmDecOperand(MI, OpNo, O); 469 } else if (Imm == 0x130) { 470 O << " wave_shl:1"; 471 } else if (Imm == 0x134) { 472 O << " wave_rol:1"; 473 } else if (Imm == 0x138) { 474 O << " wave_shr:1"; 475 } else if (Imm == 0x13c) { 476 O << " wave_ror:1"; 477 } else if (Imm == 0x140) { 478 O << " row_mirror"; 479 } else if (Imm == 0x141) { 480 O << " row_half_mirror"; 481 } else if (Imm == 0x142) { 482 O << " row_bcast:15"; 483 } else if (Imm == 0x143) { 484 O << " row_bcast:31"; 485 } else { 486 llvm_unreachable("Invalid dpp_ctrl value"); 487 } 488 } 489 490 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo, 491 raw_ostream &O) { 492 O << " row_mask:"; 493 printU4ImmOperand(MI, OpNo, O); 494 } 495 496 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo, 497 raw_ostream &O) { 498 O << " bank_mask:"; 499 printU4ImmOperand(MI, OpNo, O); 500 } 501 502 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo, 503 raw_ostream &O) { 504 unsigned Imm = MI->getOperand(OpNo).getImm(); 505 if (Imm) { 506 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3 507 } 508 } 509 510 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo, 511 raw_ostream &O) { 512 unsigned Imm = MI->getOperand(OpNo).getImm(); 513 switch (Imm) { 514 case 0: O << "BYTE_0"; break; 515 case 1: O << "BYTE_1"; break; 516 case 2: O << "BYTE_2"; break; 517 case 3: O << "BYTE_3"; break; 518 case 4: O << "WORD_0"; break; 519 case 5: O << "WORD_1"; break; 520 case 6: O << "DWORD"; break; 521 default: llvm_unreachable("Invalid SDWA data select operand"); 522 } 523 } 524 525 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo, 526 raw_ostream &O) { 527 O << "dst_sel:"; 528 printSDWASel(MI, OpNo, O); 529 } 530 531 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo, 532 raw_ostream &O) { 533 O << "src0_sel:"; 534 printSDWASel(MI, OpNo, O); 535 } 536 537 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo, 538 raw_ostream &O) { 539 O << "src1_sel:"; 540 printSDWASel(MI, OpNo, O); 541 } 542 543 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo, 544 raw_ostream &O) { 545 O << "dst_unused:"; 546 unsigned Imm = MI->getOperand(OpNo).getImm(); 547 switch (Imm) { 548 case 0: O << "UNUSED_PAD"; break; 549 case 1: O << "UNUSED_SEXT"; break; 550 case 2: O << "UNUSED_PRESERVE"; break; 551 default: llvm_unreachable("Invalid SDWA dest_unused operand"); 552 } 553 } 554 555 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 556 raw_ostream &O) { 557 unsigned Imm = MI->getOperand(OpNum).getImm(); 558 559 if (Imm == 2) { 560 O << "P0"; 561 } else if (Imm == 1) { 562 O << "P20"; 563 } else if (Imm == 0) { 564 O << "P10"; 565 } else { 566 llvm_unreachable("Invalid interpolation parameter slot"); 567 } 568 } 569 570 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 571 raw_ostream &O) { 572 printOperand(MI, OpNo, O); 573 O << ", "; 574 printOperand(MI, OpNo + 1, O); 575 } 576 577 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 578 raw_ostream &O, StringRef Asm, 579 StringRef Default) { 580 const MCOperand &Op = MI->getOperand(OpNo); 581 assert(Op.isImm()); 582 if (Op.getImm() == 1) { 583 O << Asm; 584 } else { 585 O << Default; 586 } 587 } 588 589 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 590 raw_ostream &O, char Asm) { 591 const MCOperand &Op = MI->getOperand(OpNo); 592 assert(Op.isImm()); 593 if (Op.getImm() == 1) 594 O << Asm; 595 } 596 597 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 598 raw_ostream &O) { 599 printIfSet(MI, OpNo, O, '|'); 600 } 601 602 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 603 raw_ostream &O) { 604 printIfSet(MI, OpNo, O, "_SAT"); 605 } 606 607 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo, 608 raw_ostream &O) { 609 if (MI->getOperand(OpNo).getImm()) 610 O << " clamp"; 611 } 612 613 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo, 614 raw_ostream &O) { 615 int Imm = MI->getOperand(OpNo).getImm(); 616 if (Imm == SIOutMods::MUL2) 617 O << " mul:2"; 618 else if (Imm == SIOutMods::MUL4) 619 O << " mul:4"; 620 else if (Imm == SIOutMods::DIV2) 621 O << " div:2"; 622 } 623 624 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 625 raw_ostream &O) { 626 const MCOperand &Op = MI->getOperand(OpNo); 627 assert(Op.isImm() || Op.isExpr()); 628 if (Op.isImm()) { 629 int64_t Imm = Op.getImm(); 630 O << Imm << '(' << BitsToFloat(Imm) << ')'; 631 } 632 if (Op.isExpr()) { 633 Op.getExpr()->print(O << '@', &MAI); 634 } 635 } 636 637 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, 638 raw_ostream &O) { 639 printIfSet(MI, OpNo, O, "*", " "); 640 } 641 642 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 643 raw_ostream &O) { 644 printIfSet(MI, OpNo, O, '-'); 645 } 646 647 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 648 raw_ostream &O) { 649 switch (MI->getOperand(OpNo).getImm()) { 650 default: break; 651 case 1: 652 O << " * 2.0"; 653 break; 654 case 2: 655 O << " * 4.0"; 656 break; 657 case 3: 658 O << " / 2.0"; 659 break; 660 } 661 } 662 663 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo, 664 raw_ostream &O) { 665 printIfSet(MI, OpNo, O, '+'); 666 } 667 668 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 669 raw_ostream &O) { 670 printIfSet(MI, OpNo, O, "ExecMask,"); 671 } 672 673 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 674 raw_ostream &O) { 675 printIfSet(MI, OpNo, O, "Pred,"); 676 } 677 678 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 679 raw_ostream &O) { 680 const MCOperand &Op = MI->getOperand(OpNo); 681 if (Op.getImm() == 0) { 682 O << " (MASKED)"; 683 } 684 } 685 686 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo, 687 raw_ostream &O) { 688 const char * chans = "XYZW"; 689 int sel = MI->getOperand(OpNo).getImm(); 690 691 int chan = sel & 3; 692 sel >>= 2; 693 694 if (sel >= 512) { 695 sel -= 512; 696 int cb = sel >> 12; 697 sel &= 4095; 698 O << cb << '[' << sel << ']'; 699 } else if (sel >= 448) { 700 sel -= 448; 701 O << sel; 702 } else if (sel >= 0){ 703 O << sel; 704 } 705 706 if (sel >= 0) 707 O << '.' << chans[chan]; 708 } 709 710 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 711 raw_ostream &O) { 712 int BankSwizzle = MI->getOperand(OpNo).getImm(); 713 switch (BankSwizzle) { 714 case 1: 715 O << "BS:VEC_021/SCL_122"; 716 break; 717 case 2: 718 O << "BS:VEC_120/SCL_212"; 719 break; 720 case 3: 721 O << "BS:VEC_102/SCL_221"; 722 break; 723 case 4: 724 O << "BS:VEC_201"; 725 break; 726 case 5: 727 O << "BS:VEC_210"; 728 break; 729 default: 730 break; 731 } 732 return; 733 } 734 735 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 736 raw_ostream &O) { 737 unsigned Sel = MI->getOperand(OpNo).getImm(); 738 switch (Sel) { 739 case 0: 740 O << 'X'; 741 break; 742 case 1: 743 O << 'Y'; 744 break; 745 case 2: 746 O << 'Z'; 747 break; 748 case 3: 749 O << 'W'; 750 break; 751 case 4: 752 O << '0'; 753 break; 754 case 5: 755 O << '1'; 756 break; 757 case 7: 758 O << '_'; 759 break; 760 default: 761 break; 762 } 763 } 764 765 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, 766 raw_ostream &O) { 767 unsigned CT = MI->getOperand(OpNo).getImm(); 768 switch (CT) { 769 case 0: 770 O << 'U'; 771 break; 772 case 1: 773 O << 'N'; 774 break; 775 default: 776 break; 777 } 778 } 779 780 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 781 raw_ostream &O) { 782 int KCacheMode = MI->getOperand(OpNo).getImm(); 783 if (KCacheMode > 0) { 784 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 785 O << "CB" << KCacheBank << ':'; 786 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 787 int LineSize = (KCacheMode == 1) ? 16 : 32; 788 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 789 } 790 } 791 792 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo, 793 raw_ostream &O) { 794 using namespace llvm::AMDGPU::SendMsg; 795 796 const unsigned SImm16 = MI->getOperand(OpNo).getImm(); 797 const unsigned Id = SImm16 & ID_MASK_; 798 do { 799 if (Id == ID_INTERRUPT) { 800 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0. 801 break; 802 O << "sendmsg(" << IdSymbolic[Id] << ')'; 803 return; 804 } 805 if (Id == ID_GS || Id == ID_GS_DONE) { 806 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0. 807 break; 808 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_; 809 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_; 810 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only. 811 break; 812 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits. 813 break; 814 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs]; 815 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; } 816 O << ')'; 817 return; 818 } 819 if (Id == ID_SYSMSG) { 820 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0. 821 break; 822 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_; 823 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown. 824 break; 825 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')'; 826 return; 827 } 828 } while (0); 829 O << SImm16; // Unknown simm16 code. 830 } 831 832 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 833 raw_ostream &O) { 834 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 835 unsigned Vmcnt = SImm16 & 0xF; 836 unsigned Expcnt = (SImm16 >> 4) & 0x7; 837 unsigned Lgkmcnt = (SImm16 >> 8) & 0xF; 838 839 bool NeedSpace = false; 840 841 if (Vmcnt != 0xF) { 842 O << "vmcnt(" << Vmcnt << ')'; 843 NeedSpace = true; 844 } 845 846 if (Expcnt != 0x7) { 847 if (NeedSpace) 848 O << ' '; 849 O << "expcnt(" << Expcnt << ')'; 850 NeedSpace = true; 851 } 852 853 if (Lgkmcnt != 0xF) { 854 if (NeedSpace) 855 O << ' '; 856 O << "lgkmcnt(" << Lgkmcnt << ')'; 857 } 858 } 859 860 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo, 861 raw_ostream &O) { 862 using namespace llvm::AMDGPU::Hwreg; 863 864 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 865 const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_; 866 const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_; 867 const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1; 868 869 O << "hwreg("; 870 if (ID_SYMBOLIC_FIRST_ <= Id && Id < ID_SYMBOLIC_LAST_) { 871 O << IdSymbolic[Id]; 872 } else { 873 O << Id; 874 } 875 if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) { 876 O << ", " << Offset << ", " << Width; 877 } 878 O << ')'; 879 } 880 881 #include "AMDGPUGenAsmWriter.inc" 882