xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (revision 82d4dc0621c92e3c05a86013eec35afbdec057a5)
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/MCDisassembler/MCDisassembler.h"
22  #include "llvm/MC/MCFixedLenDisassembler.h"
23  #include "llvm/MC/MCInst.h"
24  #include "llvm/Support/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() {}
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  }
46  
47  static MCDisassembler *createAVRDisassembler(const Target &T,
48                                               const MCSubtargetInfo &STI,
49                                               MCContext &Ctx) {
50    return new AVRDisassembler(STI, Ctx);
51  }
52  
53  
54  extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() {
55    // Register the disassembler.
56    TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),
57                                           createAVRDisassembler);
58  }
59  
60  static const uint16_t GPRDecoderTable[] = {
61    AVR::R0, AVR::R1, AVR::R2, AVR::R3,
62    AVR::R4, AVR::R5, AVR::R6, AVR::R7,
63    AVR::R8, AVR::R9, AVR::R10, AVR::R11,
64    AVR::R12, AVR::R13, AVR::R14, AVR::R15,
65    AVR::R16, AVR::R17, AVR::R18, AVR::R19,
66    AVR::R20, AVR::R21, AVR::R22, AVR::R23,
67    AVR::R24, AVR::R25, AVR::R26, AVR::R27,
68    AVR::R28, AVR::R29, AVR::R30, AVR::R31,
69  };
70  
71  static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
72                                              uint64_t Address, const void *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, const void *Decoder) {
83    if (RegNo > 15)
84      return MCDisassembler::Fail;
85  
86    unsigned Register = GPRDecoderTable[RegNo+16];
87    Inst.addOperand(MCOperand::createReg(Register));
88    return MCDisassembler::Success;
89  }
90  
91  static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
92                                                 uint64_t Address, const void *Decoder) {
93    // Note: this function must be defined but does not seem to be called.
94    assert(false && "unimplemented: PTRREGS register class");
95    return MCDisassembler::Success;
96  }
97  
98  static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
99                                   uint64_t Address, const void *Decoder);
100  
101  static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
102                                   uint64_t Address, const void *Decoder);
103  
104  static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
105                                   uint64_t Address, const void *Decoder);
106  
107  static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
108                                       uint64_t Address, const void *Decoder);
109  
110  static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn,
111                                uint64_t Address, const void *Decoder);
112  
113  static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn,
114                                  uint64_t Address, const void *Decoder);
115  
116  static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
117                                      uint64_t Address, const void *Decoder);
118  
119  static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
120                                      uint64_t Address, const void *Decoder);
121  
122  static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn,
123                                  uint64_t Address, const void *Decoder);
124  
125  static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
126                                      uint64_t Address, const void *Decoder);
127  
128  #include "AVRGenDisassemblerTables.inc"
129  
130  static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn,
131                                   uint64_t Address, const void *Decoder) {
132    unsigned addr = 0;
133    addr |= fieldFromInstruction(Insn, 0, 4);
134    addr |= fieldFromInstruction(Insn, 9, 2) << 4;
135    unsigned reg = fieldFromInstruction(Insn, 4, 5);
136    Inst.addOperand(MCOperand::createImm(addr));
137    if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
138      return MCDisassembler::Fail;
139    return MCDisassembler::Success;
140  }
141  
142  static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn,
143                                   uint64_t Address, const void *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    if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail)
149      return MCDisassembler::Fail;
150    Inst.addOperand(MCOperand::createImm(addr));
151    return MCDisassembler::Success;
152  }
153  
154  static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn,
155                                   uint64_t Address, const void *Decoder) {
156    unsigned addr = fieldFromInstruction(Insn, 3, 5);
157    unsigned b = fieldFromInstruction(Insn, 0, 3);
158    Inst.addOperand(MCOperand::createImm(addr));
159    Inst.addOperand(MCOperand::createImm(b));
160    return MCDisassembler::Success;
161  }
162  
163  static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
164                                       uint64_t Address, const void *Decoder) {
165    // Call targets need to be shifted left by one so this needs a custom
166    // decoder.
167    Inst.addOperand(MCOperand::createImm(Field << 1));
168    return MCDisassembler::Success;
169  }
170  
171  static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn,
172                                uint64_t Address, const void *Decoder) {
173    unsigned d = fieldFromInstruction(Insn, 4, 5);
174    if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
175      return MCDisassembler::Fail;
176    return MCDisassembler::Success;
177  }
178  
179  static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn,
180                                  uint64_t Address, const void *Decoder) {
181    if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
182      return MCDisassembler::Fail;
183    Inst.addOperand(MCOperand::createReg(AVR::R31R30));
184    return MCDisassembler::Success;
185  }
186  
187  static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
188                                      uint64_t Address, const void *Decoder) {
189    unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
190    unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
191    if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
192      return MCDisassembler::Fail;
193    if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail)
194      return MCDisassembler::Fail;
195    return MCDisassembler::Success;
196  }
197  
198  static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
199                                      uint64_t Address, const void *Decoder) {
200    unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
201    unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
202    if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail)
203      return MCDisassembler::Fail;
204    if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
205      return MCDisassembler::Fail;
206    return MCDisassembler::Success;
207  }
208  
209  static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn,
210                                      uint64_t Address, const void *Decoder) {
211    unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
212    unsigned k = 0;
213    k |= fieldFromInstruction(Insn, 0, 4);
214    k |= fieldFromInstruction(Insn, 6, 2) << 4;
215    if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
216      return MCDisassembler::Fail;
217    if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail)
218      return MCDisassembler::Fail;
219    Inst.addOperand(MCOperand::createImm(k));
220    return MCDisassembler::Success;
221  }
222  
223  static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
224                                      uint64_t Address, const void *Decoder) {
225    unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
226    unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
227    if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail)
228      return MCDisassembler::Fail;
229    if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail)
230      return MCDisassembler::Fail;
231    return MCDisassembler::Success;
232  }
233  
234  static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
235                                        uint64_t &Size, uint32_t &Insn) {
236    if (Bytes.size() < 2) {
237      Size = 0;
238      return MCDisassembler::Fail;
239    }
240  
241    Size = 2;
242    Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
243  
244    return MCDisassembler::Success;
245  }
246  
247  static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
248                                        uint64_t &Size, uint32_t &Insn) {
249  
250    if (Bytes.size() < 4) {
251      Size = 0;
252      return MCDisassembler::Fail;
253    }
254  
255    Size = 4;
256    Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
257  
258    return MCDisassembler::Success;
259  }
260  
261  static const uint8_t *getDecoderTable(uint64_t Size) {
262  
263    switch (Size) {
264      case 2: return DecoderTable16;
265      case 4: return DecoderTable32;
266      default: llvm_unreachable("instructions must be 16 or 32-bits");
267    }
268  }
269  
270  DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
271                                               ArrayRef<uint8_t> Bytes,
272                                               uint64_t Address,
273                                               raw_ostream &CStream) const {
274    uint32_t Insn;
275  
276    DecodeStatus Result;
277  
278    // Try decode a 16-bit instruction.
279    {
280      Result = readInstruction16(Bytes, Address, Size, Insn);
281  
282      if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
283  
284      // Try to auto-decode a 16-bit instruction.
285      Result = decodeInstruction(getDecoderTable(Size), Instr,
286                                 Insn, Address, this, STI);
287  
288      if (Result != MCDisassembler::Fail)
289        return Result;
290    }
291  
292    // Try decode a 32-bit instruction.
293    {
294      Result = readInstruction32(Bytes, Address, Size, Insn);
295  
296      if (Result == MCDisassembler::Fail) return MCDisassembler::Fail;
297  
298      Result = decodeInstruction(getDecoderTable(Size), Instr, Insn,
299                                 Address, this, STI);
300  
301      if (Result != MCDisassembler::Fail) {
302        return Result;
303      }
304  
305      return MCDisassembler::Fail;
306    }
307  }
308  
309  typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
310                                     const void *Decoder);
311  
312