LLVM  12.0.0git
AVRDisassembler.cpp
Go to the documentation of this file.
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"
18 
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCInst.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "avr-disassembler"
29 
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 
48  const MCSubtargetInfo &STI,
49  MCContext &Ctx) {
50  return new AVRDisassembler(STI, Ctx);
51 }
52 
53 
55  // Register the disassembler.
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));
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));
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");
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;
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));
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));
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));
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;
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));
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;
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;
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;
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;
232 }
233 
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 
245 }
246 
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 
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 
static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
#define R4(n)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
DecodeStatus
Ternary decode status.
Superclass for all disassemblers.
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
#define R2(n)
static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
Target & getTheAVRTarget()
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static const uint16_t GPRDecoderTable[]
Context object for machine code objects.
Definition: MCContext.h:67
static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static MCDisassembler * createAVRDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:156
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define R6(n)
static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
static const uint8_t * getDecoderTable(uint64_t Size)
Target - Wrapper for Target specific information.
static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Generic base class for all target subtargets.
MCDisassembler::DecodeStatus DecodeStatus
uint32_t Size
Definition: Profile.cpp:46
static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
IRTranslator LLVM IR MI
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
Wrapper class representing virtual and physical registers.
Definition: Register.h:19