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() = default; 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 MCDisassembler *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 MCDisassembler *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 MCDisassembler *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 MCDisassembler *Decoder); 99 100 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 101 const MCDisassembler *Decoder); 102 103 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 104 const MCDisassembler *Decoder); 105 106 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, 107 uint64_t Address, 108 const MCDisassembler *Decoder); 109 110 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 111 const MCDisassembler *Decoder); 112 113 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 114 const MCDisassembler *Decoder); 115 116 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 117 uint64_t Address, 118 const MCDisassembler *Decoder); 119 120 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 121 uint64_t Address, 122 const MCDisassembler *Decoder); 123 124 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 125 const MCDisassembler *Decoder); 126 127 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 128 uint64_t Address, 129 const MCDisassembler *Decoder); 130 131 #include "AVRGenDisassemblerTables.inc" 132 133 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 134 const MCDisassembler *Decoder) { 135 unsigned addr = 0; 136 addr |= fieldFromInstruction(Insn, 0, 4); 137 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 138 unsigned reg = fieldFromInstruction(Insn, 4, 5); 139 Inst.addOperand(MCOperand::createImm(addr)); 140 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 141 MCDisassembler::Fail) 142 return MCDisassembler::Fail; 143 return MCDisassembler::Success; 144 } 145 146 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 147 const MCDisassembler *Decoder) { 148 unsigned addr = 0; 149 addr |= fieldFromInstruction(Insn, 0, 4); 150 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 151 unsigned reg = fieldFromInstruction(Insn, 4, 5); 152 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 153 MCDisassembler::Fail) 154 return MCDisassembler::Fail; 155 Inst.addOperand(MCOperand::createImm(addr)); 156 return MCDisassembler::Success; 157 } 158 159 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 160 const MCDisassembler *Decoder) { 161 unsigned addr = fieldFromInstruction(Insn, 3, 5); 162 unsigned b = fieldFromInstruction(Insn, 0, 3); 163 Inst.addOperand(MCOperand::createImm(addr)); 164 Inst.addOperand(MCOperand::createImm(b)); 165 return MCDisassembler::Success; 166 } 167 168 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, 169 uint64_t Address, 170 const MCDisassembler *Decoder) { 171 // Call targets need to be shifted left by one so this needs a custom 172 // decoder. 173 Inst.addOperand(MCOperand::createImm(Field << 1)); 174 return MCDisassembler::Success; 175 } 176 177 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 178 const MCDisassembler *Decoder) { 179 unsigned d = fieldFromInstruction(Insn, 4, 5); 180 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 181 MCDisassembler::Fail) 182 return MCDisassembler::Fail; 183 return MCDisassembler::Success; 184 } 185 186 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 187 const MCDisassembler *Decoder) { 188 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) 189 return MCDisassembler::Fail; 190 Inst.addOperand(MCOperand::createReg(AVR::R31R30)); 191 return MCDisassembler::Success; 192 } 193 194 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 195 uint64_t Address, 196 const MCDisassembler *Decoder) { 197 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; 198 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; 199 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 200 MCDisassembler::Fail) 201 return MCDisassembler::Fail; 202 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 203 MCDisassembler::Fail) 204 return MCDisassembler::Fail; 205 return MCDisassembler::Success; 206 } 207 208 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 209 uint64_t Address, 210 const MCDisassembler *Decoder) { 211 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; 212 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; 213 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 214 MCDisassembler::Fail) 215 return MCDisassembler::Fail; 216 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 217 MCDisassembler::Fail) 218 return MCDisassembler::Fail; 219 return MCDisassembler::Success; 220 } 221 222 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 223 const MCDisassembler *Decoder) { 224 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 225 unsigned k = 0; 226 k |= fieldFromInstruction(Insn, 0, 4); 227 k |= fieldFromInstruction(Insn, 6, 2) << 4; 228 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 229 MCDisassembler::Fail) 230 return MCDisassembler::Fail; 231 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 232 MCDisassembler::Fail) 233 return MCDisassembler::Fail; 234 Inst.addOperand(MCOperand::createImm(k)); 235 return MCDisassembler::Success; 236 } 237 238 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 239 uint64_t Address, 240 const MCDisassembler *Decoder) { 241 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; 242 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; 243 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == 244 MCDisassembler::Fail) 245 return MCDisassembler::Fail; 246 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == 247 MCDisassembler::Fail) 248 return MCDisassembler::Fail; 249 return MCDisassembler::Success; 250 } 251 252 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 253 uint64_t &Size, uint32_t &Insn) { 254 if (Bytes.size() < 2) { 255 Size = 0; 256 return MCDisassembler::Fail; 257 } 258 259 Size = 2; 260 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 261 262 return MCDisassembler::Success; 263 } 264 265 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 266 uint64_t &Size, uint32_t &Insn) { 267 268 if (Bytes.size() < 4) { 269 Size = 0; 270 return MCDisassembler::Fail; 271 } 272 273 Size = 4; 274 Insn = 275 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); 276 277 return MCDisassembler::Success; 278 } 279 280 static const uint8_t *getDecoderTable(uint64_t Size) { 281 282 switch (Size) { 283 case 2: 284 return DecoderTable16; 285 case 4: 286 return DecoderTable32; 287 default: 288 llvm_unreachable("instructions must be 16 or 32-bits"); 289 } 290 } 291 292 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 293 ArrayRef<uint8_t> Bytes, 294 uint64_t Address, 295 raw_ostream &CStream) const { 296 uint32_t Insn; 297 298 DecodeStatus Result; 299 300 // Try decode a 16-bit instruction. 301 { 302 Result = readInstruction16(Bytes, Address, Size, Insn); 303 304 if (Result == MCDisassembler::Fail) 305 return MCDisassembler::Fail; 306 307 // Try to auto-decode a 16-bit instruction. 308 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 309 this, STI); 310 311 if (Result != MCDisassembler::Fail) 312 return Result; 313 } 314 315 // Try decode a 32-bit instruction. 316 { 317 Result = readInstruction32(Bytes, Address, Size, Insn); 318 319 if (Result == MCDisassembler::Fail) 320 return MCDisassembler::Fail; 321 322 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 323 this, STI); 324 325 if (Result != MCDisassembler::Fail) { 326 return Result; 327 } 328 329 return MCDisassembler::Fail; 330 } 331 } 332 333 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 334 const MCDisassembler *Decoder); 335