xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (revision 0ad011ececb978e22a9bff2acf76633b094f1ff6)
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(getTheAVRTarget(),
59                                          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(MCOperand::createReg(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(MCOperand::createReg(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, 0, 4);
146   addr |= fieldFromInstruction(Insn, 9, 2) << 4;
147   unsigned reg = fieldFromInstruction(Insn, 4, 5);
148   Inst.addOperand(MCOperand::createImm(addr));
149   if (DecodeGPR8RegisterClass(Inst, 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, 0, 4);
159   addr |= fieldFromInstruction(Insn, 9, 2) << 4;
160   unsigned reg = fieldFromInstruction(Insn, 4, 5);
161   if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
162       MCDisassembler::Fail)
163     return MCDisassembler::Fail;
164   Inst.addOperand(MCOperand::createImm(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, 3, 5);
171   unsigned b = fieldFromInstruction(Insn, 0, 3);
172   Inst.addOperand(MCOperand::createImm(addr));
173   Inst.addOperand(MCOperand::createImm(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(MCOperand::createImm(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, 4, 5);
189   if (DecodeGPR8RegisterClass(Inst, 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(MCOperand::createReg(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, 4, 3) + 16;
207   unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
208   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
209       MCDisassembler::Fail)
210     return MCDisassembler::Fail;
211   if (DecodeGPR8RegisterClass(Inst, 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, 4, 4) * 2;
221   unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
222   if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
223       MCDisassembler::Fail)
224     return MCDisassembler::Fail;
225   if (DecodeGPR8RegisterClass(Inst, 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, 4, 2) * 2 + 24; // starts at r24:r25
234   unsigned k = 0;
235   k |= fieldFromInstruction(Insn, 0, 4);
236   k |= fieldFromInstruction(Insn, 6, 2) << 4;
237   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
238       MCDisassembler::Fail)
239     return MCDisassembler::Fail;
240   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
241       MCDisassembler::Fail)
242     return MCDisassembler::Fail;
243   Inst.addOperand(MCOperand::createImm(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, 4, 4) + 16;
251   unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
252   if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) ==
253       MCDisassembler::Fail)
254     return MCDisassembler::Fail;
255   if (DecodeGPR8RegisterClass(Inst, 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       MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
272   // Append the immediate offset operand.
273   Inst.addOperand(MCOperand::createImm(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(MCOperand::createImm(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(brInsts, NotAlias);
314   auto It = llvm::partition_point(brInsts, 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(MCOperand::createImm(Offset));
321   } else {
322     // Fall back to an ordinary BRBS/BRBC.
323     Inst.setOpcode(Insn & 0x400 ? AVR::BRBCsk : AVR::BRBSsk);
324     Inst.addOperand(MCOperand::createImm(Insn & 7));
325     Inst.addOperand(MCOperand::createImm(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(MCOperand::createReg(RegVal));
344       Inst.addOperand(MCOperand::createReg(RegBase));
345       Inst.addOperand(MCOperand::createImm(Offset));
346     } else { // Decode STD.
347       Inst.setOpcode(AVR::STDPtrQRr);
348       Inst.addOperand(MCOperand::createReg(RegBase));
349       Inst.addOperand(MCOperand::createImm(Offset));
350       Inst.addOperand(MCOperand::createReg(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(MCOperand::createReg(RegBase));
397     Inst.addOperand(MCOperand::createReg(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(MCOperand::createReg(RegVal));
408     Inst.addOperand(MCOperand::createReg(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(MCOperand::createReg(RegVal));
423     Inst.addOperand(MCOperand::createReg(RegBase));
424     Inst.addOperand(MCOperand::createReg(RegBase));
425   } else { // This is a store instruction.
426     Inst.addOperand(MCOperand::createReg(RegBase));
427     Inst.addOperand(MCOperand::createReg(RegBase));
428     Inst.addOperand(MCOperand::createReg(RegVal));
429     // STPtrPiRr and STPtrPdRr have an extra immediate operand.
430     Inst.addOperand(MCOperand::createImm(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(AVR::FeatureTinyEncoding)) {
493       Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn, Address,
494                                  this, STI);
495       if (Result != MCDisassembler::Fail)
496         return Result;
497     }
498 
499     // Try to auto-decode a 16-bit instruction.
500     Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
501                                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(Instr, Insn, Address, 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(getDecoderTable(Size), Instr, Insn, Address,
520                                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