Line data Source code
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:
37 : AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
38 1 : : MCDisassembler(STI, Ctx) {}
39 1 : 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 :
48 1 : static MCDisassembler *createAVRDisassembler(const Target &T,
49 : const MCSubtargetInfo &STI,
50 : MCContext &Ctx) {
51 1 : return new AVRDisassembler(STI, Ctx);
52 : }
53 :
54 :
55 10844 : extern "C" void LLVMInitializeAVRDisassembler() {
56 : // Register the disassembler.
57 10844 : TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
58 : createAVRDisassembler);
59 10844 : }
60 :
61 0 : static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
62 : uint64_t Address, const void *Decoder) {
63 0 : return MCDisassembler::Success;
64 : }
65 :
66 0 : static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
67 : uint64_t Address, const void *Decoder) {
68 0 : return MCDisassembler::Success;
69 : }
70 :
71 0 : static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
72 : uint64_t Address, const void *Decoder) {
73 0 : return MCDisassembler::Success;
74 : }
75 :
76 : #include "AVRGenDisassemblerTables.inc"
77 :
78 0 : static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
79 : uint64_t &Size, uint32_t &Insn) {
80 0 : if (Bytes.size() < 2) {
81 0 : Size = 0;
82 0 : return MCDisassembler::Fail;
83 : }
84 :
85 2 : Size = 2;
86 2 : Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
87 :
88 0 : return MCDisassembler::Success;
89 : }
90 :
91 0 : static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
92 : uint64_t &Size, uint32_t &Insn) {
93 :
94 2 : if (Bytes.size() < 4) {
95 0 : Size = 0;
96 0 : return MCDisassembler::Fail;
97 : }
98 :
99 2 : Size = 4;
100 2 : Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24);
101 :
102 0 : return MCDisassembler::Success;
103 : }
104 :
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 :
114 2 : 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 0 : if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
128 :
129 : // Try to auto-decode a 16-bit instruction.
130 2 : Result = decodeInstruction(getDecoderTable(Size), Instr,
131 : Insn, Address, this, STI);
132 :
133 2 : 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 0 : if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
142 :
143 2 : Result = decodeInstruction(getDecoderTable(Size), Instr, Insn,
144 : Address, this, STI);
145 :
146 2 : if (Result != MCDisassembler::Fail) {
147 0 : 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 :
|