xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
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/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() {}
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 void *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 void *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 DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo,
90                                                uint64_t Address,
91                                                const void *Decoder) {
92   // Note: this function must be defined but does not seem to be called.
93   assert(false && "unimplemented: PTRREGS register class");
94   return MCDisassembler::Success;
95 }
96 
97 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
98                                  const void *Decoder);
99 
100 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
101                                  const void *Decoder);
102 
103 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
104                                  const void *Decoder);
105 
106 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn,
107                                      uint64_t Address, const void *Decoder);
108 
109 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
110                               const void *Decoder);
111 
112 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
113                                 const void *Decoder);
114 
115 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
116                                     uint64_t Address, const void *Decoder);
117 
118 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
119                                     uint64_t Address, const void *Decoder);
120 
121 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
122                                 const void *Decoder);
123 
124 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
125                                     uint64_t Address, const void *Decoder);
126 
127 #include "AVRGenDisassemblerTables.inc"
128 
129 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address,
130                                  const void *Decoder) {
131   unsigned addr = 0;
132   addr |= fieldFromInstruction(Insn, 0, 4);
133   addr |= fieldFromInstruction(Insn, 9, 2) << 4;
134   unsigned reg = fieldFromInstruction(Insn, 4, 5);
135   Inst.addOperand(MCOperand::createImm(addr));
136   if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) ==
137       MCDisassembler::Fail)
138     return MCDisassembler::Fail;
139   return MCDisassembler::Success;
140 }
141 
142 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address,
143                                  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) ==
149       MCDisassembler::Fail)
150     return MCDisassembler::Fail;
151   Inst.addOperand(MCOperand::createImm(addr));
152   return MCDisassembler::Success;
153 }
154 
155 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address,
156                                  const void *Decoder) {
157   unsigned addr = fieldFromInstruction(Insn, 3, 5);
158   unsigned b = fieldFromInstruction(Insn, 0, 3);
159   Inst.addOperand(MCOperand::createImm(addr));
160   Inst.addOperand(MCOperand::createImm(b));
161   return MCDisassembler::Success;
162 }
163 
164 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
165                                      uint64_t Address, const void *Decoder) {
166   // Call targets need to be shifted left by one so this needs a custom
167   // decoder.
168   Inst.addOperand(MCOperand::createImm(Field << 1));
169   return MCDisassembler::Success;
170 }
171 
172 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address,
173                               const void *Decoder) {
174   unsigned d = fieldFromInstruction(Insn, 4, 5);
175   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
176       MCDisassembler::Fail)
177     return MCDisassembler::Fail;
178   return MCDisassembler::Success;
179 }
180 
181 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address,
182                                 const void *Decoder) {
183   if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail)
184     return MCDisassembler::Fail;
185   Inst.addOperand(MCOperand::createReg(AVR::R31R30));
186   return MCDisassembler::Success;
187 }
188 
189 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn,
190                                     uint64_t Address, const void *Decoder) {
191   unsigned d = fieldFromInstruction(Insn, 4, 3) + 16;
192   unsigned r = fieldFromInstruction(Insn, 0, 3) + 16;
193   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
194       MCDisassembler::Fail)
195     return MCDisassembler::Fail;
196   if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
197       MCDisassembler::Fail)
198     return MCDisassembler::Fail;
199   return MCDisassembler::Success;
200 }
201 
202 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn,
203                                     uint64_t Address, const void *Decoder) {
204   unsigned r = fieldFromInstruction(Insn, 4, 4) * 2;
205   unsigned d = fieldFromInstruction(Insn, 0, 4) * 2;
206   if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
207       MCDisassembler::Fail)
208     return MCDisassembler::Fail;
209   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
210       MCDisassembler::Fail)
211     return MCDisassembler::Fail;
212   return MCDisassembler::Success;
213 }
214 
215 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address,
216                                 const void *Decoder) {
217   unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25
218   unsigned k = 0;
219   k |= fieldFromInstruction(Insn, 0, 4);
220   k |= fieldFromInstruction(Insn, 6, 2) << 4;
221   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
222       MCDisassembler::Fail)
223     return MCDisassembler::Fail;
224   if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
225       MCDisassembler::Fail)
226     return MCDisassembler::Fail;
227   Inst.addOperand(MCOperand::createImm(k));
228   return MCDisassembler::Success;
229 }
230 
231 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn,
232                                     uint64_t Address, const void *Decoder) {
233   unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16;
234   unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16;
235   if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) ==
236       MCDisassembler::Fail)
237     return MCDisassembler::Fail;
238   if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) ==
239       MCDisassembler::Fail)
240     return MCDisassembler::Fail;
241   return MCDisassembler::Success;
242 }
243 
244 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
245                                       uint64_t &Size, uint32_t &Insn) {
246   if (Bytes.size() < 2) {
247     Size = 0;
248     return MCDisassembler::Fail;
249   }
250 
251   Size = 2;
252   Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
253 
254   return MCDisassembler::Success;
255 }
256 
257 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
258                                       uint64_t &Size, uint32_t &Insn) {
259 
260   if (Bytes.size() < 4) {
261     Size = 0;
262     return MCDisassembler::Fail;
263   }
264 
265   Size = 4;
266   Insn =
267       (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
268 
269   return MCDisassembler::Success;
270 }
271 
272 static const uint8_t *getDecoderTable(uint64_t Size) {
273 
274   switch (Size) {
275   case 2:
276     return DecoderTable16;
277   case 4:
278     return DecoderTable32;
279   default:
280     llvm_unreachable("instructions must be 16 or 32-bits");
281   }
282 }
283 
284 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
285                                              ArrayRef<uint8_t> Bytes,
286                                              uint64_t Address,
287                                              raw_ostream &CStream) const {
288   uint32_t Insn;
289 
290   DecodeStatus Result;
291 
292   // Try decode a 16-bit instruction.
293   {
294     Result = readInstruction16(Bytes, Address, Size, Insn);
295 
296     if (Result == MCDisassembler::Fail)
297       return MCDisassembler::Fail;
298 
299     // Try to auto-decode a 16-bit instruction.
300     Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
301                                this, STI);
302 
303     if (Result != MCDisassembler::Fail)
304       return Result;
305   }
306 
307   // Try decode a 32-bit instruction.
308   {
309     Result = readInstruction32(Bytes, Address, Size, Insn);
310 
311     if (Result == MCDisassembler::Fail)
312       return MCDisassembler::Fail;
313 
314     Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,
315                                this, STI);
316 
317     if (Result != MCDisassembler::Fail) {
318       return Result;
319     }
320 
321     return MCDisassembler::Fail;
322   }
323 }
324 
325 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
326                                    const void *Decoder);
327