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/ADT/DenseMap.h" |
20 | #include "llvm/ADT/STLExtras.h" |
21 | |
22 | #include "llvm/MC/MCAsmInfo.h" |
23 | #include "llvm/MC/MCContext.h" |
24 | #include "llvm/MC/MCDecoderOps.h" |
25 | #include "llvm/MC/MCDisassembler/MCDisassembler.h" |
26 | #include "llvm/MC/MCInst.h" |
27 | #include "llvm/MC/TargetRegistry.h" |
28 | |
29 | using namespace llvm; |
30 | |
31 | #define DEBUG_TYPE "avr-disassembler" |
32 | |
33 | typedef MCDisassembler::DecodeStatus DecodeStatus; |
34 | |
35 | namespace { |
36 | |
37 | /// A disassembler class for AVR. |
38 | class AVRDisassembler : public MCDisassembler { |
39 | public: |
40 | AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) |
41 | : MCDisassembler(STI, Ctx) {} |
42 | virtual ~AVRDisassembler() = default; |
43 | |
44 | DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, |
45 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
46 | raw_ostream &CStream) const override; |
47 | }; |
48 | } // namespace |
49 | |
50 | static MCDisassembler *createAVRDisassembler(const Target &T, |
51 | const MCSubtargetInfo &STI, |
52 | MCContext &Ctx) { |
53 | return new AVRDisassembler(STI, Ctx); |
54 | } |
55 | |
56 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { |
57 | // Register the disassembler. |
58 | TargetRegistry::RegisterMCDisassembler(T&: getTheAVRTarget(), |
59 | Fn: createAVRDisassembler); |
60 | } |
61 | |
62 | static const uint16_t GPRDecoderTable[] = { |
63 | AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6, |
64 | AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13, |
65 | AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20, |
66 | AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27, |
67 | AVR::R28, AVR::R29, AVR::R30, AVR::R31, |
68 | }; |
69 | |
70 | static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, |
71 | uint64_t Address, |
72 | const MCDisassembler *Decoder) { |
73 | if (RegNo > 31) |
74 | return MCDisassembler::Fail; |
75 | |
76 | unsigned Register = GPRDecoderTable[RegNo]; |
77 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
78 | return MCDisassembler::Success; |
79 | } |
80 | |
81 | static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, |
82 | uint64_t Address, |
83 | const MCDisassembler *Decoder) { |
84 | if (RegNo > 15) |
85 | return MCDisassembler::Fail; |
86 | |
87 | unsigned Register = GPRDecoderTable[RegNo + 16]; |
88 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
89 | return MCDisassembler::Success; |
90 | } |
91 | |
92 | static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, |
93 | const MCDisassembler *Decoder); |
94 | |
95 | static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, |
96 | const MCDisassembler *Decoder); |
97 | |
98 | static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, |
99 | const MCDisassembler *Decoder); |
100 | |
101 | static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, |
102 | uint64_t Address, |
103 | const MCDisassembler *Decoder); |
104 | |
105 | static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, |
106 | const MCDisassembler *Decoder); |
107 | |
108 | static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, |
109 | const MCDisassembler *Decoder); |
110 | |
111 | static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, |
112 | uint64_t Address, |
113 | const MCDisassembler *Decoder); |
114 | |
115 | static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, |
116 | uint64_t Address, |
117 | const MCDisassembler *Decoder); |
118 | |
119 | static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, |
120 | const MCDisassembler *Decoder); |
121 | |
122 | static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, |
123 | uint64_t Address, |
124 | const MCDisassembler *Decoder); |
125 | |
126 | static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, |
127 | const MCDisassembler *Decoder); |
128 | |
129 | static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address, |
130 | const MCDisassembler *Decoder); |
131 | |
132 | static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn, |
133 | uint64_t Address, |
134 | const MCDisassembler *Decoder); |
135 | |
136 | static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, |
137 | uint64_t Address, |
138 | const MCDisassembler *Decoder); |
139 | |
140 | #include "AVRGenDisassemblerTables.inc" |
141 | |
142 | static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, |
143 | const MCDisassembler *Decoder) { |
144 | unsigned addr = 0; |
145 | addr |= fieldFromInstruction(insn: Insn, startBit: 0, numBits: 4); |
146 | addr |= fieldFromInstruction(insn: Insn, startBit: 9, numBits: 2) << 4; |
147 | unsigned reg = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 5); |
148 | Inst.addOperand(Op: MCOperand::createImm(Val: addr)); |
149 | if (DecodeGPR8RegisterClass(Inst, RegNo: reg, Address, Decoder) == |
150 | MCDisassembler::Fail) |
151 | return MCDisassembler::Fail; |
152 | return MCDisassembler::Success; |
153 | } |
154 | |
155 | static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, |
156 | const MCDisassembler *Decoder) { |
157 | unsigned addr = 0; |
158 | addr |= fieldFromInstruction(insn: Insn, startBit: 0, numBits: 4); |
159 | addr |= fieldFromInstruction(insn: Insn, startBit: 9, numBits: 2) << 4; |
160 | unsigned reg = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 5); |
161 | if (DecodeGPR8RegisterClass(Inst, RegNo: reg, Address, Decoder) == |
162 | MCDisassembler::Fail) |
163 | return MCDisassembler::Fail; |
164 | Inst.addOperand(Op: MCOperand::createImm(Val: addr)); |
165 | return MCDisassembler::Success; |
166 | } |
167 | |
168 | static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, |
169 | const MCDisassembler *Decoder) { |
170 | unsigned addr = fieldFromInstruction(insn: Insn, startBit: 3, numBits: 5); |
171 | unsigned b = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 3); |
172 | Inst.addOperand(Op: MCOperand::createImm(Val: addr)); |
173 | Inst.addOperand(Op: MCOperand::createImm(Val: b)); |
174 | return MCDisassembler::Success; |
175 | } |
176 | |
177 | static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, |
178 | uint64_t Address, |
179 | const MCDisassembler *Decoder) { |
180 | // Call targets need to be shifted left by one so this needs a custom |
181 | // decoder. |
182 | Inst.addOperand(Op: MCOperand::createImm(Val: Field << 1)); |
183 | return MCDisassembler::Success; |
184 | } |
185 | |
186 | static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, |
187 | const MCDisassembler *Decoder) { |
188 | unsigned d = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 5); |
189 | if (DecodeGPR8RegisterClass(Inst, RegNo: d, Address, Decoder) == |
190 | MCDisassembler::Fail) |
191 | return MCDisassembler::Fail; |
192 | return MCDisassembler::Success; |
193 | } |
194 | |
195 | static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, |
196 | const MCDisassembler *Decoder) { |
197 | if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) |
198 | return MCDisassembler::Fail; |
199 | Inst.addOperand(Op: MCOperand::createReg(Reg: AVR::R31R30)); |
200 | return MCDisassembler::Success; |
201 | } |
202 | |
203 | static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, |
204 | uint64_t Address, |
205 | const MCDisassembler *Decoder) { |
206 | unsigned d = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 3) + 16; |
207 | unsigned r = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 3) + 16; |
208 | if (DecodeGPR8RegisterClass(Inst, RegNo: d, Address, Decoder) == |
209 | MCDisassembler::Fail) |
210 | return MCDisassembler::Fail; |
211 | if (DecodeGPR8RegisterClass(Inst, RegNo: r, Address, Decoder) == |
212 | MCDisassembler::Fail) |
213 | return MCDisassembler::Fail; |
214 | return MCDisassembler::Success; |
215 | } |
216 | |
217 | static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, |
218 | uint64_t Address, |
219 | const MCDisassembler *Decoder) { |
220 | unsigned r = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 4) * 2; |
221 | unsigned d = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 4) * 2; |
222 | if (DecodeGPR8RegisterClass(Inst, RegNo: r, Address, Decoder) == |
223 | MCDisassembler::Fail) |
224 | return MCDisassembler::Fail; |
225 | if (DecodeGPR8RegisterClass(Inst, RegNo: d, Address, Decoder) == |
226 | MCDisassembler::Fail) |
227 | return MCDisassembler::Fail; |
228 | return MCDisassembler::Success; |
229 | } |
230 | |
231 | static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, |
232 | const MCDisassembler *Decoder) { |
233 | unsigned d = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 2) * 2 + 24; // starts at r24:r25 |
234 | unsigned k = 0; |
235 | k |= fieldFromInstruction(insn: Insn, startBit: 0, numBits: 4); |
236 | k |= fieldFromInstruction(insn: Insn, startBit: 6, numBits: 2) << 4; |
237 | if (DecodeGPR8RegisterClass(Inst, RegNo: d, Address, Decoder) == |
238 | MCDisassembler::Fail) |
239 | return MCDisassembler::Fail; |
240 | if (DecodeGPR8RegisterClass(Inst, RegNo: d, Address, Decoder) == |
241 | MCDisassembler::Fail) |
242 | return MCDisassembler::Fail; |
243 | Inst.addOperand(Op: MCOperand::createImm(Val: k)); |
244 | return MCDisassembler::Success; |
245 | } |
246 | |
247 | static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, |
248 | uint64_t Address, |
249 | const MCDisassembler *Decoder) { |
250 | unsigned rd = fieldFromInstruction(insn: Insn, startBit: 4, numBits: 4) + 16; |
251 | unsigned rr = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 4) + 16; |
252 | if (DecodeGPR8RegisterClass(Inst, RegNo: rd, Address, Decoder) == |
253 | MCDisassembler::Fail) |
254 | return MCDisassembler::Fail; |
255 | if (DecodeGPR8RegisterClass(Inst, RegNo: rr, Address, Decoder) == |
256 | MCDisassembler::Fail) |
257 | return MCDisassembler::Fail; |
258 | return MCDisassembler::Success; |
259 | } |
260 | |
261 | static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, |
262 | const MCDisassembler *Decoder) { |
263 | // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory |
264 | // address is encoded into 7-bit, in which bits 0-5 are the immediate offset, |
265 | // and the bit-6 is the pointer register bit (Z=0, Y=1). |
266 | if (Insn > 127) |
267 | return MCDisassembler::Fail; |
268 | |
269 | // Append the base register operand. |
270 | Inst.addOperand( |
271 | Op: MCOperand::createReg(Reg: (Insn & 0x40) ? AVR::R29R28 : AVR::R31R30)); |
272 | // Append the immediate offset operand. |
273 | Inst.addOperand(Op: MCOperand::createImm(Val: Insn & 0x3f)); |
274 | |
275 | return MCDisassembler::Success; |
276 | } |
277 | |
278 | static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address, |
279 | const MCDisassembler *Decoder) { |
280 | // Decode the opcode. |
281 | switch (Insn & 0xf000) { |
282 | case 0xc000: |
283 | Inst.setOpcode(AVR::RJMPk); |
284 | break; |
285 | case 0xd000: |
286 | Inst.setOpcode(AVR::RCALLk); |
287 | break; |
288 | default: // Unknown relative branch instruction. |
289 | return MCDisassembler::Fail; |
290 | } |
291 | // Decode the relative offset. |
292 | int16_t Offset = ((int16_t)((Insn & 0xfff) << 4)) >> 3; |
293 | Inst.addOperand(Op: MCOperand::createImm(Val: Offset)); |
294 | return MCDisassembler::Success; |
295 | } |
296 | |
297 | static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn, |
298 | uint64_t Address, |
299 | const MCDisassembler *Decoder) { |
300 | // These 8 instructions are not defined as aliases of BRBS/BRBC. |
301 | DenseMap<unsigned, unsigned> brInsts = { |
302 | {0x000, AVR::BRLOk}, {0x400, AVR::BRSHk}, {0x001, AVR::BREQk}, |
303 | {0x401, AVR::BRNEk}, {0x002, AVR::BRMIk}, {0x402, AVR::BRPLk}, |
304 | {0x004, AVR::BRLTk}, {0x404, AVR::BRGEk}}; |
305 | |
306 | // Get the relative offset. |
307 | int16_t Offset = ((int16_t)((Insn & 0x3f8) << 6)) >> 8; |
308 | |
309 | // Search the instruction pattern. |
310 | auto NotAlias = [&Insn](const std::pair<unsigned, unsigned> &I) { |
311 | return (Insn & 0x407) != I.first; |
312 | }; |
313 | llvm::partition(Range&: brInsts, P: NotAlias); |
314 | auto It = llvm::partition_point(Range&: brInsts, P: NotAlias); |
315 | |
316 | // Decode the instruction. |
317 | if (It != brInsts.end()) { |
318 | // This instruction is not an alias of BRBC/BRBS. |
319 | Inst.setOpcode(It->second); |
320 | Inst.addOperand(Op: MCOperand::createImm(Val: Offset)); |
321 | } else { |
322 | // Fall back to an ordinary BRBS/BRBC. |
323 | Inst.setOpcode(Insn & 0x400 ? AVR::BRBCsk : AVR::BRBSsk); |
324 | Inst.addOperand(Op: MCOperand::createImm(Val: Insn & 7)); |
325 | Inst.addOperand(Op: MCOperand::createImm(Val: Offset)); |
326 | } |
327 | |
328 | return MCDisassembler::Success; |
329 | } |
330 | |
331 | static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, |
332 | uint64_t Address, |
333 | const MCDisassembler *Decoder) { |
334 | // Get the register will be loaded or stored. |
335 | unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f]; |
336 | |
337 | // Decode LDD/STD with offset less than 8. |
338 | if ((Insn & 0xf000) == 0x8000) { |
339 | unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30; |
340 | unsigned Offset = Insn & 7; // We need not consider offset > 7. |
341 | if ((Insn & 0x200) == 0) { // Decode LDD. |
342 | Inst.setOpcode(AVR::LDDRdPtrQ); |
343 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
344 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
345 | Inst.addOperand(Op: MCOperand::createImm(Val: Offset)); |
346 | } else { // Decode STD. |
347 | Inst.setOpcode(AVR::STDPtrQRr); |
348 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
349 | Inst.addOperand(Op: MCOperand::createImm(Val: Offset)); |
350 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
351 | } |
352 | return MCDisassembler::Success; |
353 | } |
354 | |
355 | // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1), |
356 | // bits 8~4 indicate the value register, bits 3-2 indicate the base address |
357 | // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic, |
358 | // 01-postinc, 10-predec). |
359 | // ST X, Rr : 1001 001r rrrr 1100 |
360 | // ST X+, Rr : 1001 001r rrrr 1101 |
361 | // ST -X, Rr : 1001 001r rrrr 1110 |
362 | // ST Y+, Rr : 1001 001r rrrr 1001 |
363 | // ST -Y, Rr : 1001 001r rrrr 1010 |
364 | // ST Z+, Rr : 1001 001r rrrr 0001 |
365 | // ST -Z, Rr : 1001 001r rrrr 0010 |
366 | // LD Rd, X : 1001 000d dddd 1100 |
367 | // LD Rd, X+ : 1001 000d dddd 1101 |
368 | // LD Rd, -X : 1001 000d dddd 1110 |
369 | // LD Rd, Y+ : 1001 000d dddd 1001 |
370 | // LD Rd, -Y : 1001 000d dddd 1010 |
371 | // LD Rd, Z+ : 1001 000d dddd 0001 |
372 | // LD Rd, -Z : 1001 000d dddd 0010 |
373 | if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) |
374 | return MCDisassembler::Fail; |
375 | |
376 | // Get the base address register. |
377 | unsigned RegBase; |
378 | switch (Insn & 0xc) { |
379 | case 0xc: |
380 | RegBase = AVR::R27R26; |
381 | break; |
382 | case 0x8: |
383 | RegBase = AVR::R29R28; |
384 | break; |
385 | case 0x0: |
386 | RegBase = AVR::R31R30; |
387 | break; |
388 | default: |
389 | return MCDisassembler::Fail; |
390 | } |
391 | |
392 | // Set the opcode. |
393 | switch (Insn & 0x203) { |
394 | case 0x200: |
395 | Inst.setOpcode(AVR::STPtrRr); |
396 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
397 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
398 | return MCDisassembler::Success; |
399 | case 0x201: |
400 | Inst.setOpcode(AVR::STPtrPiRr); |
401 | break; |
402 | case 0x202: |
403 | Inst.setOpcode(AVR::STPtrPdRr); |
404 | break; |
405 | case 0: |
406 | Inst.setOpcode(AVR::LDRdPtr); |
407 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
408 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
409 | return MCDisassembler::Success; |
410 | case 1: |
411 | Inst.setOpcode(AVR::LDRdPtrPi); |
412 | break; |
413 | case 2: |
414 | Inst.setOpcode(AVR::LDRdPtrPd); |
415 | break; |
416 | default: |
417 | return MCDisassembler::Fail; |
418 | } |
419 | |
420 | // Build postinc/predec machine instructions. |
421 | if ((Insn & 0x200) == 0) { // This is a load instruction. |
422 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
423 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
424 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
425 | } else { // This is a store instruction. |
426 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
427 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase)); |
428 | Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal)); |
429 | // STPtrPiRr and STPtrPdRr have an extra immediate operand. |
430 | Inst.addOperand(Op: MCOperand::createImm(Val: 1)); |
431 | } |
432 | |
433 | return MCDisassembler::Success; |
434 | } |
435 | |
436 | static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, |
437 | uint64_t &Size, uint32_t &Insn) { |
438 | if (Bytes.size() < 2) { |
439 | Size = 0; |
440 | return MCDisassembler::Fail; |
441 | } |
442 | |
443 | Size = 2; |
444 | Insn = (Bytes[0] << 0) | (Bytes[1] << 8); |
445 | |
446 | return MCDisassembler::Success; |
447 | } |
448 | |
449 | static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, |
450 | uint64_t &Size, uint32_t &Insn) { |
451 | |
452 | if (Bytes.size() < 4) { |
453 | Size = 0; |
454 | return MCDisassembler::Fail; |
455 | } |
456 | |
457 | Size = 4; |
458 | Insn = |
459 | (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); |
460 | |
461 | return MCDisassembler::Success; |
462 | } |
463 | |
464 | static const uint8_t *getDecoderTable(uint64_t Size) { |
465 | |
466 | switch (Size) { |
467 | case 2: |
468 | return DecoderTable16; |
469 | case 4: |
470 | return DecoderTable32; |
471 | default: |
472 | llvm_unreachable("instructions must be 16 or 32-bits" ); |
473 | } |
474 | } |
475 | |
476 | DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, |
477 | ArrayRef<uint8_t> Bytes, |
478 | uint64_t Address, |
479 | raw_ostream &CStream) const { |
480 | uint32_t Insn; |
481 | |
482 | DecodeStatus Result; |
483 | |
484 | // Try decode a 16-bit instruction. |
485 | { |
486 | Result = readInstruction16(Bytes, Address, Size, Insn); |
487 | |
488 | if (Result == MCDisassembler::Fail) |
489 | return MCDisassembler::Fail; |
490 | |
491 | // Try to decode AVRTiny instructions. |
492 | if (STI.hasFeature(Feature: AVR::FeatureTinyEncoding)) { |
493 | Result = decodeInstruction(DecodeTable: DecoderTableAVRTiny16, MI&: Instr, insn: Insn, Address, |
494 | DisAsm: this, STI); |
495 | if (Result != MCDisassembler::Fail) |
496 | return Result; |
497 | } |
498 | |
499 | // Try to auto-decode a 16-bit instruction. |
500 | Result = decodeInstruction(DecodeTable: getDecoderTable(Size), MI&: Instr, insn: Insn, Address, |
501 | DisAsm: this, STI); |
502 | if (Result != MCDisassembler::Fail) |
503 | return Result; |
504 | |
505 | // Try to decode to a load/store instruction. ST/LD need a specified |
506 | // DecoderMethod, as they already have a specified PostEncoderMethod. |
507 | Result = decodeLoadStore(Inst&: Instr, Insn, Address, Decoder: this); |
508 | if (Result != MCDisassembler::Fail) |
509 | return Result; |
510 | } |
511 | |
512 | // Try decode a 32-bit instruction. |
513 | { |
514 | Result = readInstruction32(Bytes, Address, Size, Insn); |
515 | |
516 | if (Result == MCDisassembler::Fail) |
517 | return MCDisassembler::Fail; |
518 | |
519 | Result = decodeInstruction(DecodeTable: getDecoderTable(Size), MI&: Instr, insn: Insn, Address, |
520 | DisAsm: this, STI); |
521 | |
522 | if (Result != MCDisassembler::Fail) { |
523 | return Result; |
524 | } |
525 | |
526 | return MCDisassembler::Fail; |
527 | } |
528 | } |
529 | |
530 | typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, |
531 | const MCDisassembler *Decoder); |
532 | |