LLVM  13.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];
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];
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.
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 
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 
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 
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 
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 
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MCFixedLenDisassembler.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
DecodePTRREGSRegisterClass
static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:91
DecodeStatus
MCDisassembler::DecodeStatus DecodeStatus
Definition: AVRDisassembler.cpp:30
MCDisassembler.h
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:145
LLVMInitializeAVRDisassembler
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler()
Definition: AVRDisassembler.cpp:54
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:71
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:124
DecodeFunc
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:309
decodeFMUL2RdRr
static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:223
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:819
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:194
R2
#define R2(n)
DecodeLD8RegisterClass
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:81
DecodeGPR8RegisterClass
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:71
getDecoderTable
static const uint8_t * getDecoderTable(uint64_t Size)
Definition: AVRDisassembler.cpp:261
MCContext.h
decodeFWRdK
static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:209
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:50
llvm::MCDisassembler::DecodeStatus
DecodeStatus
Ternary decode status.
Definition: MCDisassembler.h:100
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:220
readInstruction16
static DecodeStatus readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: AVRDisassembler.cpp:234
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:131
readInstruction32
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: AVRDisassembler.cpp:247
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:163
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:138
uint32_t
decodeFRd
static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:171
decodeFIOBIT
static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:154
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:130
uint16_t
GPRDecoderTable
static const uint16_t GPRDecoderTable[]
Definition: AVRDisassembler.cpp:60
decodeFMOVWRdRr
static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:198
AVR.h
decodeFLPMX
static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:179
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
decodeFFMULRdRr
static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder)
Definition: AVRDisassembler.cpp:187
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:44
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