376 lines · cpp
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-exception6//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} // namespace50 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 void58LLVMInitializeAVRDisassembler() {59 // Register the disassembler.60 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(),61 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(MCOperand::createReg(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(MCOperand::createReg(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(MCOperand::createReg(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(MCOperand::createReg(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(MCOperand::createReg(GPRPairDecoderTable[12 + RegNo]));122 return MCDisassembler::Success;123}124 125static DecodeStatus DecodeZREGRegisterClass(MCInst &Inst,126 const MCDisassembler *Decoder) {127 Inst.addOperand(MCOperand::createReg(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 custom135 // decoder.136 Inst.addOperand(MCOperand::createImm(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(MCOperand::createImm(SignExtend32(Field, 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(MCOperand::createImm(SignExtend32(Field, 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 memory159 // 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 MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30));167 // Append the immediate offset operand.168 Inst.addOperand(MCOperand::createImm(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(MCOperand::createReg(RegVal));186 Inst.addOperand(MCOperand::createReg(RegBase));187 Inst.addOperand(MCOperand::createImm(Offset));188 } else { // Decode STD.189 Inst.setOpcode(AVR::STDPtrQRr);190 Inst.addOperand(MCOperand::createReg(RegBase));191 Inst.addOperand(MCOperand::createImm(Offset));192 Inst.addOperand(MCOperand::createReg(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 address199 // 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 1100202 // ST X+, Rr : 1001 001r rrrr 1101203 // ST -X, Rr : 1001 001r rrrr 1110204 // ST Y+, Rr : 1001 001r rrrr 1001205 // ST -Y, Rr : 1001 001r rrrr 1010206 // ST Z+, Rr : 1001 001r rrrr 0001207 // ST -Z, Rr : 1001 001r rrrr 0010208 // LD Rd, X : 1001 000d dddd 1100209 // LD Rd, X+ : 1001 000d dddd 1101210 // LD Rd, -X : 1001 000d dddd 1110211 // LD Rd, Y+ : 1001 000d dddd 1001212 // LD Rd, -Y : 1001 000d dddd 1010213 // LD Rd, Z+ : 1001 000d dddd 0001214 // LD Rd, -Z : 1001 000d dddd 0010215 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(MCOperand::createReg(RegBase));239 Inst.addOperand(MCOperand::createReg(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(MCOperand::createReg(RegVal));250 Inst.addOperand(MCOperand::createReg(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(MCOperand::createReg(RegVal));265 Inst.addOperand(MCOperand::createReg(RegBase));266 Inst.addOperand(MCOperand::createReg(RegBase));267 } else { // This is a store instruction.268 Inst.addOperand(MCOperand::createReg(RegBase));269 Inst.addOperand(MCOperand::createReg(RegBase));270 Inst.addOperand(MCOperand::createReg(RegVal));271 // STPtrPiRr and STPtrPdRr have an extra immediate operand.272 Inst.addOperand(MCOperand::createImm(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(AVR::FeatureTinyEncoding)) {337 Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn, Address,338 this, STI);339 if (Result != MCDisassembler::Fail)340 return Result;341 }342 343 // Try to auto-decode a 16-bit instruction.344 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address,345 this, STI);346 if (Result != MCDisassembler::Fail)347 return Result;348 349 // Try to decode to a load/store instruction. ST/LD need a specified350 // DecoderMethod, as they already have a specified PostEncoderMethod.351 Result = decodeLoadStore(Instr, Insn, Address, 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(getDecoderTable(Size), Instr, Insn, Address,364 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