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 26 using namespace llvm; 27 28 #define DEBUG_TYPE "avr-disassembler" 29 30 typedef MCDisassembler::DecodeStatus DecodeStatus; 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 47 static MCDisassembler *createAVRDisassembler(const Target &T, 48 const MCSubtargetInfo &STI, 49 MCContext &Ctx) { 50 return new AVRDisassembler(STI, Ctx); 51 } 52 53 54 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { 55 // Register the disassembler. 56 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(), 57 createAVRDisassembler); 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]; 77 Inst.addOperand(MCOperand::createReg(Register)); 78 return MCDisassembler::Success; 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]; 87 Inst.addOperand(MCOperand::createReg(Register)); 88 return MCDisassembler::Success; 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"); 95 return MCDisassembler::Success; 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 decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 120 uint64_t Address, const void *Decoder); 121 122 #include "AVRGenDisassemblerTables.inc" 123 124 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, 125 uint64_t Address, const void *Decoder) { 126 unsigned addr = 0; 127 addr |= fieldFromInstruction(Insn, 0, 4); 128 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 129 unsigned reg = fieldFromInstruction(Insn, 4, 5); 130 Inst.addOperand(MCOperand::createImm(addr)); 131 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) 132 return MCDisassembler::Fail; 133 return MCDisassembler::Success; 134 } 135 136 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, 137 uint64_t Address, const void *Decoder) { 138 unsigned addr = 0; 139 addr |= fieldFromInstruction(Insn, 0, 4); 140 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 141 unsigned reg = fieldFromInstruction(Insn, 4, 5); 142 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) 143 return MCDisassembler::Fail; 144 Inst.addOperand(MCOperand::createImm(addr)); 145 return MCDisassembler::Success; 146 } 147 148 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, 149 uint64_t Address, const void *Decoder) { 150 unsigned addr = fieldFromInstruction(Insn, 3, 5); 151 unsigned b = fieldFromInstruction(Insn, 0, 3); 152 Inst.addOperand(MCOperand::createImm(addr)); 153 Inst.addOperand(MCOperand::createImm(b)); 154 return MCDisassembler::Success; 155 } 156 157 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, 158 uint64_t Address, const void *Decoder) { 159 // Call targets need to be shifted left by one so this needs a custom 160 // decoder. 161 Inst.addOperand(MCOperand::createImm(Field << 1)); 162 return MCDisassembler::Success; 163 } 164 165 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, 166 uint64_t Address, const void *Decoder) { 167 unsigned d = fieldFromInstruction(Insn, 4, 5); 168 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) 169 return MCDisassembler::Fail; 170 return MCDisassembler::Success; 171 } 172 173 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, 174 uint64_t Address, const void *Decoder) { 175 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) 176 return MCDisassembler::Fail; 177 Inst.addOperand(MCOperand::createReg(AVR::R31R30)); 178 return MCDisassembler::Success; 179 } 180 181 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 182 uint64_t Address, const void *Decoder) { 183 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; 184 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; 185 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) 186 return MCDisassembler::Fail; 187 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) 188 return MCDisassembler::Fail; 189 return MCDisassembler::Success; 190 } 191 192 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 193 uint64_t Address, const void *Decoder) { 194 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; 195 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; 196 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail) 197 return MCDisassembler::Fail; 198 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail) 199 return MCDisassembler::Fail; 200 return MCDisassembler::Success; 201 } 202 203 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 204 uint64_t &Size, uint32_t &Insn) { 205 if (Bytes.size() < 2) { 206 Size = 0; 207 return MCDisassembler::Fail; 208 } 209 210 Size = 2; 211 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 212 213 return MCDisassembler::Success; 214 } 215 216 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 217 uint64_t &Size, uint32_t &Insn) { 218 219 if (Bytes.size() < 4) { 220 Size = 0; 221 return MCDisassembler::Fail; 222 } 223 224 Size = 4; 225 Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); 226 227 return MCDisassembler::Success; 228 } 229 230 static const uint8_t *getDecoderTable(uint64_t Size) { 231 232 switch (Size) { 233 case 2: return DecoderTable16; 234 case 4: return DecoderTable32; 235 default: llvm_unreachable("instructions must be 16 or 32-bits"); 236 } 237 } 238 239 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 240 ArrayRef<uint8_t> Bytes, 241 uint64_t Address, 242 raw_ostream &CStream) const { 243 uint32_t Insn; 244 245 DecodeStatus Result; 246 247 // Try decode a 16-bit instruction. 248 { 249 Result = readInstruction16(Bytes, Address, Size, Insn); 250 251 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 252 253 // Try to auto-decode a 16-bit instruction. 254 Result = decodeInstruction(getDecoderTable(Size), Instr, 255 Insn, Address, this, STI); 256 257 if (Result != MCDisassembler::Fail) 258 return Result; 259 } 260 261 // Try decode a 32-bit instruction. 262 { 263 Result = readInstruction32(Bytes, Address, Size, Insn); 264 265 if (Result == MCDisassembler::Fail) return MCDisassembler::Fail; 266 267 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, 268 Address, this, STI); 269 270 if (Result != MCDisassembler::Fail) { 271 return Result; 272 } 273 274 return MCDisassembler::Fail; 275 } 276 } 277 278 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 279 const void *Decoder); 280 281