aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
diff options
context:
space:
mode:
authorRichard Osborne <richard@xmos.com>2012-12-17 16:28:02 +0000
committerRichard Osborne <richard@xmos.com>2012-12-17 16:28:02 +0000
commitc47793c62c434bd27fee1d243c2081a34d4f3817 (patch)
treec67dbecb9a16e36c6d7e3df0495ff44fedfd3723 /lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
parent9f84c05705f91686d00d0c200601eaa9df4193f0 (diff)
Add instruction encodings / disassembly support for l2r instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170345 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/XCore/Disassembler/XCoreDisassembler.cpp')
-rw-r--r--lib/Target/XCore/Disassembler/XCoreDisassembler.cpp74
1 files changed, 70 insertions, 4 deletions
diff --git a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
index 4f60724f65..094f18ceee 100644
--- a/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
+++ b/lib/Target/XCore/Disassembler/XCoreDisassembler.cpp
@@ -62,6 +62,23 @@ static bool readInstruction16(const MemoryObject &region,
return true;
}
+static bool readInstruction32(const MemoryObject &region,
+ uint64_t address,
+ uint64_t &size,
+ uint32_t &insn) {
+ uint8_t Bytes[4];
+
+ // We want to read exactly 4 Bytes of data.
+ if (region.readBytes(address, 4, Bytes, NULL) == -1) {
+ size = 0;
+ return false;
+ }
+ // Encoded as a little-endian 32-bit word in the stream.
+ insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
+ (Bytes[3] << 24);
+ return true;
+}
+
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
const XCoreDisassembler *Dis = static_cast<const XCoreDisassembler*>(D);
return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
@@ -105,6 +122,16 @@ static DecodeStatus DecodeRUSSrcDstBitpInstruction(MCInst &Inst,
uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeL2RInstruction(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
+static DecodeStatus DecodeLR2RInstruction(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder);
+
#include "XCoreGenDisassemblerTables.inc"
static DecodeStatus DecodeGRRegsRegisterClass(MCInst &Inst,
@@ -218,6 +245,32 @@ DecodeRUSSrcDstBitpInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
return S;
}
+static DecodeStatus
+DecodeL2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const void *Decoder) {
+ unsigned Op1, Op2;
+ DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
+ Op1, Op2);
+ if (S == MCDisassembler::Success) {
+ DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
+ DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
+ }
+ return S;
+}
+
+static DecodeStatus
+DecodeLR2RInstruction(MCInst &Inst, unsigned Insn, uint64_t Address,
+ const void *Decoder) {
+ unsigned Op1, Op2;
+ DecodeStatus S = Decode2OpInstruction(fieldFromInstruction(Insn, 0, 16),
+ Op1, Op2);
+ if (S == MCDisassembler::Success) {
+ DecodeGRRegsRegisterClass(Inst, Op2, Address, Decoder);
+ DecodeGRRegsRegisterClass(Inst, Op1, Address, Decoder);
+ }
+ return S;
+}
+
MCDisassembler::DecodeStatus
XCoreDisassembler::getInstruction(MCInst &instr,
uint64_t &Size,
@@ -225,20 +278,33 @@ XCoreDisassembler::getInstruction(MCInst &instr,
uint64_t Address,
raw_ostream &vStream,
raw_ostream &cStream) const {
- uint16_t low;
+ uint16_t insn16;
- if (!readInstruction16(Region, Address, Size, low)) {
+ if (!readInstruction16(Region, Address, Size, insn16)) {
return Fail;
}
// Calling the auto-generated decoder function.
- DecodeStatus Result = decodeInstruction(DecoderTable16, instr, low, Address,
- this, STI);
+ DecodeStatus Result = decodeInstruction(DecoderTable16, instr, insn16,
+ Address, this, STI);
if (Result != Fail) {
Size = 2;
return Result;
}
+ uint32_t insn32;
+
+ if (!readInstruction32(Region, Address, Size, insn32)) {
+ return Fail;
+ }
+
+ // Calling the auto-generated decoder function.
+ Result = decodeInstruction(DecoderTable32, instr, insn32, Address, this, STI);
+ if (Result != Fail) {
+ Size = 4;
+ return Result;
+ }
+
return Fail;
}