diff options
Diffstat (limited to 'llvm/lib')
4 files changed, 44 insertions, 15 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 5d5fe6ecee7..8052ea8253e 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -911,6 +911,10 @@ public: return AMDGPU::hasMIMG_R128(getSTI()); } + bool hasPackedD16() const { + return AMDGPU::hasPackedD16(getSTI()); + } + bool isSI() const { return AMDGPU::isSI(getSTI()); } @@ -2309,7 +2313,12 @@ bool AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst) { if (DMask == 0) DMask = 1; - return (VDataSize / 4) == countPopulation(DMask) + TFESize; + unsigned DataSize = countPopulation(DMask); + if ((Desc.TSFlags & SIInstrFlags::D16) != 0 && hasPackedD16()) { + DataSize = (DataSize + 1) / 2; + } + + return (VDataSize / 4) == DataSize + TFESize; } bool AMDGPUAsmParser::validateMIMGAtomicDMask(const MCInst &Inst) { @@ -2378,25 +2387,25 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, "integer clamping is not supported on this GPU"); return false; } - if (!validateMIMGDataSize(Inst)) { + if (!validateMIMGR128(Inst)) { Error(IDLoc, - "image data size does not match dmask and tfe"); + "r128 modifier is not supported on this GPU"); return false; } - if (!validateMIMGAtomicDMask(Inst)) { + // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate. + if (!validateMIMGD16(Inst)) { Error(IDLoc, - "invalid atomic image dmask"); + "d16 modifier is not supported on this GPU"); return false; } - if (!validateMIMGR128(Inst)) { + if (!validateMIMGDataSize(Inst)) { Error(IDLoc, - "r128 modifier is not supported on this GPU"); + "image data size does not match dmask and tfe"); return false; } - // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate. - if (!validateMIMGD16(Inst)) { + if (!validateMIMGAtomicDMask(Inst)) { Error(IDLoc, - "d16 modifier is not supported on this GPU"); + "invalid atomic image dmask"); return false; } diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 32f1248dae5..578fe50146e 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -269,6 +269,9 @@ DecodeStatus AMDGPUDisassembler::convertSDWAInst(MCInst &MI) const { return MCDisassembler::Success; } +// Note that MIMG format provides no information about VADDR size. +// Consequently, decoded instructions always show address +// as if it has 1 dword, which could be not really so. DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { int VDstIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdst); @@ -279,8 +282,12 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { int DMaskIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dmask); + int TFEIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), + AMDGPU::OpName::tfe); + assert(VDataIdx != -1); assert(DMaskIdx != -1); + assert(TFEIdx != -1); bool isAtomic = (VDstIdx != -1); @@ -288,19 +295,28 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { if (DMask == 0) return MCDisassembler::Success; - unsigned ChannelCount = countPopulation(DMask); - if (ChannelCount == 1) + unsigned DstSize = countPopulation(DMask); + if (DstSize == 1) + return MCDisassembler::Success; + + bool D16 = MCII->get(MI.getOpcode()).TSFlags & SIInstrFlags::D16; + if (D16 && AMDGPU::hasPackedD16(STI)) { + DstSize = (DstSize + 1) / 2; + } + + // FIXME: Add tfe support + if (MI.getOperand(TFEIdx).getImm()) return MCDisassembler::Success; int NewOpcode = -1; if (isAtomic) { if (DMask == 0x1 || DMask == 0x3 || DMask == 0xF) { - NewOpcode = AMDGPU::getMaskedMIMGAtomicOp(*MCII, MI.getOpcode(), ChannelCount); + NewOpcode = AMDGPU::getMaskedMIMGAtomicOp(*MCII, MI.getOpcode(), DstSize); } if (NewOpcode == -1) return MCDisassembler::Success; } else { - NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), ChannelCount); + NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), DstSize); assert(NewOpcode != -1 && "could not find matching mimg channel instruction"); } diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp index 594fa935223..50311c241f2 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -628,6 +628,10 @@ bool hasMIMG_R128(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureMIMG_R128]; } +bool hasPackedD16(const MCSubtargetInfo &STI) { + return !STI.getFeatureBits()[AMDGPU::FeatureUnpackedD16VMem]; +} + bool isSI(const MCSubtargetInfo &STI) { return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands]; } diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h index 9e143aa7cf9..5e15e2e233a 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -284,8 +284,8 @@ inline bool isKernel(CallingConv::ID CC) { } bool hasXNACK(const MCSubtargetInfo &STI); - bool hasMIMG_R128(const MCSubtargetInfo &STI); +bool hasPackedD16(const MCSubtargetInfo &STI); bool isSI(const MCSubtargetInfo &STI); bool isCI(const MCSubtargetInfo &STI); |

