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;
62 void getSOPPBrEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
63 SmallVectorImpl<MCFixup> &Fixups,
64 const MCSubtargetInfo &STI)
const;
66 void getSMEMOffsetEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
67 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI)
const;
70 void getSDWASrcEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
71 SmallVectorImpl<MCFixup> &Fixups,
72 const MCSubtargetInfo &STI)
const;
74 void getSDWAVopcDstEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
75 SmallVectorImpl<MCFixup> &Fixups,
76 const MCSubtargetInfo &STI)
const;
78 void getAVOperandEncoding(
const MCInst &
MI,
unsigned OpNo, APInt &
Op,
79 SmallVectorImpl<MCFixup> &Fixups,
80 const MCSubtargetInfo &STI)
const;
83 uint64_t getImplicitOpSelHiEncoding(
int Opcode)
const;
84 void getMachineOpValueCommon(
const MCInst &
MI,
const MCOperand &MO,
85 unsigned OpNo, APInt &
Op,
86 SmallVectorImpl<MCFixup> &Fixups,
87 const MCSubtargetInfo &STI)
const;
90 std::optional<uint64_t>
91 getLitEncoding(
const MCInstrDesc &
Desc,
const MCOperand &MO,
unsigned OpNo,
92 const MCSubtargetInfo &STI,
93 bool HasMandatoryLiteral =
false)
const;
95 void getBinaryCodeForInstr(
const MCInst &
MI, SmallVectorImpl<MCFixup> &Fixups,
96 APInt &Inst, APInt &Scratch,
97 const MCSubtargetInfo &STI)
const;
104 return new AMDGPUMCCodeEmitter(MCII, *Ctx.getRegisterInfo());
114template <
typename IntTy>
116 if (Imm >= 0 && Imm <= 64)
119 if (Imm >= -16 && Imm <= -1)
120 return 192 + std::abs(Imm);
155 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
168 case 0x3F00:
return 240;
169 case 0xBF00:
return 241;
170 case 0x3F80:
return 242;
171 case 0xBF80:
return 243;
172 case 0x4000:
return 244;
173 case 0xC000:
return 245;
174 case 0x4080:
return 246;
175 case 0xC080:
return 247;
176 case 0x3E22:
return 248;
211 if (Val == 0x3e22f983 &&
212 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
252 if (Val == 0x3fc45f306dc9c882 &&
253 STI.
hasFeature(AMDGPU::FeatureInv2PiInlineImm))
258 bool CanUse64BitLiterals =
259 STI.
hasFeature(AMDGPU::Feature64BitLiterals) &&
262 return CanUse64BitLiterals &&
Lo_32(Val) ? 254 : 255;
269std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
272 const MCOperandInfo &OpInfo =
Desc.operands()[OpNo];
275 if (!MO.
getExpr()->evaluateAsAbsolute(Imm))
308 return (HasMandatoryLiteral && Enc == 255) ? 254 : Enc;
354uint64_t AMDGPUMCCodeEmitter::getImplicitOpSelHiEncoding(
int Opcode)
const {
355 using namespace AMDGPU::VOP3PEncoding;
370 Desc.hasImplicitDefOfPhysReg(AMDGPU::EXEC);
373void AMDGPUMCCodeEmitter::encodeInstruction(
const MCInst &
MI,
374 SmallVectorImpl<char> &CB,
375 SmallVectorImpl<MCFixup> &Fixups,
376 const MCSubtargetInfo &STI)
const {
377 int Opcode =
MI.getOpcode();
378 APInt Encoding, Scratch;
379 getBinaryCodeForInstr(
MI, Fixups, Encoding, Scratch, STI);
380 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
381 unsigned bytes =
Desc.getSize();
386 Opcode == AMDGPU::V_ACCVGPR_READ_B32_vi ||
387 Opcode == AMDGPU::V_ACCVGPR_WRITE_B32_vi) &&
394 Encoding |= getImplicitOpSelHiEncoding(Opcode);
404 assert((Encoding & 0xFF) == 0);
405 Encoding |=
MRI.getEncodingValue(AMDGPU::EXEC_LO) &
409 for (
unsigned i = 0; i < bytes; i++) {
415 int vaddr0 = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
416 AMDGPU::OpName::vaddr0);
417 int srsrc = AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
418 AMDGPU::OpName::srsrc);
419 assert(vaddr0 >= 0 && srsrc > vaddr0);
420 unsigned NumExtraAddrs = srsrc - vaddr0 - 1;
421 unsigned NumPadding = (-NumExtraAddrs) & 3;
423 for (
unsigned i = 0; i < NumExtraAddrs; ++i) {
424 getMachineOpValue(
MI,
MI.getOperand(vaddr0 + 1 + i), Encoding, Fixups,
431 if ((bytes > 8 && STI.
hasFeature(AMDGPU::FeatureVOP3Literal)) ||
432 (bytes > 4 && !STI.
hasFeature(AMDGPU::FeatureVOP3Literal)))
440 for (
unsigned i = 0, e =
Desc.getNumOperands(); i < e; ++i) {
447 const MCOperand &
Op =
MI.getOperand(i);
448 auto Enc = getLitEncoding(
Desc,
Op, i, STI);
449 if (!Enc || (*Enc != 255 && *Enc != 254))
457 else if (
Op.isExpr()) {
480void AMDGPUMCCodeEmitter::getSOPPBrEncoding(
const MCInst &
MI,
unsigned OpNo,
482 SmallVectorImpl<MCFixup> &Fixups,
483 const MCSubtargetInfo &STI)
const {
484 const MCOperand &MO =
MI.getOperand(OpNo);
487 const MCExpr *Expr = MO.
getExpr();
491 getMachineOpValue(
MI, MO,
Op, Fixups, STI);
495void AMDGPUMCCodeEmitter::getSMEMOffsetEncoding(
496 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
497 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
498 auto Offset =
MI.getOperand(OpNo).getImm();
504void AMDGPUMCCodeEmitter::getSDWASrcEncoding(
const MCInst &
MI,
unsigned OpNo,
506 SmallVectorImpl<MCFixup> &Fixups,
507 const MCSubtargetInfo &STI)
const {
508 using namespace AMDGPU::SDWA;
512 const MCOperand &MO =
MI.getOperand(OpNo);
516 RegEnc |=
MRI.getEncodingValue(
Reg);
517 RegEnc &= SDWA9EncValues::SRC_VGPR_MASK;
519 RegEnc |= SDWA9EncValues::SRC_SGPR_MASK;
524 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
525 auto Enc = getLitEncoding(
Desc, MO, OpNo, STI);
526 if (Enc && *Enc != 255) {
527 Op = *Enc | SDWA9EncValues::SRC_SGPR_MASK;
535void AMDGPUMCCodeEmitter::getSDWAVopcDstEncoding(
536 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
537 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
538 using namespace AMDGPU::SDWA;
542 const MCOperand &MO =
MI.getOperand(OpNo);
545 if (
Reg != AMDGPU::VCC &&
Reg != AMDGPU::VCC_LO) {
546 RegEnc |=
MRI.getEncodingValue(
Reg);
547 RegEnc &= SDWA9EncValues::VOPC_DST_SGPR_MASK;
548 RegEnc |= SDWA9EncValues::VOPC_DST_VCC_MASK;
553void AMDGPUMCCodeEmitter::getAVOperandEncoding(
554 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
555 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
556 MCRegister
Reg =
MI.getOperand(OpNo).getReg();
557 unsigned Enc =
MRI.getEncodingValue(
Reg);
567 Op = Idx | (IsVGPROrAGPR << 8) | (IsAGPR << 9);
594void AMDGPUMCCodeEmitter::getMachineOpValue(
const MCInst &
MI,
595 const MCOperand &MO, APInt &
Op,
596 SmallVectorImpl<MCFixup> &Fixups,
597 const MCSubtargetInfo &STI)
const {
599 unsigned Enc =
MRI.getEncodingValue(MO.
getReg());
603 Op = Idx | (IsVGPROrAGPR << 8);
606 unsigned OpNo = &MO -
MI.begin();
607 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
610void AMDGPUMCCodeEmitter::getMachineOpValueT16(
611 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
612 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
613 const MCOperand &MO =
MI.getOperand(OpNo);
615 unsigned Enc =
MRI.getEncodingValue(MO.
getReg());
618 Op = Idx | (IsVGPR << 8);
621 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
628 if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
MI.getOpcode(),
629 AMDGPU::OpName::src0_modifiers)) {
630 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src0);
632 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::vdst);
633 if (VDstMOIdx != -1) {
634 auto DstReg =
MI.getOperand(VDstMOIdx).getReg();
638 }
else if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
639 MI.getOpcode(), AMDGPU::OpName::src1_modifiers))
640 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src1);
641 else if ((
int)OpNo == AMDGPU::getNamedOperandIdx(
642 MI.getOpcode(), AMDGPU::OpName::src2_modifiers))
643 SrcMOIdx = AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::src2);
647 const MCOperand &SrcMO =
MI.getOperand(SrcMOIdx);
650 auto SrcReg = SrcMO.
getReg();
657void AMDGPUMCCodeEmitter::getMachineOpValueT16Lo128(
658 const MCInst &
MI,
unsigned OpNo, APInt &
Op,
659 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
660 const MCOperand &MO =
MI.getOperand(OpNo);
662 uint16_t Encoding =
MRI.getEncodingValue(MO.
getReg());
667 Op = (IsVGPR ? 0x100 : 0) | (IsHi ? 0x80 : 0) | RegIdx;
670 getMachineOpValueCommon(
MI, MO, OpNo,
Op, Fixups, STI);
673void AMDGPUMCCodeEmitter::getMachineOpValueCommon(
674 const MCInst &
MI,
const MCOperand &MO,
unsigned OpNo, APInt &
Op,
675 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
676 bool isLikeImm =
false;
682 }
else if (MO.
isExpr() && MO.
getExpr()->evaluateAsAbsolute(Val)) {
696 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
704 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
706 bool HasMandatoryLiteral =
708 if (
auto Enc = getLitEncoding(
Desc, MO, OpNo, STI, HasMandatoryLiteral)) {
724#include "AMDGPUGenMCCodeEmitter.inc"
unsigned const MachineRegisterInfo * MRI
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 bool isVCMPX64(const MCInstrDesc &Desc)
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...
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.
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
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(uint64_t Opcode, OpName NamedIdx)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
std::optional< unsigned > getInlineEncodingV2F16(uint32_t Literal)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ 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 > getInlineEncodingV2I16(uint32_t Literal)
bool isVI(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type)
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)
@ C
The default llvm calling convention, compatible with C.
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)