xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (revision ada4cd3f7710d9759e391e84ad21b7763062bdbc)
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