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