1 //===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is part of the AVR Disassembler.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "AVR.h"
14 #include "AVRRegisterInfo.h"
15 #include "AVRSubtarget.h"
16 #include "MCTargetDesc/AVRMCTargetDesc.h"
17 #include "TargetInfo/AVRTargetInfo.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 &CStream) const override;
44 };
45 }
46
createAVRDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)47 static MCDisassembler *createAVRDisassembler(const Target &T,
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new AVRDisassembler(STI, Ctx);
51 }
52
53
LLVMInitializeAVRDisassembler()54 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() {
55 // Register the disassembler.
56 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
57 createAVRDisassembler);
58 }
59
60 static const uint16_t GPRDecoderTable[] = {
61 AVR::R0, AVR::R1, AVR::R2, AVR::R3,
62 AVR::R4, AVR::R5, AVR::R6, AVR::R7,
63 AVR::R8, AVR::R9, AVR::R10, AVR::R11,
64 AVR::R12, AVR::R13, AVR::R14, AVR::R15,
65 AVR::R16, AVR::R17, AVR::R18, AVR::R19,
66 AVR::R20, AVR::R21, AVR::R22, AVR::R23,
67 AVR::R24, AVR::R25, AVR::R26, AVR::R27,
68 AVR::R28, AVR::R29, AVR::R30, AVR::R31,
69 };
70
DecodeGPR8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)71 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
72 uint64_t Address, const void *Decoder) {
73 if (RegNo > 31)
74 return MCDisassembler::Fail;
75
76 unsigned Register = GPRDecoderTable[RegNo];
77 Inst.addOperand(MCOperand::createReg(Register));
78 return MCDisassembler::Success;
79 }
80
DecodeLD8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)81 static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
82 uint64_t Address, const void *Decoder) {
83 if (RegNo > 15)
84 return MCDisassembler::Fail;
85
86 unsigned Register = GPRDecoderTable[RegNo+16];
87 Inst.addOperand(MCOperand::createReg(Register));
88 return MCDisassembler::Success;
89 }
90
DecodePTRREGSRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)91 static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
92 uint64_t Address, const void *Decoder) {
93 // Note: this function must be defined but does not seem to be called.
94 assert(false && "unimplemented: PTRREGS register class");
95 return MCDisassembler::Success;
96 }
97
98 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
99 uint64_t Address, const void *Decoder);
100
101 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
102 uint64_t Address, const void *Decoder);
103
104 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
105 uint64_t Address, const void *Decoder);
106
107 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
108 uint64_t Address, const void *Decoder);
109
110 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn,
111 uint64_t Address, const void *Decoder);
112
113 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn,
114 uint64_t Address, const void *Decoder);
115
116 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
117 uint64_t Address, const void *Decoder);
118
119 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
120 uint64_t Address, const void *Decoder);
121
122 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn,
123 uint64_t Address, const void *Decoder);
124
125 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
126 uint64_t Address, const void *Decoder);
127
128 #include "AVRGenDisassemblerTables.inc"
129
decodeFIOARr(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)130 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
131 uint64_t Address, const void *Decoder) {
132 unsigned addr = 0;
133 addr |= fieldFromInstruction(Insn, 0, 4);
134 addr |= fieldFromInstruction(Insn, 9, 2) << 4;
135 unsigned reg = fieldFromInstruction(Insn, 4, 5);
136 Inst.addOperand(MCOperand::createImm(addr));
137 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
138 return MCDisassembler::Fail;
139 return MCDisassembler::Success;
140 }
141
decodeFIORdA(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)142 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
143 uint64_t Address, const void *Decoder) {
144 unsigned addr = 0;
145 addr |= fieldFromInstruction(Insn, 0, 4);
146 addr |= fieldFromInstruction(Insn, 9, 2) << 4;
147 unsigned reg = fieldFromInstruction(Insn, 4, 5);
148 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
149 return MCDisassembler::Fail;
150 Inst.addOperand(MCOperand::createImm(addr));
151 return MCDisassembler::Success;
152 }
153
decodeFIOBIT(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)154 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
155 uint64_t Address, const void *Decoder) {
156 unsigned addr = fieldFromInstruction(Insn, 3, 5);
157 unsigned b = fieldFromInstruction(Insn, 0, 3);
158 Inst.addOperand(MCOperand::createImm(addr));
159 Inst.addOperand(MCOperand::createImm(b));
160 return MCDisassembler::Success;
161 }
162
decodeCallTarget(MCInst & Inst,unsigned Field,uint64_t Address,const void * Decoder)163 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
164 uint64_t Address, const void *Decoder) {
165 // Call targets need to be shifted left by one so this needs a custom
166 // decoder.
167 Inst.addOperand(MCOperand::createImm(Field << 1));
168 return MCDisassembler::Success;
169 }
170
decodeFRd(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)171 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn,
172 uint64_t Address, const void *Decoder) {
173 unsigned d = fieldFromInstruction(Insn, 4, 5);
174 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
175 return MCDisassembler::Fail;
176 return MCDisassembler::Success;
177 }
178
decodeFLPMX(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)179 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn,
180 uint64_t Address, const void *Decoder) {
181 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
182 return MCDisassembler::Fail;
183 Inst.addOperand(MCOperand::createReg(AVR::R31R30));
184 return MCDisassembler::Success;
185 }
186
decodeFFMULRdRr(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)187 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
188 uint64_t Address, const void *Decoder) {
189 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
190 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
191 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
192 return MCDisassembler::Fail;
193 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail)
194 return MCDisassembler::Fail;
195 return MCDisassembler::Success;
196 }
197
decodeFMOVWRdRr(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)198 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
199 uint64_t Address, const void *Decoder) {
200 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
201 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
202 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail)
203 return MCDisassembler::Fail;
204 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
205 return MCDisassembler::Fail;
206 return MCDisassembler::Success;
207 }
208
decodeFWRdK(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)209 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn,
210 uint64_t Address, const void *Decoder) {
211 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
212 unsigned k = 0;
213 k |= fieldFromInstruction(Insn, 0, 4);
214 k |= fieldFromInstruction(Insn, 6, 2) << 4;
215 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
216 return MCDisassembler::Fail;
217 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
218 return MCDisassembler::Fail;
219 Inst.addOperand(MCOperand::createImm(k));
220 return MCDisassembler::Success;
221 }
222
decodeFMUL2RdRr(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)223 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
224 uint64_t Address, const void *Decoder) {
225 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
226 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
227 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail)
228 return MCDisassembler::Fail;
229 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail)
230 return MCDisassembler::Fail;
231 return MCDisassembler::Success;
232 }
233
readInstruction16(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)234 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
235 uint64_t &Size, uint32_t &Insn) {
236 if (Bytes.size() < 2) {
237 Size = 0;
238 return MCDisassembler::Fail;
239 }
240
241 Size = 2;
242 Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
243
244 return MCDisassembler::Success;
245 }
246
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn)247 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
248 uint64_t &Size, uint32_t &Insn) {
249
250 if (Bytes.size() < 4) {
251 Size = 0;
252 return MCDisassembler::Fail;
253 }
254
255 Size = 4;
256 Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
257
258 return MCDisassembler::Success;
259 }
260
getDecoderTable(uint64_t Size)261 static const uint8_t *getDecoderTable(uint64_t Size) {
262
263 switch (Size) {
264 case 2: return DecoderTable16;
265 case 4: return DecoderTable32;
266 default: llvm_unreachable("instructions must be 16 or 32-bits");
267 }
268 }
269
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const270 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
271 ArrayRef<uint8_t> Bytes,
272 uint64_t Address,
273 raw_ostream &CStream) const {
274 uint32_t Insn;
275
276 DecodeStatus Result;
277
278 // Try decode a 16-bit instruction.
279 {
280 Result = readInstruction16(Bytes, Address, Size, Insn);
281
282 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
283
284 // Try to auto-decode a 16-bit instruction.
285 Result = decodeInstruction(getDecoderTable(Size), Instr,
286 Insn, Address, this, STI);
287
288 if (Result != MCDisassembler::Fail)
289 return Result;
290 }
291
292 // Try decode a 32-bit instruction.
293 {
294 Result = readInstruction32(Bytes, Address, Size, Insn);
295
296 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
297
298 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn,
299 Address, this, STI);
300
301 if (Result != MCDisassembler::Fail) {
302 return Result;
303 }
304
305 return MCDisassembler::Fail;
306 }
307 }
308
309 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
310 const void *Decoder);
311
312