diff options
| author | Dmitry Preobrazhensky <dmitry.preobrazhensky@amd.com> | 2018-01-26 15:43:29 +0000 |
|---|---|---|
| committer | Dmitry Preobrazhensky <dmitry.preobrazhensky@amd.com> | 2018-01-26 15:43:29 +0000 |
| commit | 0b4eb1ead18e437b3f630bf3f4c082adab417170 (patch) | |
| tree | 75d09dbff6eba1d7c8c155bf8bf8e0f87a48913a /llvm/lib/Target/AMDGPU/Disassembler | |
| parent | 041ef2dd15dc1606e338dafc48a1f263ec2fa61f (diff) | |
| download | bcm5719-llvm-0b4eb1ead18e437b3f630bf3f4c082adab417170.tar.gz bcm5719-llvm-0b4eb1ead18e437b3f630bf3f4c082adab417170.zip | |
[AMDGPU][MC] Added support of 64-bit image atomics
See bug 35998: https://bugs.llvm.org/show_bug.cgi?id=35998
Differential Revision: https://reviews.llvm.org/D42469
Reviewers: vpykhtin, artem.tamazov, arsenm
llvm-svn: 323534
Diffstat (limited to 'llvm/lib/Target/AMDGPU/Disassembler')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 6ea9367f270..3697d5aec64 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -265,11 +265,20 @@ DecodeStatus AMDGPUDisassembler::convertSDWAInst(MCInst &MI) const { } DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { + int VDstIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), + AMDGPU::OpName::vdst); + int VDataIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::vdata); int DMaskIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::dmask); + + assert(VDataIdx != -1); + assert(DMaskIdx != -1); + + bool isAtomic = (VDstIdx != -1); + unsigned DMask = MI.getOperand(DMaskIdx).getImm() & 0xf; if (DMask == 0) return MCDisassembler::Success; @@ -278,12 +287,26 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { if (ChannelCount == 1) return MCDisassembler::Success; - int NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), ChannelCount); - assert(NewOpcode != -1 && "could not find matching mimg channel instruction"); + int NewOpcode = -1; + + if (isAtomic) { + if (DMask == 0x1 || DMask == 0x3 || DMask == 0xF) { + NewOpcode = AMDGPU::getMaskedMIMGAtomicOp(*MCII, MI.getOpcode(), ChannelCount); + } + if (NewOpcode == -1) return MCDisassembler::Success; + } else { + NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), ChannelCount); + assert(NewOpcode != -1 && "could not find matching mimg channel instruction"); + } + auto RCID = MCII->get(NewOpcode).OpInfo[VDataIdx].RegClass; - // Widen the register to the correct number of enabled channels. + // Get first subregister of VData unsigned Vdata0 = MI.getOperand(VDataIdx).getReg(); + unsigned VdataSub0 = MRI.getSubReg(Vdata0, AMDGPU::sub0); + Vdata0 = (VdataSub0 != 0)? VdataSub0 : Vdata0; + + // Widen the register to the correct number of enabled channels. auto NewVdata = MRI.getMatchingSuperReg(Vdata0, AMDGPU::sub0, &MRI.getRegClass(RCID)); if (NewVdata == AMDGPU::NoRegister) { @@ -297,6 +320,12 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const { // how it is usually emitted because the number of register components is not // in the instruction encoding. MI.getOperand(VDataIdx) = MCOperand::createReg(NewVdata); + + if (isAtomic) { + // Atomic operations have an additional operand (a copy of data) + MI.getOperand(VDstIdx) = MCOperand::createReg(NewVdata); + } + return MCDisassembler::Success; } |

