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