1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "AMDGPUInstPrinter.h"
12 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
13 #include "SIDefines.h"
14 #include "Utils/AMDGPUAsmUtils.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCInstrInfo.h"
18 #include "llvm/MC/MCRegisterInfo.h"
19 #include "llvm/Support/MathExtras.h"
20 #include "llvm/Support/raw_ostream.h"
26 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
27 StringRef Annot, const MCSubtargetInfo &STI) {
29 printInstruction(MI, OS);
31 printAnnotation(OS, Annot);
34 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
36 O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
39 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
41 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
44 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
46 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffff);
49 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
51 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
54 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst *MI, unsigned OpNo,
56 O << formatDec(MI->getOperand(OpNo).getImm() & 0xf);
59 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
61 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
64 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
66 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
69 void AMDGPUInstPrinter::printNamedBit(const MCInst* MI, unsigned OpNo,
70 raw_ostream& O, StringRef BitName) {
71 if (MI->getOperand(OpNo).getImm()) {
76 void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
78 printNamedBit(MI, OpNo, O, "offen");
81 void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
83 printNamedBit(MI, OpNo, O, "idxen");
86 void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
88 printNamedBit(MI, OpNo, O, "addr64");
91 void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
93 if (MI->getOperand(OpNo).getImm()) {
95 printU16ImmDecOperand(MI, OpNo, O);
99 void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
101 uint16_t Imm = MI->getOperand(OpNo).getImm();
104 printU16ImmDecOperand(MI, OpNo, O);
108 void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
110 if (MI->getOperand(OpNo).getImm()) {
112 printU8ImmDecOperand(MI, OpNo, O);
116 void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
118 if (MI->getOperand(OpNo).getImm()) {
120 printU8ImmDecOperand(MI, OpNo, O);
124 void AMDGPUInstPrinter::printSMRDOffset(const MCInst *MI, unsigned OpNo,
126 printU32ImmOperand(MI, OpNo, O);
129 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
131 printU32ImmOperand(MI, OpNo, O);
134 void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
136 printNamedBit(MI, OpNo, O, "gds");
139 void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
141 printNamedBit(MI, OpNo, O, "glc");
144 void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
146 printNamedBit(MI, OpNo, O, "slc");
149 void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
151 printNamedBit(MI, OpNo, O, "tfe");
154 void AMDGPUInstPrinter::printDMask(const MCInst *MI, unsigned OpNo,
156 if (MI->getOperand(OpNo).getImm()) {
158 printU16ImmOperand(MI, OpNo, O);
162 void AMDGPUInstPrinter::printUNorm(const MCInst *MI, unsigned OpNo,
164 printNamedBit(MI, OpNo, O, "unorm");
167 void AMDGPUInstPrinter::printDA(const MCInst *MI, unsigned OpNo,
169 printNamedBit(MI, OpNo, O, "da");
172 void AMDGPUInstPrinter::printR128(const MCInst *MI, unsigned OpNo,
174 printNamedBit(MI, OpNo, O, "r128");
177 void AMDGPUInstPrinter::printLWE(const MCInst *MI, unsigned OpNo,
179 printNamedBit(MI, OpNo, O, "lwe");
182 void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O,
183 const MCRegisterInfo &MRI) {
197 case AMDGPU::FLAT_SCR:
218 case AMDGPU::EXEC_LO:
221 case AMDGPU::EXEC_HI:
224 case AMDGPU::FLAT_SCR_LO:
225 O << "flat_scratch_lo";
227 case AMDGPU::FLAT_SCR_HI:
228 O << "flat_scratch_hi";
234 // The low 8 bits of the encoding value is the register index, for both VGPRs
236 unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1);
239 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) {
242 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) {
245 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) {
248 } else if (MRI.getRegClass(AMDGPU::SGPR_64RegClassID).contains(reg)) {
251 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) {
254 } else if (MRI.getRegClass(AMDGPU::SGPR_128RegClassID).contains(reg)) {
257 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) {
260 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) {
263 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) {
266 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) {
269 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) {
272 } else if (MRI.getRegClass(AMDGPU::TTMP_64RegClassID).contains(reg)) {
275 RegIdx -= 112; // Trap temps start at offset 112. TODO: Get this from tablegen.
276 } else if (MRI.getRegClass(AMDGPU::TTMP_128RegClassID).contains(reg)) {
279 RegIdx -= 112; // Trap temps start at offset 112. TODO: Get this from tablegen.
281 O << getRegisterName(reg);
290 O << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
293 void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
295 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
297 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP)
299 else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA)
304 printOperand(MI, OpNo, O);
307 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, raw_ostream &O) {
308 int32_t SImm = static_cast<int32_t>(Imm);
309 if (SImm >= -16 && SImm <= 64) {
314 if (Imm == FloatToBits(0.0f))
316 else if (Imm == FloatToBits(1.0f))
318 else if (Imm == FloatToBits(-1.0f))
320 else if (Imm == FloatToBits(0.5f))
322 else if (Imm == FloatToBits(-0.5f))
324 else if (Imm == FloatToBits(2.0f))
326 else if (Imm == FloatToBits(-2.0f))
328 else if (Imm == FloatToBits(4.0f))
330 else if (Imm == FloatToBits(-4.0f))
333 O << formatHex(static_cast<uint64_t>(Imm));
336 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) {
337 int64_t SImm = static_cast<int64_t>(Imm);
338 if (SImm >= -16 && SImm <= 64) {
343 if (Imm == DoubleToBits(0.0))
345 else if (Imm == DoubleToBits(1.0))
347 else if (Imm == DoubleToBits(-1.0))
349 else if (Imm == DoubleToBits(0.5))
351 else if (Imm == DoubleToBits(-0.5))
353 else if (Imm == DoubleToBits(2.0))
355 else if (Imm == DoubleToBits(-2.0))
357 else if (Imm == DoubleToBits(4.0))
359 else if (Imm == DoubleToBits(-4.0))
362 assert(isUInt<32>(Imm));
364 // In rare situations, we will have a 32-bit literal in a 64-bit
365 // operand. This is technically allowed for the encoding of s_mov_b64.
366 O << formatHex(static_cast<uint64_t>(Imm));
370 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
373 const MCOperand &Op = MI->getOperand(OpNo);
375 switch (Op.getReg()) {
376 // This is the default predicate state, so we don't need to print it.
377 case AMDGPU::PRED_SEL_OFF:
381 printRegOperand(Op.getReg(), O, MRI);
384 } else if (Op.isImm()) {
385 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
386 int RCID = Desc.OpInfo[OpNo].RegClass;
388 const MCRegisterClass &ImmRC = MRI.getRegClass(RCID);
389 if (ImmRC.getSize() == 4)
390 printImmediate32(Op.getImm(), O);
391 else if (ImmRC.getSize() == 8)
392 printImmediate64(Op.getImm(), O);
394 llvm_unreachable("Invalid register class size");
395 } else if (Desc.OpInfo[OpNo].OperandType == MCOI::OPERAND_IMMEDIATE) {
396 printImmediate32(Op.getImm(), O);
398 // We hit this for the immediate instruction bits that don't yet have a
400 // TODO: Eventually this should be unnecessary.
401 O << formatDec(Op.getImm());
403 } else if (Op.isFPImm()) {
404 // We special case 0.0 because otherwise it will be printed as an integer.
405 if (Op.getFPImm() == 0.0)
408 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
409 const MCRegisterClass &ImmRC = MRI.getRegClass(Desc.OpInfo[OpNo].RegClass);
411 if (ImmRC.getSize() == 4)
412 printImmediate32(FloatToBits(Op.getFPImm()), O);
413 else if (ImmRC.getSize() == 8)
414 printImmediate64(DoubleToBits(Op.getFPImm()), O);
416 llvm_unreachable("Invalid register class size");
418 } else if (Op.isExpr()) {
419 const MCExpr *Exp = Op.getExpr();
426 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
429 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
430 if (InputModifiers & SISrcMods::NEG)
432 if (InputModifiers & SISrcMods::ABS)
434 printOperand(MI, OpNo + 1, O);
435 if (InputModifiers & SISrcMods::ABS)
439 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
442 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
443 if (InputModifiers & SISrcMods::SEXT)
445 printOperand(MI, OpNo + 1, O);
446 if (InputModifiers & SISrcMods::SEXT)
451 void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
453 unsigned Imm = MI->getOperand(OpNo).getImm();
456 O << formatDec(Imm & 0x3) << ',';
457 O << formatDec((Imm & 0xc) >> 2) << ',';
458 O << formatDec((Imm & 0x30) >> 4) << ',';
459 O << formatDec((Imm & 0xc0) >> 6) << ']';
460 } else if ((Imm >= 0x101) && (Imm <= 0x10f)) {
462 printU4ImmDecOperand(MI, OpNo, O);
463 } else if ((Imm >= 0x111) && (Imm <= 0x11f)) {
465 printU4ImmDecOperand(MI, OpNo, O);
466 } else if ((Imm >= 0x121) && (Imm <= 0x12f)) {
468 printU4ImmDecOperand(MI, OpNo, O);
469 } else if (Imm == 0x130) {
471 } else if (Imm == 0x134) {
473 } else if (Imm == 0x138) {
475 } else if (Imm == 0x13c) {
477 } else if (Imm == 0x140) {
479 } else if (Imm == 0x141) {
480 O << " row_half_mirror";
481 } else if (Imm == 0x142) {
482 O << " row_bcast:15";
483 } else if (Imm == 0x143) {
484 O << " row_bcast:31";
486 llvm_unreachable("Invalid dpp_ctrl value");
490 void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
493 printU4ImmOperand(MI, OpNo, O);
496 void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
499 printU4ImmOperand(MI, OpNo, O);
502 void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
504 unsigned Imm = MI->getOperand(OpNo).getImm();
506 O << " bound_ctrl:0"; // XXX - this syntax is used in sp3
510 void AMDGPUInstPrinter::printSDWASel(const MCInst *MI, unsigned OpNo,
512 unsigned Imm = MI->getOperand(OpNo).getImm();
514 case 0: O << "BYTE_0"; break;
515 case 1: O << "BYTE_1"; break;
516 case 2: O << "BYTE_2"; break;
517 case 3: O << "BYTE_3"; break;
518 case 4: O << "WORD_0"; break;
519 case 5: O << "WORD_1"; break;
520 case 6: O << "DWORD"; break;
521 default: llvm_unreachable("Invalid SDWA data select operand");
525 void AMDGPUInstPrinter::printSDWADstSel(const MCInst *MI, unsigned OpNo,
528 printSDWASel(MI, OpNo, O);
531 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst *MI, unsigned OpNo,
534 printSDWASel(MI, OpNo, O);
537 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst *MI, unsigned OpNo,
540 printSDWASel(MI, OpNo, O);
543 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst *MI, unsigned OpNo,
546 unsigned Imm = MI->getOperand(OpNo).getImm();
548 case 0: O << "UNUSED_PAD"; break;
549 case 1: O << "UNUSED_SEXT"; break;
550 case 2: O << "UNUSED_PRESERVE"; break;
551 default: llvm_unreachable("Invalid SDWA dest_unused operand");
555 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
557 unsigned Imm = MI->getOperand(OpNum).getImm();
561 } else if (Imm == 1) {
563 } else if (Imm == 0) {
566 llvm_unreachable("Invalid interpolation parameter slot");
570 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
572 printOperand(MI, OpNo, O);
574 printOperand(MI, OpNo + 1, O);
577 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
578 raw_ostream &O, StringRef Asm,
580 const MCOperand &Op = MI->getOperand(OpNo);
582 if (Op.getImm() == 1) {
589 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
590 raw_ostream &O, char Asm) {
591 const MCOperand &Op = MI->getOperand(OpNo);
593 if (Op.getImm() == 1)
597 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
599 printIfSet(MI, OpNo, O, '|');
602 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
604 printIfSet(MI, OpNo, O, "_SAT");
607 void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
609 if (MI->getOperand(OpNo).getImm())
613 void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
615 int Imm = MI->getOperand(OpNo).getImm();
616 if (Imm == SIOutMods::MUL2)
618 else if (Imm == SIOutMods::MUL4)
620 else if (Imm == SIOutMods::DIV2)
624 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
626 const MCOperand &Op = MI->getOperand(OpNo);
627 assert(Op.isImm() || Op.isExpr());
629 int64_t Imm = Op.getImm();
630 O << Imm << '(' << BitsToFloat(Imm) << ')';
633 Op.getExpr()->print(O << '@', &MAI);
637 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
639 printIfSet(MI, OpNo, O, "*", " ");
642 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
644 printIfSet(MI, OpNo, O, '-');
647 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
649 switch (MI->getOperand(OpNo).getImm()) {
663 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
665 printIfSet(MI, OpNo, O, '+');
668 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
670 printIfSet(MI, OpNo, O, "ExecMask,");
673 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
675 printIfSet(MI, OpNo, O, "Pred,");
678 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
680 const MCOperand &Op = MI->getOperand(OpNo);
681 if (Op.getImm() == 0) {
686 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
688 const char * chans = "XYZW";
689 int sel = MI->getOperand(OpNo).getImm();
698 O << cb << '[' << sel << ']';
699 } else if (sel >= 448) {
702 } else if (sel >= 0){
707 O << '.' << chans[chan];
710 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
712 int BankSwizzle = MI->getOperand(OpNo).getImm();
713 switch (BankSwizzle) {
715 O << "BS:VEC_021/SCL_122";
718 O << "BS:VEC_120/SCL_212";
721 O << "BS:VEC_102/SCL_221";
735 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
737 unsigned Sel = MI->getOperand(OpNo).getImm();
765 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
767 unsigned CT = MI->getOperand(OpNo).getImm();
780 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
782 int KCacheMode = MI->getOperand(OpNo).getImm();
783 if (KCacheMode > 0) {
784 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
785 O << "CB" << KCacheBank << ':';
786 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
787 int LineSize = (KCacheMode == 1) ? 16 : 32;
788 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
792 void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
794 using namespace llvm::AMDGPU::SendMsg;
796 const unsigned SImm16 = MI->getOperand(OpNo).getImm();
797 const unsigned Id = SImm16 & ID_MASK_;
799 if (Id == ID_INTERRUPT) {
800 if ((SImm16 & ~ID_MASK_) != 0) // Unused/unknown bits must be 0.
802 O << "sendmsg(" << IdSymbolic[Id] << ')';
805 if (Id == ID_GS || Id == ID_GS_DONE) {
806 if ((SImm16 & ~(ID_MASK_|OP_GS_MASK_|STREAM_ID_MASK_)) != 0) // Unused/unknown bits must be 0.
808 const unsigned OpGs = (SImm16 & OP_GS_MASK_) >> OP_SHIFT_;
809 const unsigned StreamId = (SImm16 & STREAM_ID_MASK_) >> STREAM_ID_SHIFT_;
810 if (OpGs == OP_GS_NOP && Id != ID_GS_DONE) // NOP to be used for GS_DONE only.
812 if (OpGs == OP_GS_NOP && StreamId != 0) // NOP does not use/define stream id bits.
814 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpGsSymbolic[OpGs];
815 if (OpGs != OP_GS_NOP) { O << ", " << StreamId; }
819 if (Id == ID_SYSMSG) {
820 if ((SImm16 & ~(ID_MASK_|OP_SYS_MASK_)) != 0) // Unused/unknown bits must be 0.
822 const unsigned OpSys = (SImm16 & OP_SYS_MASK_) >> OP_SHIFT_;
823 if (! (OP_SYS_FIRST_ <= OpSys && OpSys < OP_SYS_LAST_)) // Unused/unknown.
825 O << "sendmsg(" << IdSymbolic[Id] << ", " << OpSysSymbolic[OpSys] << ')';
829 O << SImm16; // Unknown simm16 code.
832 void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
834 unsigned SImm16 = MI->getOperand(OpNo).getImm();
835 unsigned Vmcnt = SImm16 & 0xF;
836 unsigned Expcnt = (SImm16 >> 4) & 0x7;
837 unsigned Lgkmcnt = (SImm16 >> 8) & 0xF;
839 bool NeedSpace = false;
842 O << "vmcnt(" << Vmcnt << ')';
849 O << "expcnt(" << Expcnt << ')';
853 if (Lgkmcnt != 0xF) {
856 O << "lgkmcnt(" << Lgkmcnt << ')';
860 void AMDGPUInstPrinter::printHwreg(const MCInst *MI, unsigned OpNo,
862 using namespace llvm::AMDGPU::Hwreg;
864 unsigned SImm16 = MI->getOperand(OpNo).getImm();
865 const unsigned Id = (SImm16 & ID_MASK_) >> ID_SHIFT_;
866 const unsigned Offset = (SImm16 & OFFSET_MASK_) >> OFFSET_SHIFT_;
867 const unsigned Width = ((SImm16 & WIDTH_M1_MASK_) >> WIDTH_M1_SHIFT_) + 1;
870 if (ID_SYMBOLIC_FIRST_ <= Id && Id < ID_SYMBOLIC_LAST_) {
875 if (Width != WIDTH_M1_DEFAULT_ + 1 || Offset != OFFSET_DEFAULT_) {
876 O << ", " << Offset << ", " << Width;
881 #include "AMDGPUGenAsmWriter.inc"