36 const MCRegisterInfo &MRI;
37 const MCInstrInfo &MCII;
40 AMDGPUMCCodeEmitter(
const MCInstrInfo &MCII,
const MCRegisterInfo &MRI)
41 : MRI(MRI), MCII(MCII) {}
44 void encodeInstruction(
const MCInst &
MI, SmallVectorImpl<char> &CB,
45 SmallVectorImpl<MCFixup> &Fixups,
46 const MCSubtargetInfo &STI)
const override;
48 void getMachineOpValue(
const MCInst &
MI,
const MCOperand &MO, APInt &
Op,
49 SmallVectorImpl<MCFixup> &Fixups,
50 const MCSubtargetInfo &STI)
const;
52 void getMachineOpValueT16(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
53 SmallVectorImpl<MCFixup> &Fixups,
54 const MCSubtargetInfo &STI)
const;
56 void getMachineOpValueT16Lo128(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
57 SmallVectorImpl<MCFixup> &Fixups,
58 const MCSubtargetInfo &STI)
const;
60 void getMachineOpValueRsrcRegOp(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
61 SmallVectorImpl<MCFixup> &Fixups,
62 const MCSubtargetInfo &STI)
const;
66 void getSOPPBrEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
67 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI)
const;
70 void getSMEMOffsetEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
71 SmallVectorImpl<MCFixup> &Fixups,
72 const MCSubtargetInfo &STI)
const;
74 void getSDWASrcEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
75 SmallVectorImpl<MCFixup> &Fixups,
76 const MCSubtargetInfo &STI)
const;
78 void getSDWAVopcDstEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
79 SmallVectorImpl<MCFixup> &Fixups,
80 const MCSubtargetInfo &STI)
const;
82 void getAVOperandEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
83 SmallVectorImpl<MCFixup> &Fixups,
84 const MCSubtargetInfo &STI)
const;
87 uint64_t getImplicitOpSelHiEncoding(
int Opcode)
const;
88 void getMachineOpValueCommon(
const MCInst &
MI,
const MCOperand &MO,
89 unsigned OpNo, APInt &
Op,
90 SmallVectorImpl<MCFixup> &Fixups,
91 const MCSubtargetInfo &STI)
const;
94 std::optional<uint64_t>
95 getLitEncoding(
const MCInstrDesc &
Desc,
const MCOperand &MO,
unsigned OpNo,
96 const MCSubtargetInfo &STI,
97 bool HasMandatoryLiteral =
false)
const;
99 void getBinaryCodeForInstr(
const MCInst &
MI, SmallVectorImpl<MCFixup> &Fixups,
100 APInt &Inst, APInt &Scratch,
101 const MCSubtargetInfo &STI)
const;
103 template <
bool HasSrc0,
bool HasSrc1,
bool HasSrc2>
104 APInt postEncodeVOP3(
const MCInst &
MI, APInt EncodedValue,
105 const MCSubtargetInfo &STI)
const;
107 APInt postEncodeVOPCX(
const MCInst &
MI, APInt EncodedValue,
108 const MCSubtargetInfo &STI)
const;
115 return new AMDGPUMCCodeEmitter(MCII, *Ctx.getRegisterInfo());
125template <
typename IntTy>
127 if (
Imm >= 0 &&
Imm <= 64)
130 if (
Imm >= -16 &&
Imm <= -1)
131 return 192 + std::abs(
Imm);
166 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
179 case 0x3F00:
return 240;
180 case 0xBF00:
return 241;
181 case 0x3F80:
return 242;
182 case 0xBF80:
return 243;
183 case 0x4000:
return 244;
184 case 0xC000:
return 245;
185 case 0x4080:
return 246;
186 case 0xC080:
return 247;
187 case 0x3E22:
return 248;
222 if (Val == 0x3e22f983 &&
223 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
263 if (Val == 0x3fc45f306dc9c882 &&
264 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
269 bool CanUse64BitLiterals = STI.
hasFeature(AMDGPU::Feature64BitLiterals) &&
272 return CanUse64BitLiterals &&
Lo_32(Val) ? 254 : 255;
279std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
282 const MCOperandInfo &OpInfo =
Desc.operands()[OpNo];
291 if (STI.
hasFeature(AMDGPU::Feature64BitLiterals) &&
330 return (HasMandatoryLiteral && Enc == 255) ? 254 : Enc;
387uint64_t AMDGPUMCCodeEmitter::getImplicitOpSelHiEncoding(
int Opcode)
const {
388 using namespace AMDGPU::VOP3PEncoding;
401void AMDGPUMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
402 SmallVectorImpl<char> &CB,
403 SmallVectorImpl<MCFixup> &Fixups,
404 const MCSubtargetInfo &STI)
const {
405 int Opcode =
MI.getOpcode();
406 APInt Encoding, Scratch;
407 getBinaryCodeForInstr(
MI, Fixups, Encoding, Scratch, STI);
408 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
409 unsigned bytes =
Desc.getSize();
414 Opcode == AMDGPU::V_ACCVGPR_WRITE_B32_vi) &&
424 Encoding |= getImplicitOpSelHiEncoding(Opcode);
427 for (
unsigned i = 0; i < bytes; i++) {
433 int vaddr0 = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
434 AMDGPU::OpName::vaddr0);
435 int srsrc = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
436 AMDGPU::OpName::srsrc);
437 assert(vaddr0 >= 0 && srsrc > vaddr0);
438 unsigned NumExtraAddrs = srsrc - vaddr0 - 1;
439 unsigned NumPadding = (-NumExtraAddrs) & 3;
441 for (
unsigned i = 0; i < NumExtraAddrs; ++i) {
442 getMachineOpValue(
MI,
MI.getOperand(vaddr0 + 1 + i), Encoding, Fixups,
449 if ((bytes > 8 && STI.
hasFeature(AMDGPU::FeatureVOP3Literal)) ||
450 (bytes > 4 && !STI.
hasFeature(AMDGPU::FeatureVOP3Literal)))
458 for (
unsigned i = 0, e =
Desc.getNumOperands(); i < e; ++i) {
465 const MCOperand &
Op =
MI.getOperand(i);
466 auto Enc = getLitEncoding(
Desc,
Op, i, STI);
467 if (!Enc || (*Enc != 255 && *Enc != 254))
476 else if (
Op.isExpr()) {
501void AMDGPUMCCodeEmitter::getSOPPBrEncoding(
const MCInst &
MI,
unsigned OpNo,
503 SmallVectorImpl<MCFixup> &Fixups,
504 const MCSubtargetInfo &STI)
const {
505 const MCOperand &MO =
MI.getOperand(OpNo);
508 const MCExpr *Expr = MO.
getExpr();
512 getMachineOpValue(
MI, MO,
Op, Fixups, STI);
516void AMDGPUMCCodeEmitter::getSMEMOffsetEncoding(
517 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
518 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
525void AMDGPUMCCodeEmitter::getSDWASrcEncoding(
const MCInst &
MI,
unsigned OpNo,
527 SmallVectorImpl<MCFixup> &Fixups,
528 const MCSubtargetInfo &STI)
const {
529 using namespace AMDGPU::SDWA;
533 const MCOperand &MO =
MI.getOperand(OpNo);
538 RegEnc &= SDWA9EncValues::SRC_VGPR_MASK;
540 RegEnc |= SDWA9EncValues::SRC_SGPR_MASK;
545 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
546 auto Enc = getLitEncoding(
Desc, MO, OpNo, STI);
547 if (Enc && *Enc != 255) {
548 Op = *Enc | SDWA9EncValues::SRC_SGPR_MASK;
556void AMDGPUMCCodeEmitter::getSDWAVopcDstEncoding(
557 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
558 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
559 using namespace AMDGPU::SDWA;
563 const MCOperand &MO =
MI.getOperand(OpNo);
566 if (
Reg != AMDGPU::VCC &&
Reg != AMDGPU::VCC_LO) {
568 RegEnc &= SDWA9EncValues::VOPC_DST_SGPR_MASK;
569 RegEnc |= SDWA9EncValues::VOPC_DST_VCC_MASK;
574void AMDGPUMCCodeEmitter::getAVOperandEncoding(
575 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
576 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
577 MCRegister
Reg =
MI.getOperand(OpNo).getReg();
588 Op =
Idx | (IsVGPROrAGPR << 8) | (IsAGPR << 9);
615void AMDGPUMCCodeEmitter::getMachineOpValue(
const MCInst &
MI,
616 const MCOperand &MO, APInt &
Op,
617 SmallVectorImpl<MCFixup> &Fixups,
618 const MCSubtargetInfo &STI)
const {
624 Op =
Idx | (IsVGPROrAGPR << 8);
627 unsigned OpNo = &MO -
MI.begin();
628 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
631void AMDGPUMCCodeEmitter::getMachineOpValueT16(
632 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
633 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
634 const MCOperand &MO =
MI.getOperand(OpNo);
639 Op =
Idx | (IsVGPR << 8);
642 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
649 if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
650 AMDGPU::OpName::src0_modifiers)) {
651 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
653 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdst);
654 if (VDstMOIdx != -1) {
655 auto DstReg =
MI.getOperand(VDstMOIdx).getReg();
659 }
else if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
660 MI.getOpcode(), AMDGPU::OpName::src1_modifiers))
661 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src1);
662 else if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
663 MI.getOpcode(), AMDGPU::OpName::src2_modifiers))
664 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src2);
668 const MCOperand &SrcMO =
MI.getOperand(SrcMOIdx);
671 auto SrcReg = SrcMO.
getReg();
678void AMDGPUMCCodeEmitter::getMachineOpValueT16Lo128(
679 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
680 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
681 const MCOperand &MO =
MI.getOperand(OpNo);
688 Op = (IsVGPR ? 0x100 : 0) | (IsHi ? 0x80 : 0) | RegIdx;
691 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
697void AMDGPUMCCodeEmitter::getMachineOpValueRsrcRegOp(
698 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
699 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
700 const MCOperand &MO =
MI.getOperand(OpNo);
707 Op =
Idx | IsVGPROrAGPR << 8 | IsSReg32 << 7;
710void AMDGPUMCCodeEmitter::getMachineOpValueCommon(
711 const MCInst &
MI,
const MCOperand &MO,
unsigned OpNo, APInt &
Op,
712 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
713 bool isLikeImm =
false;
719 }
else if (MO.
isExpr() && MO.
getExpr()->evaluateAsAbsolute(Val)) {
733 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
741 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
743 bool HasMandatoryLiteral =
745 if (
auto Enc = getLitEncoding(
Desc, MO, OpNo, STI, HasMandatoryLiteral)) {
761template <
bool HasSrc0,
bool HasSrc1,
bool HasSrc2>
762APInt AMDGPUMCCodeEmitter::postEncodeVOP3(
const MCInst &
MI, APInt EncodedValue,
763 const MCSubtargetInfo &STI)
const {
768 constexpr uint64_t InlineImmediate0 = 0x80;
770 EncodedValue |= InlineImmediate0 << 32;
772 EncodedValue |= InlineImmediate0 << 41;
774 EncodedValue |= InlineImmediate0 << 50;
778APInt AMDGPUMCCodeEmitter::postEncodeVOPCX(
const MCInst &
MI, APInt EncodedValue,
779 const MCSubtargetInfo &STI)
const {
790 return postEncodeVOP3<true, true, false>(
MI, EncodedValue, STI);
793#include "AMDGPUGenMCCodeEmitter.inc"
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint32_t getLit64Encoding(const MCInstrDesc &Desc, uint64_t Val, const MCSubtargetInfo &STI, bool IsFP)
static uint32_t getLit16IntEncoding(uint32_t Val, const MCSubtargetInfo &STI)
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
static uint32_t getLitBF16Encoding(uint16_t Val)
static uint32_t getLit16Encoding(uint16_t Val, const MCSubtargetInfo &STI)
static uint32_t getIntInlineImmEncoding(IntTy Imm)
static bool needsPCRel(const MCExpr *Expr)
static uint32_t getLit32Encoding(uint32_t Val, const MCSubtargetInfo &STI)
Provides AMDGPU specific target descriptions.
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
LLVM_ABI uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX) const
If this value is smaller than the specified limit, return it, otherwise return the limit value.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
static MCFixupKind getDataKindForSize(unsigned Size)
Return the generic fixup kind for a value with the given size.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Describe properties that are true of each instruction in the target description file.
LLVM_ABI bool hasImplicitDefOfPhysReg(MCRegister Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
uint8_t OperandType
Information about the type of the operand.
Instances of this class represent operands of the MCInst class.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
static AMDGPUMCExpr::Specifier getSpecifier(const MCSymbolRefExpr *SRE)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
@ fixup_si_sopp_br
16-bit PC relative fixup for SOPP branch instructions.
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
bool hasNoOpSelHi(unsigned Opc)
Returns true if this VOP3P opcode has no op_sel_hi field, in which case those bits are encoded as zer...
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY AMDGPUMCExpr::VariantKind getExprKind(const MCExpr *Expr)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
std::optional< unsigned > getInlineEncodingV2F16(uint32_t Literal)
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_IMM_NOINLINE_FP16
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT64
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
std::optional< unsigned > getPKFMACF16InlineEncoding(uint32_t Literal, bool IsGFX11Plus)
std::optional< unsigned > getInlineEncodingV2I16(uint32_t Literal)
bool isVI(const MCSubtargetInfo &STI)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
std::optional< unsigned > getInlineEncodingV2BF16(uint32_t Literal)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
constexpr bool isVOP3(const T &...O)
constexpr bool isVOP3P(const T &...O)
constexpr bool isVOP3Like(const T &...O)
constexpr bool isMIMG(const T &...O)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
To bit_cast(const From &from) noexcept
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
MCCodeEmitter * createAMDGPUMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)