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:
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 
47 static MCDisassembler *createAVRDisassembler(const Target &T,
48                                              const MCSubtargetInfo &STI,
49                                              MCContext &Ctx) {
50   return new AVRDisassembler(STI, Ctx);
51 }
52 
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 
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 
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 decodeLoadStore(MCInst &Inst, unsigned Insn,
127                                     uint64_t Address,
128                                     const MCDisassembler *Decoder);
129 
130 #include "AVRGenDisassemblerTables.inc"
131 
132 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
133                                  const MCDisassembler *Decoder) {
134   unsigned addr = 0;
135   addr |= fieldFromInstruction(Insn, 0, 4);
136   addr |= fieldFromInstruction(Insn, 9, 2) << 4;
137   unsigned reg = fieldFromInstruction(Insn, 4, 5);
138   Inst.addOperand(MCOperand::createImm(addr));
139   if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
140       MCDisassembler::Fail)
141     return MCDisassembler::Fail;
142   return MCDisassembler::Success;
143 }
144 
145 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
146                                  const MCDisassembler *Decoder) {
147   unsigned addr = 0;
148   addr |= fieldFromInstruction(Insn, 0, 4);
149   addr |= fieldFromInstruction(Insn, 9, 2) << 4;
150   unsigned reg = fieldFromInstruction(Insn, 4, 5);
151   if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
152       MCDisassembler::Fail)
153     return MCDisassembler::Fail;
154   Inst.addOperand(MCOperand::createImm(addr));
155   return MCDisassembler::Success;
156 }
157 
158 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
159                                  const MCDisassembler *Decoder) {
160   unsigned addr = fieldFromInstruction(Insn, 3, 5);
161   unsigned b = fieldFromInstruction(Insn, 0, 3);
162   Inst.addOperand(MCOperand::createImm(addr));
163   Inst.addOperand(MCOperand::createImm(b));
164   return MCDisassembler::Success;
165 }
166 
167 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
168                                      uint64_t Address,
169                                      const MCDisassembler *Decoder) {
170   // Call targets need to be shifted left by one so this needs a custom
171   // decoder.
172   Inst.addOperand(MCOperand::createImm(Field << 1));
173   return MCDisassembler::Success;
174 }
175 
176 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
177                               const MCDisassembler *Decoder) {
178   unsigned d = fieldFromInstruction(Insn, 4, 5);
179   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
180       MCDisassembler::Fail)
181     return MCDisassembler::Fail;
182   return MCDisassembler::Success;
183 }
184 
185 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
186                                 const MCDisassembler *Decoder) {
187   if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
188     return MCDisassembler::Fail;
189   Inst.addOperand(MCOperand::createReg(AVR::R31R30));
190   return MCDisassembler::Success;
191 }
192 
193 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
194                                     uint64_t Address,
195                                     const MCDisassembler *Decoder) {
196   unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
197   unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
198   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
199       MCDisassembler::Fail)
200     return MCDisassembler::Fail;
201   if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
202       MCDisassembler::Fail)
203     return MCDisassembler::Fail;
204   return MCDisassembler::Success;
205 }
206 
207 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
208                                     uint64_t Address,
209                                     const MCDisassembler *Decoder) {
210   unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
211   unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
212   if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
213       MCDisassembler::Fail)
214     return MCDisassembler::Fail;
215   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
216       MCDisassembler::Fail)
217     return MCDisassembler::Fail;
218   return MCDisassembler::Success;
219 }
220 
221 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
222                                 const MCDisassembler *Decoder) {
223   unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
224   unsigned k = 0;
225   k |= fieldFromInstruction(Insn, 0, 4);
226   k |= fieldFromInstruction(Insn, 6, 2) << 4;
227   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
228       MCDisassembler::Fail)
229     return MCDisassembler::Fail;
230   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
231       MCDisassembler::Fail)
232     return MCDisassembler::Fail;
233   Inst.addOperand(MCOperand::createImm(k));
234   return MCDisassembler::Success;
235 }
236 
237 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
238                                     uint64_t Address,
239                                     const MCDisassembler *Decoder) {
240   unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
241   unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
242   if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) ==
243       MCDisassembler::Fail)
244     return MCDisassembler::Fail;
245   if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) ==
246       MCDisassembler::Fail)
247     return MCDisassembler::Fail;
248   return MCDisassembler::Success;
249 }
250 
251 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
252                                 const MCDisassembler *Decoder) {
253   // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory
254   // address is encoded into 7-bit, in which bits 0-5 are the immediate offset,
255   // and the bit-6 is the pointer register bit (Z=0, Y=1).
256   if (Insn > 127)
257     return MCDisassembler::Fail;
258 
259   // Append the base register operand.
260   Inst.addOperand(
261       MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
262   // Append the immediate offset operand.
263   Inst.addOperand(MCOperand::createImm(Insn & 0x3f));
264 
265   return MCDisassembler::Success;
266 }
267 
268 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
269                                     uint64_t Address,
270                                     const MCDisassembler *Decoder) {
271   // Get the register will be loaded or stored.
272   unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
273 
274   // Decode LDD/STD with offset less than 8.
275   if ((Insn & 0xf000) == 0x8000) {
276     unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
277     unsigned Offset = Insn & 7; // We need not consider offset > 7.
278     if ((Insn & 0x200) == 0) { // Decode LDD.
279       Inst.setOpcode(AVR::LDDRdPtrQ);
280       Inst.addOperand(MCOperand::createReg(RegVal));
281       Inst.addOperand(MCOperand::createReg(RegBase));
282       Inst.addOperand(MCOperand::createImm(Offset));
283     } else { // Decode STD.
284       Inst.setOpcode(AVR::STDPtrQRr);
285       Inst.addOperand(MCOperand::createReg(RegBase));
286       Inst.addOperand(MCOperand::createImm(Offset));
287       Inst.addOperand(MCOperand::createReg(RegVal));
288     }
289     return MCDisassembler::Success;
290   }
291 
292   // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1),
293   // bits 8~4 indicate the value register, bits 3-2 indicate the base address
294   // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic,
295   // 01-postinc, 10-predec).
296   // ST X,  Rr : 1001 001r rrrr 1100
297   // ST X+, Rr : 1001 001r rrrr 1101
298   // ST -X, Rr : 1001 001r rrrr 1110
299   // ST Y+, Rr : 1001 001r rrrr 1001
300   // ST -Y, Rr : 1001 001r rrrr 1010
301   // ST Z+, Rr : 1001 001r rrrr 0001
302   // ST -Z, Rr : 1001 001r rrrr 0010
303   // LD Rd, X  : 1001 000d dddd 1100
304   // LD Rd, X+ : 1001 000d dddd 1101
305   // LD Rd, -X : 1001 000d dddd 1110
306   // LD Rd, Y+ : 1001 000d dddd 1001
307   // LD Rd, -Y : 1001 000d dddd 1010
308   // LD Rd, Z+ : 1001 000d dddd 0001
309   // LD Rd, -Z : 1001 000d dddd 0010
310   if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0)
311     return MCDisassembler::Fail;
312 
313   // Get the base address register.
314   unsigned RegBase;
315   switch (Insn & 0xc) {
316   case 0xc:
317     RegBase = AVR::R27R26;
318     break;
319   case 0x8:
320     RegBase = AVR::R29R28;
321     break;
322   case 0x0:
323     RegBase = AVR::R31R30;
324     break;
325   default:
326     return MCDisassembler::Fail;
327   }
328 
329   // Set the opcode.
330   switch (Insn & 0x203) {
331   case 0x200:
332     Inst.setOpcode(AVR::STPtrRr);
333     Inst.addOperand(MCOperand::createReg(RegBase));
334     Inst.addOperand(MCOperand::createReg(RegVal));
335     return MCDisassembler::Success;
336   case 0x201:
337     Inst.setOpcode(AVR::STPtrPiRr);
338     break;
339   case 0x202:
340     Inst.setOpcode(AVR::STPtrPdRr);
341     break;
342   case 0:
343     Inst.setOpcode(AVR::LDRdPtr);
344     Inst.addOperand(MCOperand::createReg(RegVal));
345     Inst.addOperand(MCOperand::createReg(RegBase));
346     return MCDisassembler::Success;
347   case 1:
348     Inst.setOpcode(AVR::LDRdPtrPi);
349     break;
350   case 2:
351     Inst.setOpcode(AVR::LDRdPtrPd);
352     break;
353   default:
354     return MCDisassembler::Fail;
355   }
356 
357   // Build postinc/predec machine instructions.
358   if ((Insn & 0x200) == 0) { // This is a load instruction.
359     Inst.addOperand(MCOperand::createReg(RegVal));
360     Inst.addOperand(MCOperand::createReg(RegBase));
361     Inst.addOperand(MCOperand::createReg(RegBase));
362   } else { // This is a store instruction.
363     Inst.addOperand(MCOperand::createReg(RegBase));
364     Inst.addOperand(MCOperand::createReg(RegBase));
365     Inst.addOperand(MCOperand::createReg(RegVal));
366     // STPtrPiRr and STPtrPdRr have an extra immediate operand.
367     Inst.addOperand(MCOperand::createImm(1));
368   }
369 
370   return MCDisassembler::Success;
371 }
372 
373 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
374                                       uint64_t &Size, uint32_t &Insn) {
375   if (Bytes.size() < 2) {
376     Size = 0;
377     return MCDisassembler::Fail;
378   }
379 
380   Size = 2;
381   Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
382 
383   return MCDisassembler::Success;
384 }
385 
386 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
387                                       uint64_t &Size, uint32_t &Insn) {
388 
389   if (Bytes.size() < 4) {
390     Size = 0;
391     return MCDisassembler::Fail;
392   }
393 
394   Size = 4;
395   Insn =
396       (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
397 
398   return MCDisassembler::Success;
399 }
400 
401 static const uint8_t *getDecoderTable(uint64_t Size) {
402 
403   switch (Size) {
404   case 2:
405     return DecoderTable16;
406   case 4:
407     return DecoderTable32;
408   default:
409     llvm_unreachable("instructions must be 16 or 32-bits");
410   }
411 }
412 
413 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
414                                              ArrayRef<uint8_t> Bytes,
415                                              uint64_t Address,
416                                              raw_ostream &CStream) const {
417   uint32_t Insn;
418 
419   DecodeStatus Result;
420 
421   // Try decode a 16-bit instruction.
422   {
423     Result = readInstruction16(Bytes, Address, Size, Insn);
424 
425     if (Result == MCDisassembler::Fail)
426       return MCDisassembler::Fail;
427 
428     // Try to auto-decode a 16-bit instruction.
429     Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
430                                this, STI);
431     if (Result != MCDisassembler::Fail)
432       return Result;
433 
434     // Try to decode to a load/store instruction. ST/LD need a specified
435     // DecoderMethod, as they already have a specified PostEncoderMethod.
436     Result = decodeLoadStore(Instr, Insn, Address, this);
437     if (Result != MCDisassembler::Fail)
438       return Result;
439   }
440 
441   // Try decode a 32-bit instruction.
442   {
443     Result = readInstruction32(Bytes, Address, Size, Insn);
444 
445     if (Result == MCDisassembler::Fail)
446       return MCDisassembler::Fail;
447 
448     Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
449                                this, STI);
450 
451     if (Result != MCDisassembler::Fail) {
452       return Result;
453     }
454 
455     return MCDisassembler::Fail;
456   }
457 }
458 
459 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
460                                    const MCDisassembler *Decoder);
461