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" 16#include "MCTargetDesc/AVRMCTargetDesc.h" 17#include "TargetInfo/AVRTargetInfo.h" 18 19#include "llvm/MC/MCAsmInfo.h" 20#include "llvm/MC/MCContext.h" 21#include "llvm/MC/MCDisassembler/MCDisassembler.h" 22#include "llvm/MC/MCFixedLenDisassembler.h" 23#include "llvm/MC/MCInst.h" 24#include "llvm/Support/TargetRegistry.h" 25 26using namespace llvm; 27 28#define DEBUG_TYPE "avr-disassembler" 29 30typedef MCDisassembler::DecodeStatus DecodeStatus; 31 32namespace { 33 34/// A disassembler class for AVR. 35class AVRDisassembler : public MCDisassembler { 36public: 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 47static MCDisassembler *createAVRDisassembler(const Target &T, 48 const MCSubtargetInfo &STI, 49 MCContext &Ctx) { 50 return new AVRDisassembler(STI, Ctx); 51} 52 53 54extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { 55 // Register the disassembler. 56 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(), 57 createAVRDisassembler); 58} 59 60static 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 71static 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]; 77 Inst.addOperand(MCOperand::createReg(Register)); 78 return MCDisassembler::Success; 79} 80 81static 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]; 87 Inst.addOperand(MCOperand::createReg(Register)); 88 return MCDisassembler::Success; 89} 90 91static 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"); 95 return MCDisassembler::Success; 96} 97 98static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, 99 uint64_t Address, const void *Decoder); 100 101static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, 102 uint64_t Address, const void *Decoder); 103 104static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, 105 uint64_t Address, const void *Decoder); 106 107static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, 108 uint64_t Address, const void *Decoder); 109 110static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, 111 uint64_t Address, const void *Decoder); 112 113static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, 114 uint64_t Address, const void *Decoder); 115 116static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 117 uint64_t Address, const void *Decoder); 118 119static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 120 uint64_t Address, const void *Decoder); 121 122static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, 123 uint64_t Address, const void *Decoder); 124 125static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 126 uint64_t Address, const void *Decoder); 127 128#include "AVRGenDisassemblerTables.inc" 129 130static 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; 139 return MCDisassembler::Success; 140} 141 142static 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)); 151 return MCDisassembler::Success; 152} 153 154static 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)); 159 Inst.addOperand(MCOperand::createImm(b)); 160 return MCDisassembler::Success; 161} 162 163static 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. 167 Inst.addOperand(MCOperand::createImm(Field << 1)); 168 return MCDisassembler::Success; 169} 170 171static 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; 176 return MCDisassembler::Success; 177} 178 179static 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)); 184 return MCDisassembler::Success; 185} 186 187static 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; 195 return MCDisassembler::Success; 196} 197 198static 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; 206 return MCDisassembler::Success; 207} 208 209static 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; 219 Inst.addOperand(MCOperand::createImm(k)); 220 return MCDisassembler::Success; 221} 222 223static 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; 231 return MCDisassembler::Success; 232} 233 234static 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 244 return MCDisassembler::Success; 245} 246 247static 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 258 return MCDisassembler::Success; 259} 260 261static 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 270DecodeStatus 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 276 DecodeStatus Result; 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 309typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 310 const void *Decoder); 311 312