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/MC/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 } // namespace 46 47 static MCDisassembler *createAVRDisassembler(const Target &T, 48 const MCSubtargetInfo &STI, 49 MCContext &Ctx) { 50 return new AVRDisassembler(STI, Ctx); 51 } 52 53 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { 54 // Register the disassembler. 55 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(), 56 createAVRDisassembler); 57 } 58 59 static const uint16_t GPRDecoderTable[] = { 60 AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6, 61 AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13, 62 AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20, 63 AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27, 64 AVR::R28, AVR::R29, AVR::R30, AVR::R31, 65 }; 66 67 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, 68 uint64_t Address, 69 const void *Decoder) { 70 if (RegNo > 31) 71 return MCDisassembler::Fail; 72 73 unsigned Register = GPRDecoderTable[RegNo]; 74 Inst.addOperand(MCOperand::createReg(Register)); 75 return MCDisassembler::Success; 76 } 77 78 static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, 79 uint64_t Address, 80 const void *Decoder) { 81 if (RegNo > 15) 82 return MCDisassembler::Fail; 83 84 unsigned Register = GPRDecoderTable[RegNo + 16]; 85 Inst.addOperand(MCOperand::createReg(Register)); 86 return MCDisassembler::Success; 87 } 88 89 static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, 90 uint64_t Address, 91 const void *Decoder) { 92 // Note: this function must be defined but does not seem to be called. 93 assert(false && "unimplemented: PTRREGS register class"); 94 return MCDisassembler::Success; 95 } 96 97 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 98 const void *Decoder); 99 100 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 101 const void *Decoder); 102 103 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 104 const void *Decoder); 105 106 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, 107 uint64_t Address, const void *Decoder); 108 109 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 110 const void *Decoder); 111 112 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 113 const void *Decoder); 114 115 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 116 uint64_t Address, const void *Decoder); 117 118 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 119 uint64_t Address, const void *Decoder); 120 121 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 122 const void *Decoder); 123 124 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 125 uint64_t Address, const void *Decoder); 126 127 #include "AVRGenDisassemblerTables.inc" 128 129 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 130 const void *Decoder) { 131 unsigned addr = 0; 132 addr |= fieldFromInstruction(Insn, 0, 4); 133 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 134 unsigned reg = fieldFromInstruction(Insn, 4, 5); 135 Inst.addOperand(MCOperand::createImm(addr)); 136 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 137 MCDisassembler::Fail) 138 return MCDisassembler::Fail; 139 return MCDisassembler::Success; 140 } 141 142 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 143 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) == 149 MCDisassembler::Fail) 150 return MCDisassembler::Fail; 151 Inst.addOperand(MCOperand::createImm(addr)); 152 return MCDisassembler::Success; 153 } 154 155 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 156 const void *Decoder) { 157 unsigned addr = fieldFromInstruction(Insn, 3, 5); 158 unsigned b = fieldFromInstruction(Insn, 0, 3); 159 Inst.addOperand(MCOperand::createImm(addr)); 160 Inst.addOperand(MCOperand::createImm(b)); 161 return MCDisassembler::Success; 162 } 163 164 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, 165 uint64_t Address, const void *Decoder) { 166 // Call targets need to be shifted left by one so this needs a custom 167 // decoder. 168 Inst.addOperand(MCOperand::createImm(Field << 1)); 169 return MCDisassembler::Success; 170 } 171 172 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 173 const void *Decoder) { 174 unsigned d = fieldFromInstruction(Insn, 4, 5); 175 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 176 MCDisassembler::Fail) 177 return MCDisassembler::Fail; 178 return MCDisassembler::Success; 179 } 180 181 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 182 const void *Decoder) { 183 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) 184 return MCDisassembler::Fail; 185 Inst.addOperand(MCOperand::createReg(AVR::R31R30)); 186 return MCDisassembler::Success; 187 } 188 189 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 190 uint64_t Address, const void *Decoder) { 191 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; 192 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; 193 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 194 MCDisassembler::Fail) 195 return MCDisassembler::Fail; 196 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 197 MCDisassembler::Fail) 198 return MCDisassembler::Fail; 199 return MCDisassembler::Success; 200 } 201 202 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 203 uint64_t Address, const void *Decoder) { 204 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; 205 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; 206 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 207 MCDisassembler::Fail) 208 return MCDisassembler::Fail; 209 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 210 MCDisassembler::Fail) 211 return MCDisassembler::Fail; 212 return MCDisassembler::Success; 213 } 214 215 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 216 const void *Decoder) { 217 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 218 unsigned k = 0; 219 k |= fieldFromInstruction(Insn, 0, 4); 220 k |= fieldFromInstruction(Insn, 6, 2) << 4; 221 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 222 MCDisassembler::Fail) 223 return MCDisassembler::Fail; 224 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 225 MCDisassembler::Fail) 226 return MCDisassembler::Fail; 227 Inst.addOperand(MCOperand::createImm(k)); 228 return MCDisassembler::Success; 229 } 230 231 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 232 uint64_t Address, const void *Decoder) { 233 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; 234 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; 235 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == 236 MCDisassembler::Fail) 237 return MCDisassembler::Fail; 238 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == 239 MCDisassembler::Fail) 240 return MCDisassembler::Fail; 241 return MCDisassembler::Success; 242 } 243 244 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 245 uint64_t &Size, uint32_t &Insn) { 246 if (Bytes.size() < 2) { 247 Size = 0; 248 return MCDisassembler::Fail; 249 } 250 251 Size = 2; 252 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 253 254 return MCDisassembler::Success; 255 } 256 257 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 258 uint64_t &Size, uint32_t &Insn) { 259 260 if (Bytes.size() < 4) { 261 Size = 0; 262 return MCDisassembler::Fail; 263 } 264 265 Size = 4; 266 Insn = 267 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); 268 269 return MCDisassembler::Success; 270 } 271 272 static const uint8_t *getDecoderTable(uint64_t Size) { 273 274 switch (Size) { 275 case 2: 276 return DecoderTable16; 277 case 4: 278 return DecoderTable32; 279 default: 280 llvm_unreachable("instructions must be 16 or 32-bits"); 281 } 282 } 283 284 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 285 ArrayRef<uint8_t> Bytes, 286 uint64_t Address, 287 raw_ostream &CStream) const { 288 uint32_t Insn; 289 290 DecodeStatus Result; 291 292 // Try decode a 16-bit instruction. 293 { 294 Result = readInstruction16(Bytes, Address, Size, Insn); 295 296 if (Result == MCDisassembler::Fail) 297 return MCDisassembler::Fail; 298 299 // Try to auto-decode a 16-bit instruction. 300 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 301 this, STI); 302 303 if (Result != MCDisassembler::Fail) 304 return Result; 305 } 306 307 // Try decode a 32-bit instruction. 308 { 309 Result = readInstruction32(Bytes, Address, Size, Insn); 310 311 if (Result == MCDisassembler::Fail) 312 return MCDisassembler::Fail; 313 314 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 315 this, STI); 316 317 if (Result != MCDisassembler::Fail) { 318 return Result; 319 } 320 321 return MCDisassembler::Fail; 322 } 323 } 324 325 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 326 const void *Decoder); 327