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