53 #define DEBUG_TYPE "amdgpu-disassembler" 70 std::advance(
I, OpIdx);
77 uint64_t Addr,
const void *Decoder) {
80 APInt SignedOffset(18, Imm * 4,
true);
81 int64_t
Offset = (SignedOffset.
sext(64) + 4 + Addr).getSExtValue();
83 if (DAsm->tryAddingSymbolicOperand(Inst, Offset, Addr,
true, 2, 2))
88 #define DECODE_OPERAND(StaticDecoderName, DecoderName) \ 89 static DecodeStatus StaticDecoderName(MCInst &Inst, \ 92 const void *Decoder) { \ 93 auto DAsm = static_cast<const AMDGPUDisassembler*>(Decoder); \ 94 return addOperand(Inst, DAsm->DecoderName(Imm)); \ 97 #define DECODE_OPERAND_REG(RegClass) \ 98 DECODE_OPERAND(Decode##RegClass##RegisterClass, decodeOperand_##RegClass) 121 const void *Decoder) {
123 return addOperand(Inst, DAsm->decodeOperand_VSrc16(Imm));
129 const void *Decoder) {
131 return addOperand(Inst, DAsm->decodeOperand_VSrcV216(Imm));
134 #define DECODE_SDWA(DecName) \ 135 DECODE_OPERAND(decodeSDWA##DecName, decodeSDWA##DecName) 141 #include "AMDGPUGenDisassemblerTables.inc" 149 const auto Res = support::endian::read<T, support::endianness::little>(Bytes.
data());
150 Bytes = Bytes.
slice(
sizeof(
T));
157 uint64_t Address)
const {
162 const auto SavedBytes = Bytes;
183 const unsigned MaxInstBytesNum = (std::min)((
size_t)8, Bytes_.
size());
184 Bytes = Bytes_.
slice(0, MaxInstBytesNum);
193 if (Bytes.
size() >= 8) {
194 const uint64_t QW = eatBytes<uint64_t>(Bytes);
199 if (Res) { IsSDWA =
true;
break; }
202 if (Res) { IsSDWA =
true;
break; }
205 Res =
tryDecodeInst(DecoderTableGFX80_UNPACKED64, MI, QW, Address);
221 Bytes = Bytes_.
slice(0, MaxInstBytesNum);
224 if (Bytes.
size() < 4)
break;
225 const uint32_t DW = eatBytes<uint32_t>(Bytes);
235 if (Bytes.
size() < 4)
break;
236 const uint64_t QW = ((uint64_t)eatBytes<uint32_t>(Bytes) << 32) | DW;
246 if (Res && (MI.
getOpcode() == AMDGPU::V_MAC_F32_e64_vi ||
247 MI.
getOpcode() == AMDGPU::V_MAC_F32_e64_si ||
248 MI.
getOpcode() == AMDGPU::V_MAC_F16_e64_vi ||
249 MI.
getOpcode() == AMDGPU::V_FMAC_F32_e64_vi)) {
252 AMDGPU::OpName::src2_modifiers);
264 Size = Res ? (MaxInstBytesNum - Bytes.
size())
265 : std::min((
size_t)4, Bytes_.
size());
279 AMDGPU::OpName::sdst);
294 AMDGPU::OpName::vdst);
297 AMDGPU::OpName::vdata);
300 AMDGPU::OpName::dmask);
303 AMDGPU::OpName::tfe);
305 AMDGPU::OpName::d16);
311 bool IsAtomic = (VDstIdx != -1);
324 DstSize = (DstSize + 1) / 2;
344 auto RCID = MCII->get(NewOpcode).OpInfo[VDataIdx].RegClass;
348 unsigned VdataSub0 = MRI.
getSubReg(Vdata0, AMDGPU::sub0);
349 Vdata0 = (VdataSub0 != 0)? VdataSub0 : Vdata0;
354 if (NewVdata == AMDGPU::NoRegister) {
381 const Twine& ErrMsg)
const {
396 unsigned Val)
const {
397 const auto& RegCl = AMDGPUMCRegisterClasses[RegClassID];
398 if (Val >= RegCl.getNumRegs())
400 ": unknown register " +
Twine(Val));
406 unsigned Val)
const {
410 switch (SRegClassID) {
411 case AMDGPU::SGPR_32RegClassID:
412 case AMDGPU::TTMP_32RegClassID:
414 case AMDGPU::SGPR_64RegClassID:
415 case AMDGPU::TTMP_64RegClassID:
418 case AMDGPU::SGPR_128RegClassID:
419 case AMDGPU::TTMP_128RegClassID:
422 case AMDGPU::SGPR_256RegClassID:
423 case AMDGPU::TTMP_256RegClassID:
426 case AMDGPU::SGPR_512RegClassID:
427 case AMDGPU::TTMP_512RegClassID:
436 if (Val % (1 << shift)) {
438 <<
": scalar reg isn't aligned " << Val;
493 unsigned Val)
const {
499 unsigned Val)
const {
529 if (Bytes.
size() < 4) {
530 return errOperand(0,
"cannot read literal, inst bytes left " +
534 Literal = eatBytes<uint32_t>(Bytes);
540 using namespace AMDGPU::EncValues;
593 return 0x3fc45f306dc9c882;
651 return VGPR_32RegClassID;
652 case OPW64:
return VReg_64RegClassID;
653 case OPW128:
return VReg_128RegClassID;
666 return SGPR_32RegClassID;
667 case OPW64:
return SGPR_64RegClassID;
668 case OPW128:
return SGPR_128RegClassID;
669 case OPW256:
return SGPR_256RegClassID;
670 case OPW512:
return SGPR_512RegClassID;
683 return TTMP_32RegClassID;
684 case OPW64:
return TTMP_64RegClassID;
685 case OPW128:
return TTMP_128RegClassID;
686 case OPW256:
return TTMP_256RegClassID;
687 case OPW512:
return TTMP_512RegClassID;
692 using namespace AMDGPU::EncValues;
697 return (TTmpMin <= Val && Val <= TTmpMax)? Val - TTmpMin : -1;
701 using namespace AMDGPU::EncValues;
740 using namespace AMDGPU::EncValues;
806 const unsigned Val)
const {
808 using namespace AMDGPU::EncValues;
856 "SDWAVopcDst should be present only on GFX9");
888 uint64_t ,
bool IsBranch,
889 uint64_t , uint64_t ) {
890 using SymbolInfoTy = std::tuple<uint64_t, StringRef, uint8_t>;
891 using SectionSymbolsTy = std::vector<SymbolInfoTy>;
897 auto *Symbols =
static_cast<SectionSymbolsTy *
>(DisInfo);
901 auto Result =
std::find_if(Symbols->begin(), Symbols->end(),
902 [Value](
const SymbolInfoTy& Val) {
903 return std::get<0>(Val) == static_cast<uint64_t>(Value)
906 if (Result != Symbols->end()) {
907 auto *Sym = Ctx.getOrCreateSymbol(std::get<1>(*Result));
930 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
MCOperand createRegOperand(unsigned int RegId) const
static int64_t getInlineImmVal16(unsigned Imm)
MCOperand decodeOperand_SReg_64_XEXEC(unsigned Val) const
MCOperand decodeOperand_VGPR_32(unsigned Val) const
Target & getTheGCNTarget()
The target for GCN GPUs.
MCOperand decodeSDWASrc(const OpWidthTy Width, unsigned Val) const
bool hasPackedD16(const MCSubtargetInfo &STI)
APInt sext(unsigned width) const
Sign extend to a new width.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
#define DECODE_OPERAND_REG(RegClass)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
MCOperand decodeOperand_VReg_64(unsigned Val) const
MCOperand decodeOperand_VSrcV216(unsigned Val) const
DecodeStatus
Ternary decode status.
static MCOperand decodeFPImmed(OpWidthTy Width, unsigned Imm)
MCOperand decodeOperand_VS_128(unsigned Val) const
static MCOperand createExpr(const MCExpr *Val)
MCOperand decodeOperand_SReg_512(unsigned Val) const
Superclass for all disassemblers.
raw_ostream * CommentStream
MCOperand decodeDstOp(const OpWidthTy Width, unsigned Val) const
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
const char * getRegClassName(unsigned RegClassID) const
static T eatBytes(ArrayRef< uint8_t > &Bytes)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
MCOperand decodeOperand_VS_32(unsigned Val) const
MCOperand decodeLiteralConstant() const
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
MCOperand decodeOperand_SReg_128(unsigned Val) const
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const FeatureBitset & getFeatureBits() const
MCOperand decodeSDWAVopcDst(unsigned Val) const
MCOperand errOperand(unsigned V, const Twine &ErrMsg) const
int(* LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, void *TagBuf)
The type for the operand information call back function.
void tryAddingPcLoadReferenceComment(raw_ostream &cStream, int64_t Value, uint64_t Address) override
Try to add a comment on the PC-relative load.
int getMaskedMIMGOp(unsigned Opc, unsigned NewChannels)
This file implements a class to represent arbitrary precision integral constant values and operations...
unsigned getReg() const
Returns the register number.
TargetRegisterInfo interface that is implemented by all hw codegen targets.
static int64_t getInlineImmVal32(unsigned Imm)
Context object for machine code objects.
DecodeStatus convertSDWAInst(MCInst &MI) const
const MCSubtargetInfo & STI
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
MCOperand decodeSDWASrc32(unsigned Val) const
static MCSymbolizer * createAMDGPUSymbolizer(const Triple &, LLVMOpInfoCallback, LLVMSymbolLookupCallback, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
iterator insert(iterator I, const MCOperand &Op)
Instances of this class represent a single low-level machine instruction.
DecodeStatus tryDecodeInst(const uint8_t *Table, MCInst &MI, uint64_t Inst, uint64_t Address) const
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
unsigned getVgprClassId(const OpWidthTy Width) const
MCOperand decodeOperand_VReg_128(unsigned Val) const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
MCOperand decodeOperand_SReg_256(unsigned Val) const
MCOperand decodeOperand_SReg_32(unsigned Val) const
Symbolize and annotate disassembled instructions.
size_t size() const
size - Get the array size.
DecodeStatus convertMIMGInst(MCInst &MI) const
MCOperand decodeOperand_VS_64(unsigned Val) const
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
unsigned getNumOperands() const
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
static int64_t getInlineImmVal64(unsigned Imm)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
MCOperand decodeSDWASrc16(unsigned Val) const
void setOpcode(unsigned Op)
unsigned countPopulation(T Value)
Count the number of set bits in a value.
const MCOperand & getOperand(unsigned i) const
MCContext & getContext() const
MCOperand decodeOperand_SReg_32_XM0_XEXEC(unsigned Val) const
MCOperand decodeSrcOp(const OpWidthTy Width, unsigned Val) const
static DecodeStatus decodeOperand_VSrc16(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
uint64_t DoubleToBits(double Double)
This function takes a double and returns the bit equivalent 64-bit integer.
static MCOperand decodeIntImmed(unsigned Imm)
#define DECODE_SDWA(DecName)
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t InstSize) override
Try to add a symbolic operand instead of Value to the MCInst.
Provides AMDGPU specific target descriptions.
static DecodeStatus decodeOperand_VSrcV216(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder)
void LLVMInitializeAMDGPUDisassembler()
MCOperand decodeOperand_SReg_32_XEXEC_HI(unsigned Val) const
This file contains declaration for AMDGPU ISA disassembler.
MCOperand decodeOperand_VSrc16(unsigned Val) const
Generic base class for all target subtargets.
unsigned getSgprClassId(const OpWidthTy Width) const
MCOperand createSRegOperand(unsigned SRegClassID, unsigned Val) const
static int insertNamedMCOperand(MCInst &MI, const MCOperand &Op, uint16_t NameIdx)
static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn)
RegisterMCSymbolizer - Register an MCSymbolizer implementation for the given target.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCOperand decodeOperand_SReg_64(unsigned Val) const
const MCRegisterInfo * getRegisterInfo() const
AMDGPUDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, MCInstrInfo const *MCII)
MCOperand decodeOperand_VReg_96(unsigned Val) const
LLVM Value Representation.
unsigned getTtmpClassId(const OpWidthTy Width) const
MCOperand decodeSpecialReg64(unsigned Val) const
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg...
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
DecodeStatus getInstruction(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &WS, raw_ostream &CS) const override
Returns the disassembly of a single instruction.
unsigned getOpcode() const
MCOperand decodeSpecialReg32(unsigned Val) const
int getTTmpIdx(unsigned Val) const
Instances of this class represent operands of the MCInst class.
const char *(* LLVMSymbolLookupCallback)(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
The type for the symbol lookup function.
static MCDisassembler * createAMDGPUDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static MCOperand createImm(int64_t Val)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.