diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIInstrInfo.td | 4 |
2 files changed, 23 insertions, 7 deletions
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index a3c58663ef8..2990b570f53 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -83,10 +83,10 @@ DECODE_OPERAND(SReg_512) // //===----------------------------------------------------------------------===// -static inline uint32_t eatB32(ArrayRef<uint8_t>& Bytes) { - assert(Bytes.size() >= sizeof eatB32(Bytes)); - const auto Res = support::endian::read32le(Bytes.data()); - Bytes = Bytes.slice(sizeof Res); +template <typename T> static inline T eatBytes(ArrayRef<uint8_t>& Bytes) { + assert(Bytes.size() >= sizeof(T)); + const auto Res = support::endian::read<T, support::endianness::little>(Bytes.data()); + Bytes = Bytes.slice(sizeof(T)); return Res; } @@ -123,8 +123,20 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, do { // ToDo: better to switch encoding length using some bit predicate // but it is unknown yet, so try all we can + + // Try to decode DPP first to solve conflict with VOP1 and VOP2 encodings + if (Bytes.size() >= 8) { + const uint64_t QW = eatBytes<uint64_t>(Bytes); + Res = tryDecodeInst(DecoderTableDPP64, MI, QW, Address); + if (Res) break; + } + + // Reinitialize Bytes as DPP64 could have eaten too much + Bytes = Bytes_.slice(0, MaxInstBytesNum); + + // Try decode 32-bit instruction if (Bytes.size() < 4) break; - const uint32_t DW = eatB32(Bytes); + const uint32_t DW = eatBytes<uint32_t>(Bytes); Res = tryDecodeInst(DecoderTableVI32, MI, DW, Address); if (Res) break; @@ -132,7 +144,7 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size, if (Res) break; if (Bytes.size() < 4) break; - const uint64_t QW = ((uint64_t)eatB32(Bytes) << 32) | DW; + const uint64_t QW = ((uint64_t)eatBytes<uint32_t>(Bytes) << 32) | DW; Res = tryDecodeInst(DecoderTableVI64, MI, QW, Address); if (Res) break; @@ -261,7 +273,7 @@ MCOperand AMDGPUDisassembler::decodeLiteralConstant() const { if (Bytes.size() < 4) return errOperand(0, "cannot read literal, inst bytes left " + Twine(Bytes.size())); - return MCOperand::createImm(eatB32(Bytes)); + return MCOperand::createImm(eatBytes<uint32_t>(Bytes)); } MCOperand AMDGPUDisassembler::decodeIntImmed(unsigned Imm) { diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td index 37ee35c79de..669acd5c5ba 100644 --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -1705,6 +1705,8 @@ class VOP1_DPP <vop1 op, string opName, VOPProfile p> : VOP1_DPPe <op.VI>, VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "DPP"; + let DisableDecoder = DisableVIDecoder; let src0_modifiers = !if(p.HasModifiers, ?, 0); let src1_modifiers = 0; } @@ -1767,6 +1769,8 @@ class VOP2_DPP <vop2 op, string opName, VOPProfile p> : VOP2_DPPe <op.VI>, VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> { let AssemblerPredicates = [isVI]; + let DecoderNamespace = "DPP"; + let DisableDecoder = DisableVIDecoder; let src0_modifiers = !if(p.HasModifiers, ?, 0); let src1_modifiers = !if(p.HasModifiers, ?, 0); } |