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 "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"
28 using namespace llvm::AMDGPU
;
30 void AMDGPUInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&OS
,
31 StringRef Annot
, const MCSubtargetInfo
&STI
) {
33 printInstruction(MI
, STI
, OS
);
34 printAnnotation(OS
, Annot
);
37 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst
*MI
, unsigned OpNo
,
38 const MCSubtargetInfo
&STI
,
40 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xf);
43 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst
*MI
, unsigned OpNo
,
45 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xff);
48 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst
*MI
, unsigned OpNo
,
49 const MCSubtargetInfo
&STI
,
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));
57 printU32ImmOperand(MI
, OpNo
, STI
, O
);
60 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
62 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xf);
65 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
67 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xff);
70 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
72 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xffff);
75 void AMDGPUInstPrinter::printS13ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
77 O
<< formatDec(SignExtend32
<13>(MI
->getOperand(OpNo
).getImm()));
80 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst
*MI
, unsigned OpNo
,
81 const MCSubtargetInfo
&STI
,
83 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xffffffff);
86 void AMDGPUInstPrinter::printNamedBit(const MCInst
*MI
, unsigned OpNo
,
87 raw_ostream
&O
, StringRef BitName
) {
88 if (MI
->getOperand(OpNo
).getImm()) {
93 void AMDGPUInstPrinter::printOffen(const MCInst
*MI
, unsigned OpNo
,
95 printNamedBit(MI
, OpNo
, O
, "offen");
98 void AMDGPUInstPrinter::printIdxen(const MCInst
*MI
, unsigned OpNo
,
100 printNamedBit(MI
, OpNo
, O
, "idxen");
103 void AMDGPUInstPrinter::printAddr64(const MCInst
*MI
, unsigned OpNo
,
105 printNamedBit(MI
, OpNo
, O
, "addr64");
108 void AMDGPUInstPrinter::printMBUFOffset(const MCInst
*MI
, unsigned OpNo
,
110 if (MI
->getOperand(OpNo
).getImm()) {
112 printU16ImmDecOperand(MI
, OpNo
, O
);
116 void AMDGPUInstPrinter::printOffset(const MCInst
*MI
, unsigned OpNo
,
117 const MCSubtargetInfo
&STI
,
119 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
121 O
<< ((OpNo
== 0)? "offset:" : " offset:");
122 printU16ImmDecOperand(MI
, OpNo
, O
);
126 void AMDGPUInstPrinter::printOffsetS13(const MCInst
*MI
, unsigned OpNo
,
127 const MCSubtargetInfo
&STI
,
129 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
131 O
<< ((OpNo
== 0)? "offset:" : " offset:");
132 printS13ImmDecOperand(MI
, OpNo
, O
);
136 void AMDGPUInstPrinter::printOffset0(const MCInst
*MI
, unsigned OpNo
,
137 const MCSubtargetInfo
&STI
,
139 if (MI
->getOperand(OpNo
).getImm()) {
141 printU8ImmDecOperand(MI
, OpNo
, O
);
145 void AMDGPUInstPrinter::printOffset1(const MCInst
*MI
, unsigned OpNo
,
146 const MCSubtargetInfo
&STI
,
148 if (MI
->getOperand(OpNo
).getImm()) {
150 printU8ImmDecOperand(MI
, OpNo
, O
);
154 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst
*MI
, unsigned OpNo
,
155 const MCSubtargetInfo
&STI
,
157 printU32ImmOperand(MI
, OpNo
, STI
, O
);
160 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst
*MI
, unsigned OpNo
,
161 const MCSubtargetInfo
&STI
,
163 printU32ImmOperand(MI
, OpNo
, STI
, O
);
166 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst
*MI
, unsigned OpNo
,
167 const MCSubtargetInfo
&STI
,
169 printU32ImmOperand(MI
, OpNo
, STI
, O
);
172 void AMDGPUInstPrinter::printGDS(const MCInst
*MI
, unsigned OpNo
,
173 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
174 printNamedBit(MI
, OpNo
, O
, "gds");
177 void AMDGPUInstPrinter::printGLC(const MCInst
*MI
, unsigned OpNo
,
178 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
179 printNamedBit(MI
, OpNo
, O
, "glc");
182 void AMDGPUInstPrinter::printSLC(const MCInst
*MI
, unsigned OpNo
,
183 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
184 printNamedBit(MI
, OpNo
, O
, "slc");
187 void AMDGPUInstPrinter::printTFE(const MCInst
*MI
, unsigned OpNo
,
188 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
189 printNamedBit(MI
, OpNo
, O
, "tfe");
192 void AMDGPUInstPrinter::printDMask(const MCInst
*MI
, unsigned OpNo
,
193 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
194 if (MI
->getOperand(OpNo
).getImm()) {
196 printU16ImmOperand(MI
, OpNo
, STI
, O
);
200 void AMDGPUInstPrinter::printUNorm(const MCInst
*MI
, unsigned OpNo
,
201 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
202 printNamedBit(MI
, OpNo
, O
, "unorm");
205 void AMDGPUInstPrinter::printDA(const MCInst
*MI
, unsigned OpNo
,
206 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
207 printNamedBit(MI
, OpNo
, O
, "da");
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");
215 printNamedBit(MI
, OpNo
, O
, "r128");
218 void AMDGPUInstPrinter::printLWE(const MCInst
*MI
, unsigned OpNo
,
219 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
220 printNamedBit(MI
, OpNo
, O
, "lwe");
223 void AMDGPUInstPrinter::printD16(const MCInst
*MI
, unsigned OpNo
,
224 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
225 printNamedBit(MI
, OpNo
, O
, "d16");
228 void AMDGPUInstPrinter::printExpCompr(const MCInst
*MI
, unsigned OpNo
,
229 const MCSubtargetInfo
&STI
,
231 if (MI
->getOperand(OpNo
).getImm())
235 void AMDGPUInstPrinter::printExpVM(const MCInst
*MI
, unsigned OpNo
,
236 const MCSubtargetInfo
&STI
,
238 if (MI
->getOperand(OpNo
).getImm())
242 void AMDGPUInstPrinter::printFORMAT(const MCInst
*MI
, unsigned OpNo
,
243 const MCSubtargetInfo
&STI
,
245 if (unsigned Val
= MI
->getOperand(OpNo
).getImm()) {
246 O
<< " dfmt:" << (Val
& 15);
247 O
<< ", nfmt:" << (Val
>> 4);
251 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo
, raw_ostream
&O
,
252 const MCRegisterInfo
&MRI
) {
266 case AMDGPU::FLAT_SCR
:
269 case AMDGPU::XNACK_MASK
:
290 case AMDGPU::EXEC_LO
:
293 case AMDGPU::EXEC_HI
:
296 case AMDGPU::FLAT_SCR_LO
:
297 O
<< "flat_scratch_lo";
299 case AMDGPU::FLAT_SCR_HI
:
300 O
<< "flat_scratch_hi";
302 case AMDGPU::XNACK_MASK_LO
:
303 O
<< "xnack_mask_lo";
305 case AMDGPU::XNACK_MASK_HI
:
306 O
<< "xnack_mask_hi";
310 case AMDGPU::SCRATCH_WAVE_OFFSET_REG
:
311 case AMDGPU::PRIVATE_RSRC_REG
:
312 llvm_unreachable("pseudo-register should not ever be emitted");
317 // The low 8 bits of the encoding value is the register index, for both VGPRs
319 unsigned RegIdx
= MRI
.getEncodingValue(RegNo
) & ((1 << 8) - 1);
322 if (MRI
.getRegClass(AMDGPU::VGPR_32RegClassID
).contains(RegNo
)) {
325 } else if (MRI
.getRegClass(AMDGPU::SGPR_32RegClassID
).contains(RegNo
)) {
328 } else if (MRI
.getRegClass(AMDGPU::VReg_64RegClassID
).contains(RegNo
)) {
331 } else if (MRI
.getRegClass(AMDGPU::SGPR_64RegClassID
).contains(RegNo
)) {
334 } else if (MRI
.getRegClass(AMDGPU::VReg_128RegClassID
).contains(RegNo
)) {
337 } else if (MRI
.getRegClass(AMDGPU::SGPR_128RegClassID
).contains(RegNo
)) {
340 } else if (MRI
.getRegClass(AMDGPU::VReg_96RegClassID
).contains(RegNo
)) {
343 } else if (MRI
.getRegClass(AMDGPU::VReg_256RegClassID
).contains(RegNo
)) {
346 } else if (MRI
.getRegClass(AMDGPU::SGPR_256RegClassID
).contains(RegNo
)) {
349 } else if (MRI
.getRegClass(AMDGPU::VReg_512RegClassID
).contains(RegNo
)) {
352 } else if (MRI
.getRegClass(AMDGPU::SGPR_512RegClassID
).contains(RegNo
)) {
356 O
<< getRegisterName(RegNo
);
365 O
<< '[' << RegIdx
<< ':' << (RegIdx
+ NumRegs
- 1) << ']';
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
)
372 else if (MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::DPP
)
374 else if (MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::SDWA
)
379 printOperand(MI
, OpNo
, STI
, O
);
382 void AMDGPUInstPrinter::printVINTRPDst(const MCInst
*MI
, unsigned OpNo
,
383 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
384 if (AMDGPU::isSI(STI
) || AMDGPU::isCI(STI
))
389 printOperand(MI
, OpNo
, STI
, O
);
392 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm
,
393 const MCSubtargetInfo
&STI
,
395 int16_t SImm
= static_cast<int16_t>(Imm
);
396 if (SImm
>= -16 && SImm
<= 64) {
403 else if (Imm
== 0xBC00)
405 else if (Imm
== 0x3800)
407 else if (Imm
== 0xB800)
409 else if (Imm
== 0x4000)
411 else if (Imm
== 0xC000)
413 else if (Imm
== 0x4400)
415 else if (Imm
== 0xC400)
417 else if (Imm
== 0x3118) {
418 assert(STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
]);
421 O
<< formatHex(static_cast<uint64_t>(Imm
));
424 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm
,
425 const MCSubtargetInfo
&STI
,
427 uint16_t Lo16
= static_cast<uint16_t>(Imm
);
428 printImmediate16(Lo16
, STI
, O
);
431 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm
,
432 const MCSubtargetInfo
&STI
,
434 int32_t SImm
= static_cast<int32_t>(Imm
);
435 if (SImm
>= -16 && SImm
<= 64) {
440 if (Imm
== FloatToBits(0.0f
))
442 else if (Imm
== FloatToBits(1.0f
))
444 else if (Imm
== FloatToBits(-1.0f
))
446 else if (Imm
== FloatToBits(0.5f
))
448 else if (Imm
== FloatToBits(-0.5f
))
450 else if (Imm
== FloatToBits(2.0f
))
452 else if (Imm
== FloatToBits(-2.0f
))
454 else if (Imm
== FloatToBits(4.0f
))
456 else if (Imm
== FloatToBits(-4.0f
))
458 else if (Imm
== 0x3e22f983 &&
459 STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
])
462 O
<< formatHex(static_cast<uint64_t>(Imm
));
465 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm
,
466 const MCSubtargetInfo
&STI
,
468 int64_t SImm
= static_cast<int64_t>(Imm
);
469 if (SImm
>= -16 && SImm
<= 64) {
474 if (Imm
== DoubleToBits(0.0))
476 else if (Imm
== DoubleToBits(1.0))
478 else if (Imm
== DoubleToBits(-1.0))
480 else if (Imm
== DoubleToBits(0.5))
482 else if (Imm
== DoubleToBits(-0.5))
484 else if (Imm
== DoubleToBits(2.0))
486 else if (Imm
== DoubleToBits(-2.0))
488 else if (Imm
== DoubleToBits(4.0))
490 else if (Imm
== DoubleToBits(-4.0))
492 else if (Imm
== 0x3fc45f306dc9c882 &&
493 STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
])
496 assert(isUInt
<32>(Imm
) || Imm
== 0x3fc45f306dc9c882);
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
));
504 void AMDGPUInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
505 const MCSubtargetInfo
&STI
,
507 if (OpNo
>= MI
->getNumOperands()) {
508 O
<< "/*Missing OP" << OpNo
<< "*/";
512 const MCOperand
&Op
= MI
->getOperand(OpNo
);
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
);
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
);
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
);
537 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16
:
538 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16
:
539 printImmediateV216(Op
.getImm(), STI
, O
);
541 case MCOI::OPERAND_UNKNOWN
:
542 case MCOI::OPERAND_PCREL
:
543 O
<< formatDec(Op
.getImm());
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*/";
551 // We hit this for the immediate instruction bits that don't yet have a
553 llvm_unreachable("unexpected immediate operand type");
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)
560 const MCInstrDesc
&Desc
= MII
.get(MI
->getOpcode());
561 int RCID
= Desc
.OpInfo
[OpNo
].RegClass
;
562 unsigned RCBits
= AMDGPU::getRegBitWidth(MRI
.getRegClass(RCID
));
564 printImmediate32(FloatToBits(Op
.getFPImm()), STI
, O
);
565 else if (RCBits
== 64)
566 printImmediate64(DoubleToBits(Op
.getFPImm()), STI
, O
);
568 llvm_unreachable("Invalid register class size");
570 } else if (Op
.isExpr()) {
571 const MCExpr
*Exp
= Op
.getExpr();
578 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst
*MI
,
580 const MCSubtargetInfo
&STI
,
582 unsigned InputModifiers
= MI
->getOperand(OpNo
).getImm();
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;
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();
602 if (InputModifiers
& SISrcMods::ABS
)
604 printOperand(MI
, OpNo
+ 1, STI
, O
);
605 if (InputModifiers
& SISrcMods::ABS
)
613 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst
*MI
,
615 const MCSubtargetInfo
&STI
,
617 unsigned InputModifiers
= MI
->getOperand(OpNo
).getImm();
618 if (InputModifiers
& SISrcMods::SEXT
)
620 printOperand(MI
, OpNo
+ 1, STI
, O
);
621 if (InputModifiers
& SISrcMods::SEXT
)
625 void AMDGPUInstPrinter::printDPPCtrl(const MCInst
*MI
, unsigned OpNo
,
626 const MCSubtargetInfo
&STI
,
628 using namespace AMDGPU::DPP
;
630 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
631 if (Imm
<= DppCtrl::QUAD_PERM_LAST
) {
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
)) {
640 printU4ImmDecOperand(MI
, OpNo
, O
);
641 } else if ((Imm
>= DppCtrl::ROW_SHR_FIRST
) &&
642 (Imm
<= DppCtrl::ROW_SHR_LAST
)) {
644 printU4ImmDecOperand(MI
, OpNo
, O
);
645 } else if ((Imm
>= DppCtrl::ROW_ROR_FIRST
) &&
646 (Imm
<= DppCtrl::ROW_ROR_LAST
)) {
648 printU4ImmDecOperand(MI
, OpNo
, O
);
649 } else if (Imm
== DppCtrl::WAVE_SHL1
) {
651 } else if (Imm
== DppCtrl::WAVE_ROL1
) {
653 } else if (Imm
== DppCtrl::WAVE_SHR1
) {
655 } else if (Imm
== DppCtrl::WAVE_ROR1
) {
657 } else if (Imm
== DppCtrl::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";
666 O
<< " /* Invalid dpp_ctrl value */";
670 void AMDGPUInstPrinter::printRowMask(const MCInst
*MI
, unsigned OpNo
,
671 const MCSubtargetInfo
&STI
,
674 printU4ImmOperand(MI
, OpNo
, STI
, O
);
677 void AMDGPUInstPrinter::printBankMask(const MCInst
*MI
, unsigned OpNo
,
678 const MCSubtargetInfo
&STI
,
681 printU4ImmOperand(MI
, OpNo
, STI
, O
);
684 void AMDGPUInstPrinter::printBoundCtrl(const MCInst
*MI
, unsigned OpNo
,
685 const MCSubtargetInfo
&STI
,
687 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
689 O
<< " bound_ctrl:0"; // XXX - this syntax is used in sp3
693 void AMDGPUInstPrinter::printSDWASel(const MCInst
*MI
, unsigned OpNo
,
695 using namespace llvm::AMDGPU::SDWA
;
697 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
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");
710 void AMDGPUInstPrinter::printSDWADstSel(const MCInst
*MI
, unsigned OpNo
,
711 const MCSubtargetInfo
&STI
,
714 printSDWASel(MI
, OpNo
, O
);
717 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst
*MI
, unsigned OpNo
,
718 const MCSubtargetInfo
&STI
,
721 printSDWASel(MI
, OpNo
, O
);
724 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst
*MI
, unsigned OpNo
,
725 const MCSubtargetInfo
&STI
,
728 printSDWASel(MI
, OpNo
, O
);
731 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst
*MI
, unsigned OpNo
,
732 const MCSubtargetInfo
&STI
,
734 using namespace llvm::AMDGPU::SDWA
;
737 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
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");
746 template <unsigned N
>
747 void AMDGPUInstPrinter::printExpSrcN(const MCInst
*MI
, unsigned OpNo
,
748 const MCSubtargetInfo
&STI
,
750 unsigned Opc
= MI
->getOpcode();
751 int EnIdx
= AMDGPU::getNamedOperandIdx(Opc
, AMDGPU::OpName::en
);
752 unsigned En
= MI
->getOperand(EnIdx
).getImm();
754 int ComprIdx
= AMDGPU::getNamedOperandIdx(Opc
, AMDGPU::OpName::compr
);
756 // If compr is set, print as src0, src0, src1, src1
757 if (MI
->getOperand(ComprIdx
).getImm()) {
758 if (N
== 1 || N
== 2)
765 printRegOperand(MI
->getOperand(OpNo
).getReg(), O
, MRI
);
770 void AMDGPUInstPrinter::printExpSrc0(const MCInst
*MI
, unsigned OpNo
,
771 const MCSubtargetInfo
&STI
,
773 printExpSrcN
<0>(MI
, OpNo
, STI
, O
);
776 void AMDGPUInstPrinter::printExpSrc1(const MCInst
*MI
, unsigned OpNo
,
777 const MCSubtargetInfo
&STI
,
779 printExpSrcN
<1>(MI
, OpNo
, STI
, O
);
782 void AMDGPUInstPrinter::printExpSrc2(const MCInst
*MI
, unsigned OpNo
,
783 const MCSubtargetInfo
&STI
,
785 printExpSrcN
<2>(MI
, OpNo
, STI
, O
);
788 void AMDGPUInstPrinter::printExpSrc3(const MCInst
*MI
, unsigned OpNo
,
789 const MCSubtargetInfo
&STI
,
791 printExpSrcN
<3>(MI
, OpNo
, STI
, O
);
794 void AMDGPUInstPrinter::printExpTgt(const MCInst
*MI
, unsigned OpNo
,
795 const MCSubtargetInfo
&STI
,
797 // This is really a 6 bit field.
798 uint32_t Tgt
= MI
->getOperand(OpNo
).getImm() & ((1 << 6) - 1);
806 else if (Tgt
>= 12 && Tgt
<= 15)
807 O
<< " pos" << Tgt
- 12;
808 else if (Tgt
>= 32 && Tgt
<= 63)
809 O
<< " param" << Tgt
- 32;
811 // Reserved values 10, 11
812 O
<< " invalid_target_" << Tgt
;
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
);
820 for (int I
= 0; I
< NumOps
; ++I
) {
821 if (!!(Ops
[I
] & Mod
) != DefaultValue
)
825 if (HasDstSel
&& (Ops
[0] & SISrcMods::DST_OP_SEL
) != 0)
831 void AMDGPUInstPrinter::printPackedModifier(const MCInst
*MI
,
835 unsigned Opc
= MI
->getOpcode();
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
);
846 Ops
[NumOps
++] = MI
->getOperand(Idx
).getImm();
849 const bool HasDstSel
=
851 Mod
== SISrcMods::OP_SEL_0
&&
852 MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::VOP3_OPSEL
;
854 const bool IsPacked
=
855 MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::IsPacked
;
857 if (allOpsDefaultValue(Ops
, NumOps
, Mod
, IsPacked
, HasDstSel
))
861 for (int I
= 0; I
< NumOps
; ++I
) {
865 O
<< !!(Ops
[I
] & Mod
);
869 O
<< ',' << !!(Ops
[0] & SISrcMods::DST_OP_SEL
);
875 void AMDGPUInstPrinter::printOpSel(const MCInst
*MI
, unsigned,
876 const MCSubtargetInfo
&STI
,
878 printPackedModifier(MI
, " op_sel:[", SISrcMods::OP_SEL_0
, O
);
881 void AMDGPUInstPrinter::printOpSelHi(const MCInst
*MI
, unsigned OpNo
,
882 const MCSubtargetInfo
&STI
,
884 printPackedModifier(MI
, " op_sel_hi:[", SISrcMods::OP_SEL_1
, O
);
887 void AMDGPUInstPrinter::printNegLo(const MCInst
*MI
, unsigned OpNo
,
888 const MCSubtargetInfo
&STI
,
890 printPackedModifier(MI
, " neg_lo:[", SISrcMods::NEG
, O
);
893 void AMDGPUInstPrinter::printNegHi(const MCInst
*MI
, unsigned OpNo
,
894 const MCSubtargetInfo
&STI
,
896 printPackedModifier(MI
, " neg_hi:[", SISrcMods::NEG_HI
, O
);
899 void AMDGPUInstPrinter::printInterpSlot(const MCInst
*MI
, unsigned OpNum
,
900 const MCSubtargetInfo
&STI
,
902 unsigned Imm
= MI
->getOperand(OpNum
).getImm();
914 O
<< "invalid_param_" << Imm
;
918 void AMDGPUInstPrinter::printInterpAttr(const MCInst
*MI
, unsigned OpNum
,
919 const MCSubtargetInfo
&STI
,
921 unsigned Attr
= MI
->getOperand(OpNum
).getImm();
925 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst
*MI
, unsigned OpNum
,
926 const MCSubtargetInfo
&STI
,
928 unsigned Chan
= MI
->getOperand(OpNum
).getImm();
929 O
<< '.' << "xyzw"[Chan
& 0x3];
932 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst
*MI
, unsigned OpNo
,
933 const MCSubtargetInfo
&STI
,
935 unsigned Val
= MI
->getOperand(OpNo
).getImm();
941 if (Val
& VGPRIndexMode::DST_ENABLE
)
944 if (Val
& VGPRIndexMode::SRC0_ENABLE
)
947 if (Val
& VGPRIndexMode::SRC1_ENABLE
)
950 if (Val
& VGPRIndexMode::SRC2_ENABLE
)
954 void AMDGPUInstPrinter::printMemOperand(const MCInst
*MI
, unsigned OpNo
,
955 const MCSubtargetInfo
&STI
,
957 printOperand(MI
, OpNo
, STI
, O
);
959 printOperand(MI
, OpNo
+ 1, STI
, O
);
962 void AMDGPUInstPrinter::printIfSet(const MCInst
*MI
, unsigned OpNo
,
963 raw_ostream
&O
, StringRef Asm
,
965 const MCOperand
&Op
= MI
->getOperand(OpNo
);
967 if (Op
.getImm() == 1) {
974 void AMDGPUInstPrinter::printIfSet(const MCInst
*MI
, unsigned OpNo
,
975 raw_ostream
&O
, char Asm
) {
976 const MCOperand
&Op
= MI
->getOperand(OpNo
);
978 if (Op
.getImm() == 1)
982 void AMDGPUInstPrinter::printHigh(const MCInst
*MI
, unsigned OpNo
,
983 const MCSubtargetInfo
&STI
,
985 if (MI
->getOperand(OpNo
).getImm())
989 void AMDGPUInstPrinter::printClampSI(const MCInst
*MI
, unsigned OpNo
,
990 const MCSubtargetInfo
&STI
,
992 if (MI
->getOperand(OpNo
).getImm())
996 void AMDGPUInstPrinter::printOModSI(const MCInst
*MI
, unsigned OpNo
,
997 const MCSubtargetInfo
&STI
,
999 int Imm
= MI
->getOperand(OpNo
).getImm();
1000 if (Imm
== SIOutMods::MUL2
)
1002 else if (Imm
== SIOutMods::MUL4
)
1004 else if (Imm
== SIOutMods::DIV2
)
1008 void AMDGPUInstPrinter::printSendMsg(const MCInst
*MI
, unsigned OpNo
,
1009 const MCSubtargetInfo
&STI
,
1011 using namespace llvm::AMDGPU::SendMsg
;
1013 const unsigned SImm16
= MI
->getOperand(OpNo
).getImm();
1014 const unsigned Id
= SImm16
& ID_MASK_
;
1016 if (Id
== ID_INTERRUPT
) {
1017 if ((SImm16
& ~ID_MASK_
) != 0) // Unused/unknown bits must be 0.
1019 O
<< "sendmsg(" << IdSymbolic
[Id
] << ')';
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.
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.
1029 if (OpGs
== OP_GS_NOP
&& StreamId
!= 0) // NOP does not use/define stream id bits.
1031 O
<< "sendmsg(" << IdSymbolic
[Id
] << ", " << OpGsSymbolic
[OpGs
];
1032 if (OpGs
!= OP_GS_NOP
) { O
<< ", " << StreamId
; }
1036 if (Id
== ID_SYSMSG
) {
1037 if ((SImm16
& ~(ID_MASK_
|OP_SYS_MASK_
)) != 0) // Unused/unknown bits must be 0.
1039 const unsigned OpSys
= (SImm16
& OP_SYS_MASK_
) >> OP_SHIFT_
;
1040 if (! (OP_SYS_FIRST_
<= OpSys
&& OpSys
< OP_SYS_LAST_
)) // Unused/unknown.
1042 O
<< "sendmsg(" << IdSymbolic
[Id
] << ", " << OpSysSymbolic
[OpSys
] << ')';
1046 O
<< SImm16
; // Unknown simm16 code.
1049 static void printSwizzleBitmask(const uint16_t AndMask
,
1050 const uint16_t OrMask
,
1051 const uint16_t XorMask
,
1053 using namespace llvm::AMDGPU::Swizzle
;
1055 uint16_t Probe0
= ((0 & AndMask
) | OrMask
) ^ XorMask
;
1056 uint16_t Probe1
= ((BITMASK_MASK
& AndMask
) | OrMask
) ^ XorMask
;
1060 for (unsigned Mask
= 1 << (BITMASK_WIDTH
- 1); Mask
> 0; Mask
>>= 1) {
1061 uint16_t p0
= Probe0
& Mask
;
1062 uint16_t p1
= Probe1
& Mask
;
1082 void AMDGPUInstPrinter::printSwizzle(const MCInst
*MI
, unsigned OpNo
,
1083 const MCSubtargetInfo
&STI
,
1085 using namespace llvm::AMDGPU::Swizzle
;
1087 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
1094 if ((Imm
& QUAD_PERM_ENC_MASK
) == QUAD_PERM_ENC
) {
1096 O
<< "swizzle(" << IdSymbolic
[ID_QUAD_PERM
];
1097 for (auto i
= 0; i
< LANE_NUM
; ++i
) {
1099 O
<< formatDec(Imm
& LANE_MASK
);
1104 } else if ((Imm
& BITMASK_PERM_ENC_MASK
) == BITMASK_PERM_ENC
) {
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
;
1110 if (AndMask
== BITMASK_MAX
&&
1112 countPopulation(XorMask
) == 1) {
1114 O
<< "swizzle(" << IdSymbolic
[ID_SWAP
];
1116 O
<< formatDec(XorMask
);
1119 } else if (AndMask
== BITMASK_MAX
&&
1120 OrMask
== 0 && XorMask
> 0 &&
1121 isPowerOf2_64(XorMask
+ 1)) {
1123 O
<< "swizzle(" << IdSymbolic
[ID_REVERSE
];
1125 O
<< formatDec(XorMask
+ 1);
1130 uint16_t GroupSize
= BITMASK_MAX
- AndMask
+ 1;
1131 if (GroupSize
> 1 &&
1132 isPowerOf2_64(GroupSize
) &&
1133 OrMask
< GroupSize
&&
1136 O
<< "swizzle(" << IdSymbolic
[ID_BROADCAST
];
1138 O
<< formatDec(GroupSize
);
1140 O
<< formatDec(OrMask
);
1144 O
<< "swizzle(" << IdSymbolic
[ID_BITMASK_PERM
];
1146 printSwizzleBitmask(AndMask
, OrMask
, XorMask
, O
);
1151 printU16ImmDecOperand(MI
, OpNo
, O
);
1155 void AMDGPUInstPrinter::printWaitFlag(const MCInst
*MI
, unsigned OpNo
,
1156 const MCSubtargetInfo
&STI
,
1158 AMDGPU::IsaVersion ISA
= AMDGPU::getIsaVersion(STI
.getCPU());
1160 unsigned SImm16
= MI
->getOperand(OpNo
).getImm();
1161 unsigned Vmcnt
, Expcnt
, Lgkmcnt
;
1162 decodeWaitcnt(ISA
, SImm16
, Vmcnt
, Expcnt
, Lgkmcnt
);
1164 bool NeedSpace
= false;
1166 if (Vmcnt
!= getVmcntBitMask(ISA
)) {
1167 O
<< "vmcnt(" << Vmcnt
<< ')';
1171 if (Expcnt
!= getExpcntBitMask(ISA
)) {
1174 O
<< "expcnt(" << Expcnt
<< ')';
1178 if (Lgkmcnt
!= getLgkmcntBitMask(ISA
)) {
1181 O
<< "lgkmcnt(" << Lgkmcnt
<< ')';
1185 void AMDGPUInstPrinter::printHwreg(const MCInst
*MI
, unsigned OpNo
,
1186 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
1187 using namespace llvm::AMDGPU::Hwreg
;
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;
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
];
1203 if (Width
!= WIDTH_M1_DEFAULT_
+ 1 || Offset
!= OFFSET_DEFAULT_
) {
1204 O
<< ", " << Offset
<< ", " << Width
;
1209 #include "AMDGPUGenAsmWriter.inc"
1211 void R600InstPrinter::printInst(const MCInst
*MI
, raw_ostream
&O
,
1212 StringRef Annot
, const MCSubtargetInfo
&STI
) {
1214 printInstruction(MI
, O
);
1215 printAnnotation(O
, Annot
);
1218 void R600InstPrinter::printAbs(const MCInst
*MI
, unsigned OpNo
,
1220 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '|');
1223 void R600InstPrinter::printBankSwizzle(const MCInst
*MI
, unsigned OpNo
,
1225 int BankSwizzle
= MI
->getOperand(OpNo
).getImm();
1226 switch (BankSwizzle
) {
1228 O
<< "BS:VEC_021/SCL_122";
1231 O
<< "BS:VEC_120/SCL_212";
1234 O
<< "BS:VEC_102/SCL_221";
1247 void R600InstPrinter::printClamp(const MCInst
*MI
, unsigned OpNo
,
1249 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "_SAT");
1252 void R600InstPrinter::printCT(const MCInst
*MI
, unsigned OpNo
,
1254 unsigned CT
= MI
->getOperand(OpNo
).getImm();
1267 void R600InstPrinter::printKCache(const MCInst
*MI
, unsigned OpNo
,
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
;
1279 void R600InstPrinter::printLast(const MCInst
*MI
, unsigned OpNo
,
1281 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "*", " ");
1284 void R600InstPrinter::printLiteral(const MCInst
*MI
, unsigned OpNo
,
1286 const MCOperand
&Op
= MI
->getOperand(OpNo
);
1287 assert(Op
.isImm() || Op
.isExpr());
1289 int64_t Imm
= Op
.getImm();
1290 O
<< Imm
<< '(' << BitsToFloat(Imm
) << ')';
1293 Op
.getExpr()->print(O
<< '@', &MAI
);
1297 void R600InstPrinter::printNeg(const MCInst
*MI
, unsigned OpNo
,
1299 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '-');
1302 void R600InstPrinter::printOMOD(const MCInst
*MI
, unsigned OpNo
,
1304 switch (MI
->getOperand(OpNo
).getImm()) {
1318 void R600InstPrinter::printMemOperand(const MCInst
*MI
, unsigned OpNo
,
1320 printOperand(MI
, OpNo
, O
);
1322 printOperand(MI
, OpNo
+ 1, O
);
1325 void R600InstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
1327 if (OpNo
>= MI
->getNumOperands()) {
1328 O
<< "/*Missing OP" << OpNo
<< "*/";
1332 const MCOperand
&Op
= MI
->getOperand(OpNo
);
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
:
1340 O
<< getRegisterName(Op
.getReg());
1343 } else if (Op
.isImm()) {
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)
1352 } else if (Op
.isExpr()) {
1353 const MCExpr
*Exp
= Op
.getExpr();
1354 Exp
->print(O
, &MAI
);
1360 void R600InstPrinter::printRel(const MCInst
*MI
, unsigned OpNo
,
1362 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '+');
1365 void R600InstPrinter::printRSel(const MCInst
*MI
, unsigned OpNo
,
1367 unsigned Sel
= MI
->getOperand(OpNo
).getImm();
1395 void R600InstPrinter::printUpdateExecMask(const MCInst
*MI
, unsigned OpNo
,
1397 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "ExecMask,");
1400 void R600InstPrinter::printUpdatePred(const MCInst
*MI
, unsigned OpNo
,
1402 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "Pred,");
1405 void R600InstPrinter::printWrite(const MCInst
*MI
, unsigned OpNo
,
1407 const MCOperand
&Op
= MI
->getOperand(OpNo
);
1408 if (Op
.getImm() == 0) {
1413 #include "R600GenAsmWriter.inc"