diff options
Diffstat (limited to 'lib/Target/XCore/Disassembler')
-rw-r--r-- | lib/Target/XCore/Disassembler/XCoreDisassembler.cpp | 74 |
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 ®ion, return true; } +static bool readInstruction32(const MemoryObject ®ion, + 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; } |