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