1//===- AVRDisassembler.cpp - Disassembler for AVR ---------------*- C++ -*-===//
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
7//===----------------------------------------------------------------------===//
9// This file is part of the AVR Disassembler.
11//===----------------------------------------------------------------------===//
32 #define DEBUG_TYPE "avr-disassembler"
38/// A disassembler class for AVR.
43 ~AVRDisassembler()
override =
default;
54 return new AVRDisassembler(STI, Ctx);
59 // Register the disassembler.
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,
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,
94 // Only r16...r31 are legal.
103 // Only r16...r23 are legal.
120 // Only AVR::R25R24, AVR::R27R26, AVR::R29R28, AVR::R31R30 are legal.
134 // Call targets need to be shifted left by one so this needs a custom
143 // The legal range is [-128, 126] (in bytes).
151 // The legal range is [-4096, 4094] (in bytes).
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).
164 // Append the base register operand.
167 // Append the immediate offset operand.
176 // Get the register will be loaded or stored.
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.
188 }
else {
// Decode STD.
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)
218 // Get the base address register.
220 switch (Insn & 0xc) {
222 RegBase = AVR::R27R26;
225 RegBase = AVR::R29R28;
228 RegBase = AVR::R31R30;
235 switch (Insn & 0x203) {
262 // Build postinc/predec machine instructions.
263 if ((Insn & 0x200) == 0) {
// This is a load instruction.
267 }
else {
// This is a store instruction.
271 // STPtrPiRr and STPtrPdRr have an extra immediate operand.
278#include "AVRGenDisassemblerTables.inc"
282 if (Bytes.
size() < 2) {
288 Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
296 if (Bytes.
size() < 4) {
303 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
312 return DecoderTable16;
314 return DecoderTable32;
328 // Try decode a 16-bit instruction.
335 // Try to decode AVRTiny instructions.
336 if (STI.hasFeature(AVR::FeatureTinyEncoding)) {
337 Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn,
Address,
343 // Try to auto-decode a 16-bit instruction.
349 // Try to decode to a load/store instruction. ST/LD need a specified
350 // DecoderMethod, as they already have a specified PostEncoderMethod.
356 // Try decode a 32-bit instruction.
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static bool readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static const uint16_t GPRPairDecoderTable[]
static const uint16_t GPRDecoderTable[]
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler()
static DecodeStatus DecodeZREGRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeIWREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRelCondBrTarget7(MCInst &Inst, unsigned Field, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeDREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRelCondBrTarget13(MCInst &Inst, unsigned Field, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static MCDisassembler * createAVRDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static DecodeStatus DecodeLD8loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static const uint8_t * getDecoderTable(uint64_t Size)
static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, uint64_t Address, const MCDisassembler *Decoder)
#define LLVM_EXTERNAL_VISIBILITY
This file defines the DenseMap class.
OptimizedStructLayoutField Field
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Context object for machine code objects.
Superclass for all disassemblers.
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
Wrapper class representing virtual and physical registers.
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheAVRTarget()
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.