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 "MCTargetDesc/AVRMCTargetDesc.h"
14#include "TargetInfo/AVRTargetInfo.h"
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/STLExtras.h"
18
19#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCDecoder.h"
22#include "llvm/MC/MCDecoderOps.h"
23#include "llvm/MC/MCDisassembler/MCDisassembler.h"
24#include "llvm/MC/MCInst.h"
25#include "llvm/MC/TargetRegistry.h"
26
27#include "llvm/Support/Compiler.h"
28
29using namespace llvm;
30using namespace llvm::MCD;
31
32#define DEBUG_TYPE "avr-disassembler"
33
34typedef MCDisassembler::DecodeStatus DecodeStatus;
35
36namespace {
37
38/// A disassembler class for AVR.
39class AVRDisassembler : public MCDisassembler {
40public:
41 AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
42 : MCDisassembler(STI, Ctx) {}
43 ~AVRDisassembler() override = default;
44
45 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
46 ArrayRef<uint8_t> Bytes, uint64_t Address,
47 raw_ostream &CStream) const override;
48};
49} // namespace
50
51static MCDisassembler *createAVRDisassembler(const Target &T,
52 const MCSubtargetInfo &STI,
53 MCContext &Ctx) {
54 return new AVRDisassembler(STI, Ctx);
55}
56
57extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
58LLVMInitializeAVRDisassembler() {
59 // Register the disassembler.
60 TargetRegistry::RegisterMCDisassembler(T&: getTheAVRTarget(),
61 Fn: createAVRDisassembler);
62}
63
64static constexpr MCRegister GPRDecoderTable[] = {
65 AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6,
66 AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13,
67 AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20,
68 AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27,
69 AVR::R28, AVR::R29, AVR::R30, AVR::R31,
70};
71
72static constexpr MCRegister GPRPairDecoderTable[] = {
73 AVR::R1R0, AVR::R3R2, AVR::R5R4, AVR::R7R6,
74 AVR::R9R8, AVR::R11R10, AVR::R13R12, AVR::R15R14,
75 AVR::R17R16, AVR::R19R18, AVR::R21R20, AVR::R23R22,
76 AVR::R25R24, AVR::R27R26, AVR::R29R28, AVR::R31R30,
77};
78
79static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo,
80 uint64_t Address,
81 const MCDisassembler *Decoder) {
82 if (RegNo > 31)
83 return MCDisassembler::Fail;
84
85 MCRegister Register = GPRDecoderTable[RegNo];
86 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
87 return MCDisassembler::Success;
88}
89
90static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo,
91 uint64_t Address,
92 const MCDisassembler *Decoder) {
93 assert(isUInt<4>(RegNo));
94 // Only r16...r31 are legal.
95 Inst.addOperand(Op: MCOperand::createReg(Reg: GPRDecoderTable[16 + RegNo]));
96 return MCDisassembler::Success;
97}
98
99static DecodeStatus DecodeLD8loRegisterClass(MCInst &Inst, unsigned RegNo,
100 uint64_t Address,
101 const MCDisassembler *Decoder) {
102 assert(isUInt<3>(RegNo));
103 // Only r16...r23 are legal.
104 Inst.addOperand(Op: MCOperand::createReg(Reg: GPRDecoderTable[16 + RegNo]));
105 return MCDisassembler::Success;
106}
107
108static DecodeStatus DecodeDREGSRegisterClass(MCInst &Inst, unsigned RegNo,
109 uint64_t Address,
110 const MCDisassembler *Decoder) {
111 assert(isUInt<4>(RegNo));
112 Inst.addOperand(Op: MCOperand::createReg(Reg: GPRPairDecoderTable[RegNo]));
113 return MCDisassembler::Success;
114}
115
116static DecodeStatus DecodeIWREGSRegisterClass(MCInst &Inst, unsigned RegNo,
117 uint64_t Address,
118 const MCDisassembler *Decoder) {
119 assert(isUInt<2>(RegNo));
120 // Only AVR::R25R24, AVR::R27R26, AVR::R29R28, AVR::R31R30 are legal.
121 Inst.addOperand(Op: MCOperand::createReg(Reg: GPRPairDecoderTable[12 + RegNo]));
122 return MCDisassembler::Success;
123}
124
125static DecodeStatus DecodeZREGRegisterClass(MCInst &Inst,
126 const MCDisassembler *Decoder) {
127 Inst.addOperand(Op: MCOperand::createReg(Reg: AVR::R31R30));
128 return MCDisassembler::Success;
129}
130
131static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field,
132 uint64_t Address,
133 const MCDisassembler *Decoder) {
134 // Call targets need to be shifted left by one so this needs a custom
135 // decoder.
136 Inst.addOperand(Op: MCOperand::createImm(Val: Field << 1));
137 return MCDisassembler::Success;
138}
139
140static DecodeStatus decodeRelCondBrTarget7(MCInst &Inst, unsigned Field,
141 uint64_t Address,
142 const MCDisassembler *Decoder) {
143 // The legal range is [-128, 126] (in bytes).
144 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend32(X: Field, B: 7) * 2));
145 return MCDisassembler::Success;
146}
147
148static DecodeStatus decodeRelCondBrTarget13(MCInst &Inst, unsigned Field,
149 uint64_t Address,
150 const MCDisassembler *Decoder) {
151 // The legal range is [-4096, 4094] (in bytes).
152 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend32(X: Field, B: 12) * 2));
153 return MCDisassembler::Success;
154}
155
156static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
157 const MCDisassembler *Decoder) {
158 // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory
159 // address is encoded into 7-bit, in which bits 0-5 are the immediate offset,
160 // and the bit-6 is the pointer register bit (Z=0, Y=1).
161 if (Insn > 127)
162 return MCDisassembler::Fail;
163
164 // Append the base register operand.
165 Inst.addOperand(
166 Op: MCOperand::createReg(Reg: (Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));
167 // Append the immediate offset operand.
168 Inst.addOperand(Op: MCOperand::createImm(Val: Insn & 0x3f));
169
170 return MCDisassembler::Success;
171}
172
173static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
174 uint64_t Address,
175 const MCDisassembler *Decoder) {
176 // Get the register will be loaded or stored.
177 MCRegister RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f];
178
179 // Decode LDD/STD with offset less than 8.
180 if ((Insn & 0xf000) == 0x8000) {
181 unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30;
182 unsigned Offset = Insn & 7; // We need not consider offset > 7.
183 if ((Insn & 0x200) == 0) { // Decode LDD.
184 Inst.setOpcode(AVR::LDDRdPtrQ);
185 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
186 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
187 Inst.addOperand(Op: MCOperand::createImm(Val: Offset));
188 } else { // Decode STD.
189 Inst.setOpcode(AVR::STDPtrQRr);
190 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
191 Inst.addOperand(Op: MCOperand::createImm(Val: Offset));
192 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
193 }
194 return MCDisassembler::Success;
195 }
196
197 // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1),
198 // bits 8~4 indicate the value register, bits 3-2 indicate the base address
199 // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic,
200 // 01-postinc, 10-predec).
201 // ST X, Rr : 1001 001r rrrr 1100
202 // ST X+, Rr : 1001 001r rrrr 1101
203 // ST -X, Rr : 1001 001r rrrr 1110
204 // ST Y+, Rr : 1001 001r rrrr 1001
205 // ST -Y, Rr : 1001 001r rrrr 1010
206 // ST Z+, Rr : 1001 001r rrrr 0001
207 // ST -Z, Rr : 1001 001r rrrr 0010
208 // LD Rd, X : 1001 000d dddd 1100
209 // LD Rd, X+ : 1001 000d dddd 1101
210 // LD Rd, -X : 1001 000d dddd 1110
211 // LD Rd, Y+ : 1001 000d dddd 1001
212 // LD Rd, -Y : 1001 000d dddd 1010
213 // LD Rd, Z+ : 1001 000d dddd 0001
214 // LD Rd, -Z : 1001 000d dddd 0010
215 if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0)
216 return MCDisassembler::Fail;
217
218 // Get the base address register.
219 unsigned RegBase;
220 switch (Insn & 0xc) {
221 case 0xc:
222 RegBase = AVR::R27R26;
223 break;
224 case 0x8:
225 RegBase = AVR::R29R28;
226 break;
227 case 0x0:
228 RegBase = AVR::R31R30;
229 break;
230 default:
231 return MCDisassembler::Fail;
232 }
233
234 // Set the opcode.
235 switch (Insn & 0x203) {
236 case 0x200:
237 Inst.setOpcode(AVR::STPtrRr);
238 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
239 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
240 return MCDisassembler::Success;
241 case 0x201:
242 Inst.setOpcode(AVR::STPtrPiRr);
243 break;
244 case 0x202:
245 Inst.setOpcode(AVR::STPtrPdRr);
246 break;
247 case 0:
248 Inst.setOpcode(AVR::LDRdPtr);
249 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
250 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
251 return MCDisassembler::Success;
252 case 1:
253 Inst.setOpcode(AVR::LDRdPtrPi);
254 break;
255 case 2:
256 Inst.setOpcode(AVR::LDRdPtrPd);
257 break;
258 default:
259 return MCDisassembler::Fail;
260 }
261
262 // Build postinc/predec machine instructions.
263 if ((Insn & 0x200) == 0) { // This is a load instruction.
264 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
265 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
266 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
267 } else { // This is a store instruction.
268 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
269 Inst.addOperand(Op: MCOperand::createReg(Reg: RegBase));
270 Inst.addOperand(Op: MCOperand::createReg(Reg: RegVal));
271 // STPtrPiRr and STPtrPdRr have an extra immediate operand.
272 Inst.addOperand(Op: MCOperand::createImm(Val: 1));
273 }
274
275 return MCDisassembler::Success;
276}
277
278#include "AVRGenDisassemblerTables.inc"
279
280static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
281 uint64_t &Size, uint32_t &Insn) {
282 if (Bytes.size() < 2) {
283 Size = 0;
284 return MCDisassembler::Fail;
285 }
286
287 Size = 2;
288 Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
289
290 return MCDisassembler::Success;
291}
292
293static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
294 uint64_t &Size, uint32_t &Insn) {
295
296 if (Bytes.size() < 4) {
297 Size = 0;
298 return MCDisassembler::Fail;
299 }
300
301 Size = 4;
302 Insn =
303 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
304
305 return MCDisassembler::Success;
306}
307
308static const uint8_t *getDecoderTable(uint64_t Size) {
309
310 switch (Size) {
311 case 2:
312 return DecoderTable16;
313 case 4:
314 return DecoderTable32;
315 default:
316 llvm_unreachable("instructions must be 16 or 32-bits");
317 }
318}
319
320DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
321 ArrayRef<uint8_t> Bytes,
322 uint64_t Address,
323 raw_ostream &CStream) const {
324 uint32_t Insn;
325
326 DecodeStatus Result;
327
328 // Try decode a 16-bit instruction.
329 {
330 Result = readInstruction16(Bytes, Address, Size, Insn);
331
332 if (Result == MCDisassembler::Fail)
333 return MCDisassembler::Fail;
334
335 // Try to decode AVRTiny instructions.
336 if (STI.hasFeature(Feature: AVR::FeatureTinyEncoding)) {
337 Result = decodeInstruction(DecodeTable: DecoderTableAVRTiny16, MI&: Instr, insn: Insn, Address,
338 DisAsm: this, STI);
339 if (Result != MCDisassembler::Fail)
340 return Result;
341 }
342
343 // Try to auto-decode a 16-bit instruction.
344 Result = decodeInstruction(DecodeTable: getDecoderTable(Size), MI&: Instr, insn: Insn, Address,
345 DisAsm: this, STI);
346 if (Result != MCDisassembler::Fail)
347 return Result;
348
349 // Try to decode to a load/store instruction. ST/LD need a specified
350 // DecoderMethod, as they already have a specified PostEncoderMethod.
351 Result = decodeLoadStore(Inst&: Instr, Insn, Address, Decoder: this);
352 if (Result != MCDisassembler::Fail)
353 return Result;
354 }
355
356 // Try decode a 32-bit instruction.
357 {
358 Result = readInstruction32(Bytes, Address, Size, Insn);
359
360 if (Result == MCDisassembler::Fail)
361 return MCDisassembler::Fail;
362
363 Result = decodeInstruction(DecodeTable: getDecoderTable(Size), MI&: Instr, insn: Insn, Address,
364 DisAsm: this, STI);
365
366 if (Result != MCDisassembler::Fail) {
367 return Result;
368 }
369
370 return MCDisassembler::Fail;
371 }
372}
373
374typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
375 const MCDisassembler *Decoder);
376