1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #include "AMDGPUInstPrinter.h"
11 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
12 #include "SIDefines.h"
13 #include "Utils/AMDGPUAsmUtils.h"
14 #include "Utils/AMDGPUBaseInfo.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCInstrDesc.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/raw_ostream.h"
27 using namespace llvm::AMDGPU
;
29 void AMDGPUInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&OS
,
30 StringRef Annot
, const MCSubtargetInfo
&STI
) {
32 printInstruction(MI
, STI
, OS
);
33 printAnnotation(OS
, Annot
);
36 void AMDGPUInstPrinter::printU4ImmOperand(const MCInst
*MI
, unsigned OpNo
,
37 const MCSubtargetInfo
&STI
,
39 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xf);
42 void AMDGPUInstPrinter::printU8ImmOperand(const MCInst
*MI
, unsigned OpNo
,
44 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xff);
47 void AMDGPUInstPrinter::printU16ImmOperand(const MCInst
*MI
, unsigned OpNo
,
48 const MCSubtargetInfo
&STI
,
50 // It's possible to end up with a 32-bit literal used with a 16-bit operand
51 // with ignored high bits. Print as 32-bit anyway in that case.
52 int64_t Imm
= MI
->getOperand(OpNo
).getImm();
53 if (isInt
<16>(Imm
) || isUInt
<16>(Imm
))
54 O
<< formatHex(static_cast<uint64_t>(Imm
& 0xffff));
56 printU32ImmOperand(MI
, OpNo
, STI
, O
);
59 void AMDGPUInstPrinter::printU4ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
61 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xf);
64 void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
66 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xff);
69 void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
71 O
<< formatDec(MI
->getOperand(OpNo
).getImm() & 0xffff);
74 void AMDGPUInstPrinter::printS13ImmDecOperand(const MCInst
*MI
, unsigned OpNo
,
76 O
<< formatDec(SignExtend32
<13>(MI
->getOperand(OpNo
).getImm()));
79 void AMDGPUInstPrinter::printU32ImmOperand(const MCInst
*MI
, unsigned OpNo
,
80 const MCSubtargetInfo
&STI
,
82 O
<< formatHex(MI
->getOperand(OpNo
).getImm() & 0xffffffff);
85 void AMDGPUInstPrinter::printNamedBit(const MCInst
*MI
, unsigned OpNo
,
86 raw_ostream
&O
, StringRef BitName
) {
87 if (MI
->getOperand(OpNo
).getImm()) {
92 void AMDGPUInstPrinter::printOffen(const MCInst
*MI
, unsigned OpNo
,
94 printNamedBit(MI
, OpNo
, O
, "offen");
97 void AMDGPUInstPrinter::printIdxen(const MCInst
*MI
, unsigned OpNo
,
99 printNamedBit(MI
, OpNo
, O
, "idxen");
102 void AMDGPUInstPrinter::printAddr64(const MCInst
*MI
, unsigned OpNo
,
104 printNamedBit(MI
, OpNo
, O
, "addr64");
107 void AMDGPUInstPrinter::printMBUFOffset(const MCInst
*MI
, unsigned OpNo
,
109 if (MI
->getOperand(OpNo
).getImm()) {
111 printU16ImmDecOperand(MI
, OpNo
, O
);
115 void AMDGPUInstPrinter::printOffset(const MCInst
*MI
, unsigned OpNo
,
116 const MCSubtargetInfo
&STI
,
118 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
120 O
<< ((OpNo
== 0)? "offset:" : " offset:");
121 printU16ImmDecOperand(MI
, OpNo
, O
);
125 void AMDGPUInstPrinter::printOffsetS13(const MCInst
*MI
, unsigned OpNo
,
126 const MCSubtargetInfo
&STI
,
128 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
130 O
<< ((OpNo
== 0)? "offset:" : " offset:");
131 printS13ImmDecOperand(MI
, OpNo
, O
);
135 void AMDGPUInstPrinter::printOffset0(const MCInst
*MI
, unsigned OpNo
,
136 const MCSubtargetInfo
&STI
,
138 if (MI
->getOperand(OpNo
).getImm()) {
140 printU8ImmDecOperand(MI
, OpNo
, O
);
144 void AMDGPUInstPrinter::printOffset1(const MCInst
*MI
, unsigned OpNo
,
145 const MCSubtargetInfo
&STI
,
147 if (MI
->getOperand(OpNo
).getImm()) {
149 printU8ImmDecOperand(MI
, OpNo
, O
);
153 void AMDGPUInstPrinter::printSMRDOffset8(const MCInst
*MI
, unsigned OpNo
,
154 const MCSubtargetInfo
&STI
,
156 printU32ImmOperand(MI
, OpNo
, STI
, O
);
159 void AMDGPUInstPrinter::printSMRDOffset20(const MCInst
*MI
, unsigned OpNo
,
160 const MCSubtargetInfo
&STI
,
162 printU32ImmOperand(MI
, OpNo
, STI
, O
);
165 void AMDGPUInstPrinter::printSMRDLiteralOffset(const MCInst
*MI
, unsigned OpNo
,
166 const MCSubtargetInfo
&STI
,
168 printU32ImmOperand(MI
, OpNo
, STI
, O
);
171 void AMDGPUInstPrinter::printGDS(const MCInst
*MI
, unsigned OpNo
,
172 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
173 printNamedBit(MI
, OpNo
, O
, "gds");
176 void AMDGPUInstPrinter::printGLC(const MCInst
*MI
, unsigned OpNo
,
177 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
178 printNamedBit(MI
, OpNo
, O
, "glc");
181 void AMDGPUInstPrinter::printSLC(const MCInst
*MI
, unsigned OpNo
,
182 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
183 printNamedBit(MI
, OpNo
, O
, "slc");
186 void AMDGPUInstPrinter::printTFE(const MCInst
*MI
, unsigned OpNo
,
187 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
188 printNamedBit(MI
, OpNo
, O
, "tfe");
191 void AMDGPUInstPrinter::printDMask(const MCInst
*MI
, unsigned OpNo
,
192 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
193 if (MI
->getOperand(OpNo
).getImm()) {
195 printU16ImmOperand(MI
, OpNo
, STI
, O
);
199 void AMDGPUInstPrinter::printUNorm(const MCInst
*MI
, unsigned OpNo
,
200 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
201 printNamedBit(MI
, OpNo
, O
, "unorm");
204 void AMDGPUInstPrinter::printDA(const MCInst
*MI
, unsigned OpNo
,
205 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
206 printNamedBit(MI
, OpNo
, O
, "da");
209 void AMDGPUInstPrinter::printR128A16(const MCInst
*MI
, unsigned OpNo
,
210 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
211 if (STI
.hasFeature(AMDGPU::FeatureR128A16
))
212 printNamedBit(MI
, OpNo
, O
, "a16");
214 printNamedBit(MI
, OpNo
, O
, "r128");
217 void AMDGPUInstPrinter::printLWE(const MCInst
*MI
, unsigned OpNo
,
218 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
219 printNamedBit(MI
, OpNo
, O
, "lwe");
222 void AMDGPUInstPrinter::printD16(const MCInst
*MI
, unsigned OpNo
,
223 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
224 printNamedBit(MI
, OpNo
, O
, "d16");
227 void AMDGPUInstPrinter::printExpCompr(const MCInst
*MI
, unsigned OpNo
,
228 const MCSubtargetInfo
&STI
,
230 if (MI
->getOperand(OpNo
).getImm())
234 void AMDGPUInstPrinter::printExpVM(const MCInst
*MI
, unsigned OpNo
,
235 const MCSubtargetInfo
&STI
,
237 if (MI
->getOperand(OpNo
).getImm())
241 void AMDGPUInstPrinter::printFORMAT(const MCInst
*MI
, unsigned OpNo
,
242 const MCSubtargetInfo
&STI
,
244 if (unsigned Val
= MI
->getOperand(OpNo
).getImm()) {
245 O
<< " dfmt:" << (Val
& 15);
246 O
<< ", nfmt:" << (Val
>> 4);
250 void AMDGPUInstPrinter::printRegOperand(unsigned RegNo
, raw_ostream
&O
,
251 const MCRegisterInfo
&MRI
) {
265 case AMDGPU::FLAT_SCR
:
268 case AMDGPU::XNACK_MASK
:
271 case AMDGPU::LDS_DIRECT
:
272 O
<< "src_lds_direct";
292 case AMDGPU::EXEC_LO
:
295 case AMDGPU::EXEC_HI
:
298 case AMDGPU::FLAT_SCR_LO
:
299 O
<< "flat_scratch_lo";
301 case AMDGPU::FLAT_SCR_HI
:
302 O
<< "flat_scratch_hi";
304 case AMDGPU::XNACK_MASK_LO
:
305 O
<< "xnack_mask_lo";
307 case AMDGPU::XNACK_MASK_HI
:
308 O
<< "xnack_mask_hi";
312 case AMDGPU::SCRATCH_WAVE_OFFSET_REG
:
313 case AMDGPU::PRIVATE_RSRC_REG
:
314 llvm_unreachable("pseudo-register should not ever be emitted");
319 // The low 8 bits of the encoding value is the register index, for both VGPRs
321 unsigned RegIdx
= MRI
.getEncodingValue(RegNo
) & ((1 << 8) - 1);
324 if (MRI
.getRegClass(AMDGPU::VGPR_32RegClassID
).contains(RegNo
)) {
327 } else if (MRI
.getRegClass(AMDGPU::SGPR_32RegClassID
).contains(RegNo
)) {
330 } else if (MRI
.getRegClass(AMDGPU::VReg_64RegClassID
).contains(RegNo
)) {
333 } else if (MRI
.getRegClass(AMDGPU::SGPR_64RegClassID
).contains(RegNo
)) {
336 } else if (MRI
.getRegClass(AMDGPU::VReg_128RegClassID
).contains(RegNo
)) {
339 } else if (MRI
.getRegClass(AMDGPU::SGPR_128RegClassID
).contains(RegNo
)) {
342 } else if (MRI
.getRegClass(AMDGPU::VReg_96RegClassID
).contains(RegNo
)) {
345 } else if (MRI
.getRegClass(AMDGPU::VReg_256RegClassID
).contains(RegNo
)) {
348 } else if (MRI
.getRegClass(AMDGPU::SGPR_256RegClassID
).contains(RegNo
)) {
351 } else if (MRI
.getRegClass(AMDGPU::VReg_512RegClassID
).contains(RegNo
)) {
354 } else if (MRI
.getRegClass(AMDGPU::SGPR_512RegClassID
).contains(RegNo
)) {
358 O
<< getRegisterName(RegNo
);
367 O
<< '[' << RegIdx
<< ':' << (RegIdx
+ NumRegs
- 1) << ']';
370 void AMDGPUInstPrinter::printVOPDst(const MCInst
*MI
, unsigned OpNo
,
371 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
372 if (MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::VOP3
)
374 else if (MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::DPP
)
376 else if (MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::SDWA
)
381 printOperand(MI
, OpNo
, STI
, O
);
384 void AMDGPUInstPrinter::printVINTRPDst(const MCInst
*MI
, unsigned OpNo
,
385 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
386 if (AMDGPU::isSI(STI
) || AMDGPU::isCI(STI
))
391 printOperand(MI
, OpNo
, STI
, O
);
394 void AMDGPUInstPrinter::printImmediate16(uint32_t Imm
,
395 const MCSubtargetInfo
&STI
,
397 int16_t SImm
= static_cast<int16_t>(Imm
);
398 if (SImm
>= -16 && SImm
<= 64) {
405 else if (Imm
== 0xBC00)
407 else if (Imm
== 0x3800)
409 else if (Imm
== 0xB800)
411 else if (Imm
== 0x4000)
413 else if (Imm
== 0xC000)
415 else if (Imm
== 0x4400)
417 else if (Imm
== 0xC400)
419 else if (Imm
== 0x3118) {
420 assert(STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
]);
423 O
<< formatHex(static_cast<uint64_t>(Imm
));
426 void AMDGPUInstPrinter::printImmediateV216(uint32_t Imm
,
427 const MCSubtargetInfo
&STI
,
429 uint16_t Lo16
= static_cast<uint16_t>(Imm
);
430 printImmediate16(Lo16
, STI
, O
);
433 void AMDGPUInstPrinter::printImmediate32(uint32_t Imm
,
434 const MCSubtargetInfo
&STI
,
436 int32_t SImm
= static_cast<int32_t>(Imm
);
437 if (SImm
>= -16 && SImm
<= 64) {
442 if (Imm
== FloatToBits(0.0f
))
444 else if (Imm
== FloatToBits(1.0f
))
446 else if (Imm
== FloatToBits(-1.0f
))
448 else if (Imm
== FloatToBits(0.5f
))
450 else if (Imm
== FloatToBits(-0.5f
))
452 else if (Imm
== FloatToBits(2.0f
))
454 else if (Imm
== FloatToBits(-2.0f
))
456 else if (Imm
== FloatToBits(4.0f
))
458 else if (Imm
== FloatToBits(-4.0f
))
460 else if (Imm
== 0x3e22f983 &&
461 STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
])
464 O
<< formatHex(static_cast<uint64_t>(Imm
));
467 void AMDGPUInstPrinter::printImmediate64(uint64_t Imm
,
468 const MCSubtargetInfo
&STI
,
470 int64_t SImm
= static_cast<int64_t>(Imm
);
471 if (SImm
>= -16 && SImm
<= 64) {
476 if (Imm
== DoubleToBits(0.0))
478 else if (Imm
== DoubleToBits(1.0))
480 else if (Imm
== DoubleToBits(-1.0))
482 else if (Imm
== DoubleToBits(0.5))
484 else if (Imm
== DoubleToBits(-0.5))
486 else if (Imm
== DoubleToBits(2.0))
488 else if (Imm
== DoubleToBits(-2.0))
490 else if (Imm
== DoubleToBits(4.0))
492 else if (Imm
== DoubleToBits(-4.0))
494 else if (Imm
== 0x3fc45f306dc9c882 &&
495 STI
.getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm
])
496 O
<< "0.15915494309189532";
498 assert(isUInt
<32>(Imm
) || Imm
== 0x3fc45f306dc9c882);
500 // In rare situations, we will have a 32-bit literal in a 64-bit
501 // operand. This is technically allowed for the encoding of s_mov_b64.
502 O
<< formatHex(static_cast<uint64_t>(Imm
));
506 void AMDGPUInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
507 const MCSubtargetInfo
&STI
,
509 if (OpNo
>= MI
->getNumOperands()) {
510 O
<< "/*Missing OP" << OpNo
<< "*/";
514 const MCOperand
&Op
= MI
->getOperand(OpNo
);
516 printRegOperand(Op
.getReg(), O
, MRI
);
517 } else if (Op
.isImm()) {
518 const MCInstrDesc
&Desc
= MII
.get(MI
->getOpcode());
519 switch (Desc
.OpInfo
[OpNo
].OperandType
) {
520 case AMDGPU::OPERAND_REG_IMM_INT32
:
521 case AMDGPU::OPERAND_REG_IMM_FP32
:
522 case AMDGPU::OPERAND_REG_INLINE_C_INT32
:
523 case AMDGPU::OPERAND_REG_INLINE_C_FP32
:
524 case MCOI::OPERAND_IMMEDIATE
:
525 printImmediate32(Op
.getImm(), STI
, O
);
527 case AMDGPU::OPERAND_REG_IMM_INT64
:
528 case AMDGPU::OPERAND_REG_IMM_FP64
:
529 case AMDGPU::OPERAND_REG_INLINE_C_INT64
:
530 case AMDGPU::OPERAND_REG_INLINE_C_FP64
:
531 printImmediate64(Op
.getImm(), STI
, O
);
533 case AMDGPU::OPERAND_REG_INLINE_C_INT16
:
534 case AMDGPU::OPERAND_REG_INLINE_C_FP16
:
535 case AMDGPU::OPERAND_REG_IMM_INT16
:
536 case AMDGPU::OPERAND_REG_IMM_FP16
:
537 printImmediate16(Op
.getImm(), STI
, O
);
539 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16
:
540 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16
:
541 printImmediateV216(Op
.getImm(), STI
, O
);
543 case MCOI::OPERAND_UNKNOWN
:
544 case MCOI::OPERAND_PCREL
:
545 O
<< formatDec(Op
.getImm());
547 case MCOI::OPERAND_REGISTER
:
548 // FIXME: This should be removed and handled somewhere else. Seems to come
549 // from a disassembler bug.
550 O
<< "/*invalid immediate*/";
553 // We hit this for the immediate instruction bits that don't yet have a
555 llvm_unreachable("unexpected immediate operand type");
557 } else if (Op
.isFPImm()) {
558 // We special case 0.0 because otherwise it will be printed as an integer.
559 if (Op
.getFPImm() == 0.0)
562 const MCInstrDesc
&Desc
= MII
.get(MI
->getOpcode());
563 int RCID
= Desc
.OpInfo
[OpNo
].RegClass
;
564 unsigned RCBits
= AMDGPU::getRegBitWidth(MRI
.getRegClass(RCID
));
566 printImmediate32(FloatToBits(Op
.getFPImm()), STI
, O
);
567 else if (RCBits
== 64)
568 printImmediate64(DoubleToBits(Op
.getFPImm()), STI
, O
);
570 llvm_unreachable("Invalid register class size");
572 } else if (Op
.isExpr()) {
573 const MCExpr
*Exp
= Op
.getExpr();
580 void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst
*MI
,
582 const MCSubtargetInfo
&STI
,
584 unsigned InputModifiers
= MI
->getOperand(OpNo
).getImm();
586 // Use 'neg(...)' instead of '-' to avoid ambiguity.
587 // This is important for integer literals because
588 // -1 is not the same value as neg(1).
589 bool NegMnemo
= false;
591 if (InputModifiers
& SISrcMods::NEG
) {
592 if (OpNo
+ 1 < MI
->getNumOperands() &&
593 (InputModifiers
& SISrcMods::ABS
) == 0) {
594 const MCOperand
&Op
= MI
->getOperand(OpNo
+ 1);
595 NegMnemo
= Op
.isImm() || Op
.isFPImm();
604 if (InputModifiers
& SISrcMods::ABS
)
606 printOperand(MI
, OpNo
+ 1, STI
, O
);
607 if (InputModifiers
& SISrcMods::ABS
)
615 void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst
*MI
,
617 const MCSubtargetInfo
&STI
,
619 unsigned InputModifiers
= MI
->getOperand(OpNo
).getImm();
620 if (InputModifiers
& SISrcMods::SEXT
)
622 printOperand(MI
, OpNo
+ 1, STI
, O
);
623 if (InputModifiers
& SISrcMods::SEXT
)
627 void AMDGPUInstPrinter::printDPPCtrl(const MCInst
*MI
, unsigned OpNo
,
628 const MCSubtargetInfo
&STI
,
630 using namespace AMDGPU::DPP
;
632 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
633 if (Imm
<= DppCtrl::QUAD_PERM_LAST
) {
635 O
<< formatDec(Imm
& 0x3) << ',';
636 O
<< formatDec((Imm
& 0xc) >> 2) << ',';
637 O
<< formatDec((Imm
& 0x30) >> 4) << ',';
638 O
<< formatDec((Imm
& 0xc0) >> 6) << ']';
639 } else if ((Imm
>= DppCtrl::ROW_SHL_FIRST
) &&
640 (Imm
<= DppCtrl::ROW_SHL_LAST
)) {
642 printU4ImmDecOperand(MI
, OpNo
, O
);
643 } else if ((Imm
>= DppCtrl::ROW_SHR_FIRST
) &&
644 (Imm
<= DppCtrl::ROW_SHR_LAST
)) {
646 printU4ImmDecOperand(MI
, OpNo
, O
);
647 } else if ((Imm
>= DppCtrl::ROW_ROR_FIRST
) &&
648 (Imm
<= DppCtrl::ROW_ROR_LAST
)) {
650 printU4ImmDecOperand(MI
, OpNo
, O
);
651 } else if (Imm
== DppCtrl::WAVE_SHL1
) {
653 } else if (Imm
== DppCtrl::WAVE_ROL1
) {
655 } else if (Imm
== DppCtrl::WAVE_SHR1
) {
657 } else if (Imm
== DppCtrl::WAVE_ROR1
) {
659 } else if (Imm
== DppCtrl::ROW_MIRROR
) {
661 } else if (Imm
== DppCtrl::ROW_HALF_MIRROR
) {
662 O
<< " row_half_mirror";
663 } else if (Imm
== DppCtrl::BCAST15
) {
664 O
<< " row_bcast:15";
665 } else if (Imm
== DppCtrl::BCAST31
) {
666 O
<< " row_bcast:31";
668 O
<< " /* Invalid dpp_ctrl value */";
672 void AMDGPUInstPrinter::printRowMask(const MCInst
*MI
, unsigned OpNo
,
673 const MCSubtargetInfo
&STI
,
676 printU4ImmOperand(MI
, OpNo
, STI
, O
);
679 void AMDGPUInstPrinter::printBankMask(const MCInst
*MI
, unsigned OpNo
,
680 const MCSubtargetInfo
&STI
,
683 printU4ImmOperand(MI
, OpNo
, STI
, O
);
686 void AMDGPUInstPrinter::printBoundCtrl(const MCInst
*MI
, unsigned OpNo
,
687 const MCSubtargetInfo
&STI
,
689 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
691 O
<< " bound_ctrl:0"; // XXX - this syntax is used in sp3
695 void AMDGPUInstPrinter::printSDWASel(const MCInst
*MI
, unsigned OpNo
,
697 using namespace llvm::AMDGPU::SDWA
;
699 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
701 case SdwaSel::BYTE_0
: O
<< "BYTE_0"; break;
702 case SdwaSel::BYTE_1
: O
<< "BYTE_1"; break;
703 case SdwaSel::BYTE_2
: O
<< "BYTE_2"; break;
704 case SdwaSel::BYTE_3
: O
<< "BYTE_3"; break;
705 case SdwaSel::WORD_0
: O
<< "WORD_0"; break;
706 case SdwaSel::WORD_1
: O
<< "WORD_1"; break;
707 case SdwaSel::DWORD
: O
<< "DWORD"; break;
708 default: llvm_unreachable("Invalid SDWA data select operand");
712 void AMDGPUInstPrinter::printSDWADstSel(const MCInst
*MI
, unsigned OpNo
,
713 const MCSubtargetInfo
&STI
,
716 printSDWASel(MI
, OpNo
, O
);
719 void AMDGPUInstPrinter::printSDWASrc0Sel(const MCInst
*MI
, unsigned OpNo
,
720 const MCSubtargetInfo
&STI
,
723 printSDWASel(MI
, OpNo
, O
);
726 void AMDGPUInstPrinter::printSDWASrc1Sel(const MCInst
*MI
, unsigned OpNo
,
727 const MCSubtargetInfo
&STI
,
730 printSDWASel(MI
, OpNo
, O
);
733 void AMDGPUInstPrinter::printSDWADstUnused(const MCInst
*MI
, unsigned OpNo
,
734 const MCSubtargetInfo
&STI
,
736 using namespace llvm::AMDGPU::SDWA
;
739 unsigned Imm
= MI
->getOperand(OpNo
).getImm();
741 case DstUnused::UNUSED_PAD
: O
<< "UNUSED_PAD"; break;
742 case DstUnused::UNUSED_SEXT
: O
<< "UNUSED_SEXT"; break;
743 case DstUnused::UNUSED_PRESERVE
: O
<< "UNUSED_PRESERVE"; break;
744 default: llvm_unreachable("Invalid SDWA dest_unused operand");
748 template <unsigned N
>
749 void AMDGPUInstPrinter::printExpSrcN(const MCInst
*MI
, unsigned OpNo
,
750 const MCSubtargetInfo
&STI
,
752 unsigned Opc
= MI
->getOpcode();
753 int EnIdx
= AMDGPU::getNamedOperandIdx(Opc
, AMDGPU::OpName::en
);
754 unsigned En
= MI
->getOperand(EnIdx
).getImm();
756 int ComprIdx
= AMDGPU::getNamedOperandIdx(Opc
, AMDGPU::OpName::compr
);
758 // If compr is set, print as src0, src0, src1, src1
759 if (MI
->getOperand(ComprIdx
).getImm()) {
760 if (N
== 1 || N
== 2)
767 printRegOperand(MI
->getOperand(OpNo
).getReg(), O
, MRI
);
772 void AMDGPUInstPrinter::printExpSrc0(const MCInst
*MI
, unsigned OpNo
,
773 const MCSubtargetInfo
&STI
,
775 printExpSrcN
<0>(MI
, OpNo
, STI
, O
);
778 void AMDGPUInstPrinter::printExpSrc1(const MCInst
*MI
, unsigned OpNo
,
779 const MCSubtargetInfo
&STI
,
781 printExpSrcN
<1>(MI
, OpNo
, STI
, O
);
784 void AMDGPUInstPrinter::printExpSrc2(const MCInst
*MI
, unsigned OpNo
,
785 const MCSubtargetInfo
&STI
,
787 printExpSrcN
<2>(MI
, OpNo
, STI
, O
);
790 void AMDGPUInstPrinter::printExpSrc3(const MCInst
*MI
, unsigned OpNo
,
791 const MCSubtargetInfo
&STI
,
793 printExpSrcN
<3>(MI
, OpNo
, STI
, O
);
796 void AMDGPUInstPrinter::printExpTgt(const MCInst
*MI
, unsigned OpNo
,
797 const MCSubtargetInfo
&STI
,
799 // This is really a 6 bit field.
800 uint32_t Tgt
= MI
->getOperand(OpNo
).getImm() & ((1 << 6) - 1);
808 else if (Tgt
>= 12 && Tgt
<= 15)
809 O
<< " pos" << Tgt
- 12;
810 else if (Tgt
>= 32 && Tgt
<= 63)
811 O
<< " param" << Tgt
- 32;
813 // Reserved values 10, 11
814 O
<< " invalid_target_" << Tgt
;
818 static bool allOpsDefaultValue(const int* Ops
, int NumOps
, int Mod
,
819 bool IsPacked
, bool HasDstSel
) {
820 int DefaultValue
= IsPacked
&& (Mod
== SISrcMods::OP_SEL_1
);
822 for (int I
= 0; I
< NumOps
; ++I
) {
823 if (!!(Ops
[I
] & Mod
) != DefaultValue
)
827 if (HasDstSel
&& (Ops
[0] & SISrcMods::DST_OP_SEL
) != 0)
833 void AMDGPUInstPrinter::printPackedModifier(const MCInst
*MI
,
837 unsigned Opc
= MI
->getOpcode();
841 for (int OpName
: { AMDGPU::OpName::src0_modifiers
,
842 AMDGPU::OpName::src1_modifiers
,
843 AMDGPU::OpName::src2_modifiers
}) {
844 int Idx
= AMDGPU::getNamedOperandIdx(Opc
, OpName
);
848 Ops
[NumOps
++] = MI
->getOperand(Idx
).getImm();
851 const bool HasDstSel
=
853 Mod
== SISrcMods::OP_SEL_0
&&
854 MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::VOP3_OPSEL
;
856 const bool IsPacked
=
857 MII
.get(MI
->getOpcode()).TSFlags
& SIInstrFlags::IsPacked
;
859 if (allOpsDefaultValue(Ops
, NumOps
, Mod
, IsPacked
, HasDstSel
))
863 for (int I
= 0; I
< NumOps
; ++I
) {
867 O
<< !!(Ops
[I
] & Mod
);
871 O
<< ',' << !!(Ops
[0] & SISrcMods::DST_OP_SEL
);
877 void AMDGPUInstPrinter::printOpSel(const MCInst
*MI
, unsigned,
878 const MCSubtargetInfo
&STI
,
880 printPackedModifier(MI
, " op_sel:[", SISrcMods::OP_SEL_0
, O
);
883 void AMDGPUInstPrinter::printOpSelHi(const MCInst
*MI
, unsigned OpNo
,
884 const MCSubtargetInfo
&STI
,
886 printPackedModifier(MI
, " op_sel_hi:[", SISrcMods::OP_SEL_1
, O
);
889 void AMDGPUInstPrinter::printNegLo(const MCInst
*MI
, unsigned OpNo
,
890 const MCSubtargetInfo
&STI
,
892 printPackedModifier(MI
, " neg_lo:[", SISrcMods::NEG
, O
);
895 void AMDGPUInstPrinter::printNegHi(const MCInst
*MI
, unsigned OpNo
,
896 const MCSubtargetInfo
&STI
,
898 printPackedModifier(MI
, " neg_hi:[", SISrcMods::NEG_HI
, O
);
901 void AMDGPUInstPrinter::printInterpSlot(const MCInst
*MI
, unsigned OpNum
,
902 const MCSubtargetInfo
&STI
,
904 unsigned Imm
= MI
->getOperand(OpNum
).getImm();
916 O
<< "invalid_param_" << Imm
;
920 void AMDGPUInstPrinter::printInterpAttr(const MCInst
*MI
, unsigned OpNum
,
921 const MCSubtargetInfo
&STI
,
923 unsigned Attr
= MI
->getOperand(OpNum
).getImm();
927 void AMDGPUInstPrinter::printInterpAttrChan(const MCInst
*MI
, unsigned OpNum
,
928 const MCSubtargetInfo
&STI
,
930 unsigned Chan
= MI
->getOperand(OpNum
).getImm();
931 O
<< '.' << "xyzw"[Chan
& 0x3];
934 void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst
*MI
, unsigned OpNo
,
935 const MCSubtargetInfo
&STI
,
937 unsigned Val
= MI
->getOperand(OpNo
).getImm();
943 if (Val
& VGPRIndexMode::DST_ENABLE
)
946 if (Val
& VGPRIndexMode::SRC0_ENABLE
)
949 if (Val
& VGPRIndexMode::SRC1_ENABLE
)
952 if (Val
& VGPRIndexMode::SRC2_ENABLE
)
956 void AMDGPUInstPrinter::printMemOperand(const MCInst
*MI
, unsigned OpNo
,
957 const MCSubtargetInfo
&STI
,
959 printOperand(MI
, OpNo
, STI
, O
);
961 printOperand(MI
, OpNo
+ 1, STI
, O
);
964 void AMDGPUInstPrinter::printIfSet(const MCInst
*MI
, unsigned OpNo
,
965 raw_ostream
&O
, StringRef Asm
,
967 const MCOperand
&Op
= MI
->getOperand(OpNo
);
969 if (Op
.getImm() == 1) {
976 void AMDGPUInstPrinter::printIfSet(const MCInst
*MI
, unsigned OpNo
,
977 raw_ostream
&O
, char Asm
) {
978 const MCOperand
&Op
= MI
->getOperand(OpNo
);
980 if (Op
.getImm() == 1)
984 void AMDGPUInstPrinter::printHigh(const MCInst
*MI
, unsigned OpNo
,
985 const MCSubtargetInfo
&STI
,
987 if (MI
->getOperand(OpNo
).getImm())
991 void AMDGPUInstPrinter::printClampSI(const MCInst
*MI
, unsigned OpNo
,
992 const MCSubtargetInfo
&STI
,
994 if (MI
->getOperand(OpNo
).getImm())
998 void AMDGPUInstPrinter::printOModSI(const MCInst
*MI
, unsigned OpNo
,
999 const MCSubtargetInfo
&STI
,
1001 int Imm
= MI
->getOperand(OpNo
).getImm();
1002 if (Imm
== SIOutMods::MUL2
)
1004 else if (Imm
== SIOutMods::MUL4
)
1006 else if (Imm
== SIOutMods::DIV2
)
1010 void AMDGPUInstPrinter::printSendMsg(const MCInst
*MI
, unsigned OpNo
,
1011 const MCSubtargetInfo
&STI
,
1013 using namespace llvm::AMDGPU::SendMsg
;
1015 const unsigned SImm16
= MI
->getOperand(OpNo
).getImm();
1016 const unsigned Id
= SImm16
& ID_MASK_
;
1018 if (Id
== ID_INTERRUPT
) {
1019 if ((SImm16
& ~ID_MASK_
) != 0) // Unused/unknown bits must be 0.
1021 O
<< "sendmsg(" << IdSymbolic
[Id
] << ')';
1024 if (Id
== ID_GS
|| Id
== ID_GS_DONE
) {
1025 if ((SImm16
& ~(ID_MASK_
|OP_GS_MASK_
|STREAM_ID_MASK_
)) != 0) // Unused/unknown bits must be 0.
1027 const unsigned OpGs
= (SImm16
& OP_GS_MASK_
) >> OP_SHIFT_
;
1028 const unsigned StreamId
= (SImm16
& STREAM_ID_MASK_
) >> STREAM_ID_SHIFT_
;
1029 if (OpGs
== OP_GS_NOP
&& Id
!= ID_GS_DONE
) // NOP to be used for GS_DONE only.
1031 if (OpGs
== OP_GS_NOP
&& StreamId
!= 0) // NOP does not use/define stream id bits.
1033 O
<< "sendmsg(" << IdSymbolic
[Id
] << ", " << OpGsSymbolic
[OpGs
];
1034 if (OpGs
!= OP_GS_NOP
) { O
<< ", " << StreamId
; }
1038 if (Id
== ID_SYSMSG
) {
1039 if ((SImm16
& ~(ID_MASK_
|OP_SYS_MASK_
)) != 0) // Unused/unknown bits must be 0.
1041 const unsigned OpSys
= (SImm16
& OP_SYS_MASK_
) >> OP_SHIFT_
;
1042 if (! (OP_SYS_FIRST_
<= OpSys
&& OpSys
< OP_SYS_LAST_
)) // Unused/unknown.
1044 O
<< "sendmsg(" << IdSymbolic
[Id
] << ", " << OpSysSymbolic
[OpSys
] << ')';
1048 O
<< SImm16
; // Unknown simm16 code.
1051 static void printSwizzleBitmask(const uint16_t AndMask
,
1052 const uint16_t OrMask
,
1053 const uint16_t XorMask
,
1055 using namespace llvm::AMDGPU::Swizzle
;
1057 uint16_t Probe0
= ((0 & AndMask
) | OrMask
) ^ XorMask
;
1058 uint16_t Probe1
= ((BITMASK_MASK
& AndMask
) | OrMask
) ^ XorMask
;
1062 for (unsigned Mask
= 1 << (BITMASK_WIDTH
- 1); Mask
> 0; Mask
>>= 1) {
1063 uint16_t p0
= Probe0
& Mask
;
1064 uint16_t p1
= Probe1
& Mask
;
1084 void AMDGPUInstPrinter::printSwizzle(const MCInst
*MI
, unsigned OpNo
,
1085 const MCSubtargetInfo
&STI
,
1087 using namespace llvm::AMDGPU::Swizzle
;
1089 uint16_t Imm
= MI
->getOperand(OpNo
).getImm();
1096 if ((Imm
& QUAD_PERM_ENC_MASK
) == QUAD_PERM_ENC
) {
1098 O
<< "swizzle(" << IdSymbolic
[ID_QUAD_PERM
];
1099 for (auto i
= 0; i
< LANE_NUM
; ++i
) {
1101 O
<< formatDec(Imm
& LANE_MASK
);
1106 } else if ((Imm
& BITMASK_PERM_ENC_MASK
) == BITMASK_PERM_ENC
) {
1108 uint16_t AndMask
= (Imm
>> BITMASK_AND_SHIFT
) & BITMASK_MASK
;
1109 uint16_t OrMask
= (Imm
>> BITMASK_OR_SHIFT
) & BITMASK_MASK
;
1110 uint16_t XorMask
= (Imm
>> BITMASK_XOR_SHIFT
) & BITMASK_MASK
;
1112 if (AndMask
== BITMASK_MAX
&&
1114 countPopulation(XorMask
) == 1) {
1116 O
<< "swizzle(" << IdSymbolic
[ID_SWAP
];
1118 O
<< formatDec(XorMask
);
1121 } else if (AndMask
== BITMASK_MAX
&&
1122 OrMask
== 0 && XorMask
> 0 &&
1123 isPowerOf2_64(XorMask
+ 1)) {
1125 O
<< "swizzle(" << IdSymbolic
[ID_REVERSE
];
1127 O
<< formatDec(XorMask
+ 1);
1132 uint16_t GroupSize
= BITMASK_MAX
- AndMask
+ 1;
1133 if (GroupSize
> 1 &&
1134 isPowerOf2_64(GroupSize
) &&
1135 OrMask
< GroupSize
&&
1138 O
<< "swizzle(" << IdSymbolic
[ID_BROADCAST
];
1140 O
<< formatDec(GroupSize
);
1142 O
<< formatDec(OrMask
);
1146 O
<< "swizzle(" << IdSymbolic
[ID_BITMASK_PERM
];
1148 printSwizzleBitmask(AndMask
, OrMask
, XorMask
, O
);
1153 printU16ImmDecOperand(MI
, OpNo
, O
);
1157 void AMDGPUInstPrinter::printWaitFlag(const MCInst
*MI
, unsigned OpNo
,
1158 const MCSubtargetInfo
&STI
,
1160 AMDGPU::IsaVersion ISA
= AMDGPU::getIsaVersion(STI
.getCPU());
1162 unsigned SImm16
= MI
->getOperand(OpNo
).getImm();
1163 unsigned Vmcnt
, Expcnt
, Lgkmcnt
;
1164 decodeWaitcnt(ISA
, SImm16
, Vmcnt
, Expcnt
, Lgkmcnt
);
1166 bool NeedSpace
= false;
1168 if (Vmcnt
!= getVmcntBitMask(ISA
)) {
1169 O
<< "vmcnt(" << Vmcnt
<< ')';
1173 if (Expcnt
!= getExpcntBitMask(ISA
)) {
1176 O
<< "expcnt(" << Expcnt
<< ')';
1180 if (Lgkmcnt
!= getLgkmcntBitMask(ISA
)) {
1183 O
<< "lgkmcnt(" << Lgkmcnt
<< ')';
1187 void AMDGPUInstPrinter::printHwreg(const MCInst
*MI
, unsigned OpNo
,
1188 const MCSubtargetInfo
&STI
, raw_ostream
&O
) {
1189 using namespace llvm::AMDGPU::Hwreg
;
1191 unsigned SImm16
= MI
->getOperand(OpNo
).getImm();
1192 const unsigned Id
= (SImm16
& ID_MASK_
) >> ID_SHIFT_
;
1193 const unsigned Offset
= (SImm16
& OFFSET_MASK_
) >> OFFSET_SHIFT_
;
1194 const unsigned Width
= ((SImm16
& WIDTH_M1_MASK_
) >> WIDTH_M1_SHIFT_
) + 1;
1197 unsigned Last
= ID_SYMBOLIC_LAST_
;
1198 if (AMDGPU::isSI(STI
) || AMDGPU::isCI(STI
) || AMDGPU::isVI(STI
))
1199 Last
= ID_SYMBOLIC_FIRST_GFX9_
;
1200 if (ID_SYMBOLIC_FIRST_
<= Id
&& Id
< Last
&& IdSymbolic
[Id
]) {
1201 O
<< IdSymbolic
[Id
];
1205 if (Width
!= WIDTH_M1_DEFAULT_
+ 1 || Offset
!= OFFSET_DEFAULT_
) {
1206 O
<< ", " << Offset
<< ", " << Width
;
1211 #include "AMDGPUGenAsmWriter.inc"
1213 void R600InstPrinter::printInst(const MCInst
*MI
, raw_ostream
&O
,
1214 StringRef Annot
, const MCSubtargetInfo
&STI
) {
1216 printInstruction(MI
, O
);
1217 printAnnotation(O
, Annot
);
1220 void R600InstPrinter::printAbs(const MCInst
*MI
, unsigned OpNo
,
1222 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '|');
1225 void R600InstPrinter::printBankSwizzle(const MCInst
*MI
, unsigned OpNo
,
1227 int BankSwizzle
= MI
->getOperand(OpNo
).getImm();
1228 switch (BankSwizzle
) {
1230 O
<< "BS:VEC_021/SCL_122";
1233 O
<< "BS:VEC_120/SCL_212";
1236 O
<< "BS:VEC_102/SCL_221";
1249 void R600InstPrinter::printClamp(const MCInst
*MI
, unsigned OpNo
,
1251 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "_SAT");
1254 void R600InstPrinter::printCT(const MCInst
*MI
, unsigned OpNo
,
1256 unsigned CT
= MI
->getOperand(OpNo
).getImm();
1269 void R600InstPrinter::printKCache(const MCInst
*MI
, unsigned OpNo
,
1271 int KCacheMode
= MI
->getOperand(OpNo
).getImm();
1272 if (KCacheMode
> 0) {
1273 int KCacheBank
= MI
->getOperand(OpNo
- 2).getImm();
1274 O
<< "CB" << KCacheBank
<< ':';
1275 int KCacheAddr
= MI
->getOperand(OpNo
+ 2).getImm();
1276 int LineSize
= (KCacheMode
== 1) ? 16 : 32;
1277 O
<< KCacheAddr
* 16 << '-' << KCacheAddr
* 16 + LineSize
;
1281 void R600InstPrinter::printLast(const MCInst
*MI
, unsigned OpNo
,
1283 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "*", " ");
1286 void R600InstPrinter::printLiteral(const MCInst
*MI
, unsigned OpNo
,
1288 const MCOperand
&Op
= MI
->getOperand(OpNo
);
1289 assert(Op
.isImm() || Op
.isExpr());
1291 int64_t Imm
= Op
.getImm();
1292 O
<< Imm
<< '(' << BitsToFloat(Imm
) << ')';
1295 Op
.getExpr()->print(O
<< '@', &MAI
);
1299 void R600InstPrinter::printNeg(const MCInst
*MI
, unsigned OpNo
,
1301 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '-');
1304 void R600InstPrinter::printOMOD(const MCInst
*MI
, unsigned OpNo
,
1306 switch (MI
->getOperand(OpNo
).getImm()) {
1320 void R600InstPrinter::printMemOperand(const MCInst
*MI
, unsigned OpNo
,
1322 printOperand(MI
, OpNo
, O
);
1324 printOperand(MI
, OpNo
+ 1, O
);
1327 void R600InstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
1329 if (OpNo
>= MI
->getNumOperands()) {
1330 O
<< "/*Missing OP" << OpNo
<< "*/";
1334 const MCOperand
&Op
= MI
->getOperand(OpNo
);
1336 switch (Op
.getReg()) {
1337 // This is the default predicate state, so we don't need to print it.
1338 case R600::PRED_SEL_OFF
:
1342 O
<< getRegisterName(Op
.getReg());
1345 } else if (Op
.isImm()) {
1347 } else if (Op
.isFPImm()) {
1348 // We special case 0.0 because otherwise it will be printed as an integer.
1349 if (Op
.getFPImm() == 0.0)
1354 } else if (Op
.isExpr()) {
1355 const MCExpr
*Exp
= Op
.getExpr();
1356 Exp
->print(O
, &MAI
);
1362 void R600InstPrinter::printRel(const MCInst
*MI
, unsigned OpNo
,
1364 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, '+');
1367 void R600InstPrinter::printRSel(const MCInst
*MI
, unsigned OpNo
,
1369 unsigned Sel
= MI
->getOperand(OpNo
).getImm();
1397 void R600InstPrinter::printUpdateExecMask(const MCInst
*MI
, unsigned OpNo
,
1399 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "ExecMask,");
1402 void R600InstPrinter::printUpdatePred(const MCInst
*MI
, unsigned OpNo
,
1404 AMDGPUInstPrinter::printIfSet(MI
, OpNo
, O
, "Pred,");
1407 void R600InstPrinter::printWrite(const MCInst
*MI
, unsigned OpNo
,
1409 const MCOperand
&Op
= MI
->getOperand(OpNo
);
1410 if (Op
.getImm() == 0) {
1415 #include "R600GenAsmWriter.inc"