LLVM  14.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,
43  raw_ostream &CStream) const override;
44 };
45 } // namespace
46 
48  const MCSubtargetInfo &STI,
49  MCContext &Ctx) {
50  return new AVRDisassembler(STI, Ctx);
51 }
52 
54  // Register the disassembler.
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];
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];
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");
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) ==
138  return MCDisassembler::Fail;
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) ==
150  return MCDisassembler::Fail;
151  Inst.addOperand(MCOperand::createImm(addr));
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));
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.
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) ==
177  return MCDisassembler::Fail;
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));
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) ==
195  return MCDisassembler::Fail;
196  if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) ==
198  return MCDisassembler::Fail;
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) ==
208  return MCDisassembler::Fail;
209  if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
211  return MCDisassembler::Fail;
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) ==
223  return MCDisassembler::Fail;
224  if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) ==
226  return MCDisassembler::Fail;
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) ==
237  return MCDisassembler::Fail;
238  if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) ==
240  return MCDisassembler::Fail;
242 }
243 
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 
255 }
256 
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 
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 
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);
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MCFixedLenDisassembler.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
DecodePTRREGSRegisterClass
static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:89
DecodeStatus
MCDisassembler::DecodeStatus DecodeStatus
Definition: AVRDisassembler.cpp:30
MCDisassembler.h
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
LLVMInitializeAVRDisassembler
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler()
Definition: AVRDisassembler.cpp:53
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
DecodeFunc
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:325
decodeFMUL2RdRr
static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:231
R4
#define R4(n)
llvm::TargetRegistry::RegisterMCDisassembler
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
Definition: TargetRegistry.h:916
decodeFIORdA
static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:142
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
R2
#define R2(n)
DecodeLD8RegisterClass
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:78
DecodeGPR8RegisterClass
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:67
getDecoderTable
static const uint8_t * getDecoderTable(uint64_t Size)
Definition: AVRDisassembler.cpp:272
MCContext.h
decodeFWRdK
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:215
b
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
Definition: README.txt:418
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCDisassembler::Success
@ Success
Definition: MCDisassembler.h:103
MCInst.h
llvm::getTheAVRTarget
Target & getTheAVRTarget()
Definition: AVRTargetInfo.cpp:12
AVRTargetInfo.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::MCDisassembler::DecodeStatus
DecodeStatus
Ternary decode status.
Definition: MCDisassembler.h:100
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
uint64_t
readInstruction16
static DecodeStatus readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: AVRDisassembler.cpp:244
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
readInstruction32
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: AVRDisassembler.cpp:257
llvm::MCDisassembler
Superclass for all disassemblers.
Definition: MCDisassembler.h:76
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
AVRMCTargetDesc.h
R6
#define R6(n)
llvm::ArrayRef< uint8_t >
AVRRegisterInfo.h
decodeCallTarget
static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:164
MCAsmInfo.h
AVRSubtarget.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
uint32_t
decodeFRd
static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:172
decodeFIOBIT
static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:155
llvm::MCDisassembler::Fail
@ Fail
Definition: MCDisassembler.h:101
createAVRDisassembler
static MCDisassembler * createAVRDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
Definition: AVRDisassembler.cpp:47
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
decodeFIOARr
static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:129
uint16_t
GPRDecoderTable
static const uint16_t GPRDecoderTable[]
Definition: AVRDisassembler.cpp:59
decodeFMOVWRdRr
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:202
AVR.h
decodeFLPMX
static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:181
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
decodeFFMULRdRr
static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:189
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:45
d
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int int d
Definition: README.txt:418
TargetRegistry.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75