diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp | 93 |
1 files changed, 80 insertions, 13 deletions
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index fe62b8590fa0..e2186d4d533e 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -25,8 +25,9 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixedLenDisassembler.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/MC/MCInstrDesc.h" #include "llvm/Support/AMDHSAKernelDescriptor.h" -#include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -264,6 +265,34 @@ static DecodeStatus decodeOperand_VReg_1024(MCInst &Inst, return addOperand(Inst, DAsm->decodeSrcOp(AMDGPUDisassembler::OPW1024, Imm)); } +static DecodeStatus decodeOperand_f32kimm(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); + return addOperand(Inst, DAsm->decodeMandatoryLiteralConstant(Imm)); +} + +static DecodeStatus decodeOperand_f16kimm(MCInst &Inst, unsigned Imm, + uint64_t Addr, const void *Decoder) { + const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); + return addOperand(Inst, DAsm->decodeMandatoryLiteralConstant(Imm)); +} + +static DecodeStatus decodeOperand_VS_16_Deferred(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const void *Decoder) { + const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); + return addOperand( + Inst, DAsm->decodeSrcOp(llvm::AMDGPUDisassembler::OPW16, Imm, true)); +} + +static DecodeStatus decodeOperand_VS_32_Deferred(MCInst &Inst, unsigned Imm, + uint64_t Addr, + const void *Decoder) { + const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder); + return addOperand( + Inst, DAsm->decodeSrcOp(llvm::AMDGPUDisassembler::OPW32, Imm, true)); +} + static bool IsAGPROperand(const MCInst &Inst, int OpIdx, const MCRegisterInfo *MRI) { if (OpIdx < 0) @@ -626,6 +655,11 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, } } + int ImmLitIdx = + AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::imm); + if (Res && ImmLitIdx != -1) + Res = convertFMAanyK(MI, ImmLitIdx); + // if the opcode was not recognized we'll assume a Size of 4 bytes // (unless there are fewer bytes left) Size = Res ? (MaxInstBytesNum - Bytes.size()) @@ -693,22 +727,21 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { int D16Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::d16); + const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI.getOpcode()); + const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode = + AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode); + assert(VDataIdx != -1); - if (DMaskIdx == -1 || TFEIdx == -1) {// intersect_ray + if (BaseOpcode->BVH) { + // Add A16 operand for intersect_ray instructions if (AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::a16) > -1) { - assert(MI.getOpcode() == AMDGPU::IMAGE_BVH_INTERSECT_RAY_a16_sa || - MI.getOpcode() == AMDGPU::IMAGE_BVH_INTERSECT_RAY_a16_nsa || - MI.getOpcode() == AMDGPU::IMAGE_BVH64_INTERSECT_RAY_a16_sa || - MI.getOpcode() == AMDGPU::IMAGE_BVH64_INTERSECT_RAY_a16_nsa); addOperand(MI, MCOperand::createImm(1)); } return MCDisassembler::Success; } - const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(MI.getOpcode()); bool IsAtomic = (VDstIdx != -1); bool IsGather4 = MCII->get(MI.getOpcode()).TSFlags & SIInstrFlags::Gather4; - bool IsNSA = false; unsigned AddrSize = Info->VAddrDwords; @@ -717,8 +750,6 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dim); int A16Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::a16); - const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode = - AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode); const AMDGPU::MIMGDimInfo *Dim = AMDGPU::getMIMGDimInfoByEncoding(MI.getOperand(DimIdx).getImm()); const bool IsA16 = (A16Idx != -1 && MI.getOperand(A16Idx).getImm()); @@ -813,6 +844,24 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { return MCDisassembler::Success; } +DecodeStatus AMDGPUDisassembler::convertFMAanyK(MCInst &MI, + int ImmLitIdx) const { + assert(HasLiteral && "Should have decoded a literal"); + const MCInstrDesc &Desc = MCII->get(MI.getOpcode()); + unsigned DescNumOps = Desc.getNumOperands(); + assert(DescNumOps == MI.getNumOperands()); + for (unsigned I = 0; I < DescNumOps; ++I) { + auto &Op = MI.getOperand(I); + auto OpType = Desc.OpInfo[I].OperandType; + bool IsDeferredOp = (OpType == AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED || + OpType == AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED); + if (Op.isImm() && Op.getImm() == AMDGPU::EncValues::LITERAL_CONST && + IsDeferredOp) + Op.setImm(Literal); + } + return MCDisassembler::Success; +} + const char* AMDGPUDisassembler::getRegClassName(unsigned RegClassID) const { return getContext().getRegisterInfo()-> getRegClassName(&AMDGPUMCRegisterClasses[RegClassID]); @@ -1022,6 +1071,18 @@ MCOperand AMDGPUDisassembler::decodeOperand_SReg_512(unsigned Val) const { return decodeDstOp(OPW512, Val); } +// Decode Literals for insts which always have a literal in the encoding +MCOperand +AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const { + if (HasLiteral) { + if (Literal != Val) + return errOperand(Val, "More than one unique literal is illegal"); + } + HasLiteral = true; + Literal = Val; + return MCOperand::createImm(Literal); +} + MCOperand AMDGPUDisassembler::decodeLiteralConstant() const { // For now all literal constants are supposed to be unsigned integer // ToDo: deal with signed/unsigned 64-bit integer constants @@ -1235,7 +1296,8 @@ int AMDGPUDisassembler::getTTmpIdx(unsigned Val) const { return (TTmpMin <= Val && Val <= TTmpMax)? Val - TTmpMin : -1; } -MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val) const { +MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val, + bool MandatoryLiteral) const { using namespace AMDGPU::EncValues; assert(Val < 1024); // enum10 @@ -1264,8 +1326,13 @@ MCOperand AMDGPUDisassembler::decodeSrcOp(const OpWidthTy Width, unsigned Val) c if (INLINE_FLOATING_C_MIN <= Val && Val <= INLINE_FLOATING_C_MAX) return decodeFPImmed(Width, Val); - if (Val == LITERAL_CONST) - return decodeLiteralConstant(); + if (Val == LITERAL_CONST) { + if (MandatoryLiteral) + // Keep a sentinel value for deferred setting + return MCOperand::createImm(LITERAL_CONST); + else + return decodeLiteralConstant(); + } switch (Width) { case OPW32: |