1d88c1a5aSDimitry Andric //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===//
2d88c1a5aSDimitry Andric //
3d88c1a5aSDimitry Andric // The LLVM Compiler Infrastructure
4d88c1a5aSDimitry Andric //
5d88c1a5aSDimitry Andric // This file is distributed under the University of Illinois Open Source
6d88c1a5aSDimitry Andric // License. See LICENSE.TXT for details.
7d88c1a5aSDimitry Andric //
8d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
9d88c1a5aSDimitry Andric //
10d88c1a5aSDimitry Andric // This file is part of the AVR Disassembler.
11d88c1a5aSDimitry Andric //
12d88c1a5aSDimitry Andric //===----------------------------------------------------------------------===//
13d88c1a5aSDimitry Andric
14d88c1a5aSDimitry Andric #include "AVR.h"
15d88c1a5aSDimitry Andric #include "AVRRegisterInfo.h"
16d88c1a5aSDimitry Andric #include "AVRSubtarget.h"
17d88c1a5aSDimitry Andric #include "MCTargetDesc/AVRMCTargetDesc.h"
18d88c1a5aSDimitry Andric
19*db17bf38SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
20*db17bf38SDimitry Andric #include "llvm/MC/MCContext.h"
21d88c1a5aSDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
22d88c1a5aSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
23d88c1a5aSDimitry Andric #include "llvm/MC/MCInst.h"
24d88c1a5aSDimitry Andric #include "llvm/Support/TargetRegistry.h"
25d88c1a5aSDimitry Andric
26d88c1a5aSDimitry Andric using namespace llvm;
27d88c1a5aSDimitry Andric
28d88c1a5aSDimitry Andric #define DEBUG_TYPE "avr-disassembler"
29d88c1a5aSDimitry Andric
30d88c1a5aSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
31d88c1a5aSDimitry Andric
32d88c1a5aSDimitry Andric namespace {
33d88c1a5aSDimitry Andric
34d88c1a5aSDimitry Andric /// A disassembler class for AVR.
35d88c1a5aSDimitry Andric class AVRDisassembler : public MCDisassembler {
36d88c1a5aSDimitry Andric public:
AVRDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)37d88c1a5aSDimitry Andric AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
38d88c1a5aSDimitry Andric : MCDisassembler(STI, Ctx) {}
~AVRDisassembler()39d88c1a5aSDimitry Andric virtual ~AVRDisassembler() {}
40d88c1a5aSDimitry Andric
41d88c1a5aSDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42d88c1a5aSDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address,
43d88c1a5aSDimitry Andric raw_ostream &VStream,
44d88c1a5aSDimitry Andric raw_ostream &CStream) const override;
45d88c1a5aSDimitry Andric };
46d88c1a5aSDimitry Andric }
47d88c1a5aSDimitry Andric
createAVRDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)48d88c1a5aSDimitry Andric static MCDisassembler *createAVRDisassembler(const Target &T,
49d88c1a5aSDimitry Andric const MCSubtargetInfo &STI,
50d88c1a5aSDimitry Andric MCContext &Ctx) {
51d88c1a5aSDimitry Andric return new AVRDisassembler(STI, Ctx);
52d88c1a5aSDimitry Andric }
53d88c1a5aSDimitry Andric
54d88c1a5aSDimitry Andric
LLVMInitializeAVRDisassembler()55d88c1a5aSDimitry Andric extern "C" void LLVMInitializeAVRDisassembler() {
56d88c1a5aSDimitry Andric // Register the disassembler.
57d88c1a5aSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
58d88c1a5aSDimitry Andric createAVRDisassembler);
59d88c1a5aSDimitry Andric }
60d88c1a5aSDimitry Andric
DecodeGPR8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)61d88c1a5aSDimitry Andric static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
62d88c1a5aSDimitry Andric uint64_t Address, const void *Decoder) {
63d88c1a5aSDimitry Andric return MCDisassembler::Success;
64d88c1a5aSDimitry Andric }
65d88c1a5aSDimitry Andric
DecodeLD8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)66d88c1a5aSDimitry Andric static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
67d88c1a5aSDimitry Andric uint64_t Address, const void *Decoder) {
68d88c1a5aSDimitry Andric return MCDisassembler::Success;
69d88c1a5aSDimitry Andric }
70d88c1a5aSDimitry Andric
DecodePTRREGSRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)71d88c1a5aSDimitry Andric static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
72d88c1a5aSDimitry Andric uint64_t Address, const void *Decoder) {
73d88c1a5aSDimitry Andric return MCDisassembler::Success;
74d88c1a5aSDimitry Andric }
75d88c1a5aSDimitry Andric
76d88c1a5aSDimitry Andric #include "AVRGenDisassemblerTables.inc"
77d88c1a5aSDimitry Andric
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)78d88c1a5aSDimitry Andric static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
79d88c1a5aSDimitry Andric uint64_t &Size, uint32_t &Insn) {
80d88c1a5aSDimitry Andric if (Bytes.size() < 2) {
81d88c1a5aSDimitry Andric Size = 0;
82d88c1a5aSDimitry Andric return MCDisassembler::Fail;
83d88c1a5aSDimitry Andric }
84d88c1a5aSDimitry Andric
85d88c1a5aSDimitry Andric Size = 2;
86d88c1a5aSDimitry Andric Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
87d88c1a5aSDimitry Andric
88d88c1a5aSDimitry Andric return MCDisassembler::Success;
89d88c1a5aSDimitry Andric }
90d88c1a5aSDimitry Andric
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)91d88c1a5aSDimitry Andric static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
92d88c1a5aSDimitry Andric uint64_t &Size, uint32_t &Insn) {
93d88c1a5aSDimitry Andric
94d88c1a5aSDimitry Andric if (Bytes.size() < 4) {
95d88c1a5aSDimitry Andric Size = 0;
96d88c1a5aSDimitry Andric return MCDisassembler::Fail;
97d88c1a5aSDimitry Andric }
98d88c1a5aSDimitry Andric
99d88c1a5aSDimitry Andric Size = 4;
100d88c1a5aSDimitry Andric Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24);
101d88c1a5aSDimitry Andric
102d88c1a5aSDimitry Andric return MCDisassembler::Success;
103d88c1a5aSDimitry Andric }
104d88c1a5aSDimitry Andric
getDecoderTable(uint64_t Size)105d88c1a5aSDimitry Andric static const uint8_t *getDecoderTable(uint64_t Size) {
106d88c1a5aSDimitry Andric
107d88c1a5aSDimitry Andric switch (Size) {
108d88c1a5aSDimitry Andric case 2: return DecoderTable16;
109d88c1a5aSDimitry Andric case 4: return DecoderTable32;
110d88c1a5aSDimitry Andric default: llvm_unreachable("instructions must be 16 or 32-bits");
111d88c1a5aSDimitry Andric }
112d88c1a5aSDimitry Andric }
113d88c1a5aSDimitry Andric
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & VStream,raw_ostream & CStream) const114d88c1a5aSDimitry Andric DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
115d88c1a5aSDimitry Andric ArrayRef<uint8_t> Bytes,
116d88c1a5aSDimitry Andric uint64_t Address,
117d88c1a5aSDimitry Andric raw_ostream &VStream,
118d88c1a5aSDimitry Andric raw_ostream &CStream) const {
119d88c1a5aSDimitry Andric uint32_t Insn;
120d88c1a5aSDimitry Andric
121d88c1a5aSDimitry Andric DecodeStatus Result;
122d88c1a5aSDimitry Andric
123d88c1a5aSDimitry Andric // Try decode a 16-bit instruction.
124d88c1a5aSDimitry Andric {
125d88c1a5aSDimitry Andric Result = readInstruction16(Bytes, Address, Size, Insn);
126d88c1a5aSDimitry Andric
127d88c1a5aSDimitry Andric if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
128d88c1a5aSDimitry Andric
129d88c1a5aSDimitry Andric // Try to auto-decode a 16-bit instruction.
130d88c1a5aSDimitry Andric Result = decodeInstruction(getDecoderTable(Size), Instr,
131d88c1a5aSDimitry Andric Insn, Address, this, STI);
132d88c1a5aSDimitry Andric
133d88c1a5aSDimitry Andric if (Result != MCDisassembler::Fail)
134d88c1a5aSDimitry Andric return Result;
135d88c1a5aSDimitry Andric }
136d88c1a5aSDimitry Andric
137d88c1a5aSDimitry Andric // Try decode a 32-bit instruction.
138d88c1a5aSDimitry Andric {
139d88c1a5aSDimitry Andric Result = readInstruction32(Bytes, Address, Size, Insn);
140d88c1a5aSDimitry Andric
141d88c1a5aSDimitry Andric if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
142d88c1a5aSDimitry Andric
143d88c1a5aSDimitry Andric Result = decodeInstruction(getDecoderTable(Size), Instr, Insn,
144d88c1a5aSDimitry Andric Address, this, STI);
145d88c1a5aSDimitry Andric
146d88c1a5aSDimitry Andric if (Result != MCDisassembler::Fail) {
147d88c1a5aSDimitry Andric return Result;
148d88c1a5aSDimitry Andric }
149d88c1a5aSDimitry Andric
150d88c1a5aSDimitry Andric return MCDisassembler::Fail;
151d88c1a5aSDimitry Andric }
152d88c1a5aSDimitry Andric }
153d88c1a5aSDimitry Andric
154d88c1a5aSDimitry Andric typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
155d88c1a5aSDimitry Andric const void *Decoder);
156d88c1a5aSDimitry Andric
157