1
0
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:
Dylan McKay 2016-10-22 23:57:59 +00:00
parent 3e08d68407
commit 872c3b9ed5
5 changed files with 190 additions and 1 deletions

View File

@ -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)

View 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);

View File

@ -0,0 +1,4 @@
add_llvm_library(LLVMAVRDisassembler
AVRDisassembler.cpp
)

View 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

View File

@ -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