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