summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp26
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.td4
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);
}
OpenPOWER on IntegriCloud