mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[AVR] Add the machine code disassembler
This adds a super basic implementation of a machine code disassembler. It doesn't support any operands with custom encoding. llvm-svn: 284930
This commit is contained in:
parent
3e08d68407
commit
872c3b9ed5
@ -3,6 +3,7 @@ set(LLVM_TARGET_DEFINITIONS AVR.td)
|
||||
tablegen(LLVM AVRGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM AVRGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM AVRGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM AVRGenDisassemblerTables.inc -gen-disassembler)
|
||||
tablegen(LLVM AVRGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM AVRGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM AVRGenSubtargetInfo.inc -gen-subtarget)
|
||||
|
160
lib/Target/AVR/Disassembler/AVRDisassembler.cpp
Normal file
160
lib/Target/AVR/Disassembler/AVRDisassembler.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
//===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is part of the AVR Disassembler.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AVR.h"
|
||||
#include "AVRRegisterInfo.h"
|
||||
#include "AVRSubtarget.h"
|
||||
#include "MCTargetDesc/AVRMCTargetDesc.h"
|
||||
|
||||
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
||||
#include "llvm/MC/MCFixedLenDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "avr-disassembler"
|
||||
|
||||
typedef MCDisassembler::DecodeStatus DecodeStatus;
|
||||
|
||||
namespace {
|
||||
|
||||
/// A disassembler class for AVR.
|
||||
class AVRDisassembler : public MCDisassembler {
|
||||
public:
|
||||
AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
|
||||
: MCDisassembler(STI, Ctx) {}
|
||||
virtual ~AVRDisassembler() {}
|
||||
|
||||
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
|
||||
ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const override;
|
||||
};
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
extern Target TheAVRTarget;
|
||||
}
|
||||
|
||||
static MCDisassembler *createAVRDisassembler(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
return new AVRDisassembler(STI, Ctx);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void LLVMInitializeAVRDisassembler() {
|
||||
// Register the disassembler.
|
||||
TargetRegistry::RegisterMCDisassembler(TheAVRTarget,
|
||||
createAVRDisassembler);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
|
||||
uint64_t Address, const void *Decoder) {
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
#include "AVRGenDisassemblerTables.inc"
|
||||
|
||||
static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
uint64_t &Size, uint32_t &Insn) {
|
||||
if (Bytes.size() < 2) {
|
||||
Size = 0;
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
Size = 2;
|
||||
Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
uint64_t &Size, uint32_t &Insn) {
|
||||
|
||||
if (Bytes.size() < 4) {
|
||||
Size = 0;
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
Size = 4;
|
||||
Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24);
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static const uint8_t *getDecoderTable(uint64_t Size) {
|
||||
|
||||
switch (Size) {
|
||||
case 2: return DecoderTable16;
|
||||
case 4: return DecoderTable32;
|
||||
default: llvm_unreachable("instructions must be 16 or 32-bits");
|
||||
}
|
||||
}
|
||||
|
||||
DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
|
||||
ArrayRef<uint8_t> Bytes,
|
||||
uint64_t Address,
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const {
|
||||
uint32_t Insn;
|
||||
|
||||
DecodeStatus Result;
|
||||
|
||||
// Try decode a 16-bit instruction.
|
||||
{
|
||||
Result = readInstruction16(Bytes, Address, Size, Insn);
|
||||
|
||||
if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
|
||||
|
||||
// Try to auto-decode a 16-bit instruction.
|
||||
Result = decodeInstruction(getDecoderTable(Size), Instr,
|
||||
Insn, Address, this, STI);
|
||||
|
||||
if (Result != MCDisassembler::Fail)
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Try decode a 32-bit instruction.
|
||||
{
|
||||
Result = readInstruction32(Bytes, Address, Size, Insn);
|
||||
|
||||
if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
|
||||
|
||||
Result = decodeInstruction(getDecoderTable(Size), Instr, Insn,
|
||||
Address, this, STI);
|
||||
|
||||
if (Result != MCDisassembler::Fail) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
}
|
||||
|
||||
typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
4
lib/Target/AVR/Disassembler/CMakeLists.txt
Normal file
4
lib/Target/AVR/Disassembler/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
add_llvm_library(LLVMAVRDisassembler
|
||||
AVRDisassembler.cpp
|
||||
)
|
||||
|
23
lib/Target/AVR/Disassembler/LLVMBuild.txt
Normal file
23
lib/Target/AVR/Disassembler/LLVMBuild.txt
Normal file
@ -0,0 +1,23 @@
|
||||
;===- ./lib/Target/AVR/Disassembler/LLVMBuild.txt --------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = AVRDisassembler
|
||||
parent = AVR
|
||||
required_libraries = MCDisassembler AVRInfo Support
|
||||
add_to_library_groups = AVR
|
@ -16,7 +16,7 @@
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = AsmParser InstPrinter MCTargetDesc TargetInfo
|
||||
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
|
||||
|
||||
[component_0]
|
||||
type = TargetGroup
|
||||
@ -24,6 +24,7 @@ name = AVR
|
||||
parent = Target
|
||||
has_asmprinter = 1
|
||||
has_asmparser = 1
|
||||
has_disassembler = 1
|
||||
|
||||
[component_1]
|
||||
type = Library
|
||||
|
Loading…
Reference in New Issue
Block a user