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 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, 132 const MCDisassembler *Decoder); 133 134 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, 135 uint64_t Address, 136 const MCDisassembler *Decoder); 137 138 #include "AVRGenDisassemblerTables.inc" 139 140 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 141 const MCDisassembler *Decoder) { 142 unsigned addr = 0; 143 addr |= fieldFromInstruction(Insn, 0, 4); 144 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 145 unsigned reg = fieldFromInstruction(Insn, 4, 5); 146 Inst.addOperand(MCOperand::createImm(addr)); 147 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 148 MCDisassembler::Fail) 149 return MCDisassembler::Fail; 150 return MCDisassembler::Success; 151 } 152 153 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 154 const MCDisassembler *Decoder) { 155 unsigned addr = 0; 156 addr |= fieldFromInstruction(Insn, 0, 4); 157 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 158 unsigned reg = fieldFromInstruction(Insn, 4, 5); 159 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 160 MCDisassembler::Fail) 161 return MCDisassembler::Fail; 162 Inst.addOperand(MCOperand::createImm(addr)); 163 return MCDisassembler::Success; 164 } 165 166 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 167 const MCDisassembler *Decoder) { 168 unsigned addr = fieldFromInstruction(Insn, 3, 5); 169 unsigned b = fieldFromInstruction(Insn, 0, 3); 170 Inst.addOperand(MCOperand::createImm(addr)); 171 Inst.addOperand(MCOperand::createImm(b)); 172 return MCDisassembler::Success; 173 } 174 175 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, 176 uint64_t Address, 177 const MCDisassembler *Decoder) { 178 // Call targets need to be shifted left by one so this needs a custom 179 // decoder. 180 Inst.addOperand(MCOperand::createImm(Field << 1)); 181 return MCDisassembler::Success; 182 } 183 184 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 185 const MCDisassembler *Decoder) { 186 unsigned d = fieldFromInstruction(Insn, 4, 5); 187 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 188 MCDisassembler::Fail) 189 return MCDisassembler::Fail; 190 return MCDisassembler::Success; 191 } 192 193 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 194 const MCDisassembler *Decoder) { 195 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) 196 return MCDisassembler::Fail; 197 Inst.addOperand(MCOperand::createReg(AVR::R31R30)); 198 return MCDisassembler::Success; 199 } 200 201 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 202 uint64_t Address, 203 const MCDisassembler *Decoder) { 204 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; 205 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; 206 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 207 MCDisassembler::Fail) 208 return MCDisassembler::Fail; 209 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 210 MCDisassembler::Fail) 211 return MCDisassembler::Fail; 212 return MCDisassembler::Success; 213 } 214 215 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 216 uint64_t Address, 217 const MCDisassembler *Decoder) { 218 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; 219 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; 220 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 221 MCDisassembler::Fail) 222 return MCDisassembler::Fail; 223 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 224 MCDisassembler::Fail) 225 return MCDisassembler::Fail; 226 return MCDisassembler::Success; 227 } 228 229 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 230 const MCDisassembler *Decoder) { 231 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 232 unsigned k = 0; 233 k |= fieldFromInstruction(Insn, 0, 4); 234 k |= fieldFromInstruction(Insn, 6, 2) << 4; 235 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 236 MCDisassembler::Fail) 237 return MCDisassembler::Fail; 238 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 239 MCDisassembler::Fail) 240 return MCDisassembler::Fail; 241 Inst.addOperand(MCOperand::createImm(k)); 242 return MCDisassembler::Success; 243 } 244 245 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 246 uint64_t Address, 247 const MCDisassembler *Decoder) { 248 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; 249 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; 250 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == 251 MCDisassembler::Fail) 252 return MCDisassembler::Fail; 253 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == 254 MCDisassembler::Fail) 255 return MCDisassembler::Fail; 256 return MCDisassembler::Success; 257 } 258 259 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, 260 const MCDisassembler *Decoder) { 261 // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory 262 // address is encoded into 7-bit, in which bits 0-5 are the immediate offset, 263 // and the bit-6 is the pointer register bit (Z=0, Y=1). 264 if (Insn > 127) 265 return MCDisassembler::Fail; 266 267 // Append the base register operand. 268 Inst.addOperand( 269 MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30)); 270 // Append the immediate offset operand. 271 Inst.addOperand(MCOperand::createImm(Insn & 0x3f)); 272 273 return MCDisassembler::Success; 274 } 275 276 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, 277 uint64_t Address, 278 const MCDisassembler *Decoder) { 279 // Get the register will be loaded or stored. 280 unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f]; 281 282 // Decode LDD/STD with offset less than 8. 283 if ((Insn & 0xf000) == 0x8000) { 284 unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30; 285 unsigned Offset = Insn & 7; // We need not consider offset > 7. 286 if ((Insn & 0x200) == 0) { // Decode LDD. 287 Inst.setOpcode(AVR::LDDRdPtrQ); 288 Inst.addOperand(MCOperand::createReg(RegVal)); 289 Inst.addOperand(MCOperand::createReg(RegBase)); 290 Inst.addOperand(MCOperand::createImm(Offset)); 291 } else { // Decode STD. 292 Inst.setOpcode(AVR::STDPtrQRr); 293 Inst.addOperand(MCOperand::createReg(RegBase)); 294 Inst.addOperand(MCOperand::createImm(Offset)); 295 Inst.addOperand(MCOperand::createReg(RegVal)); 296 } 297 return MCDisassembler::Success; 298 } 299 300 // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1), 301 // bits 8~4 indicate the value register, bits 3-2 indicate the base address 302 // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic, 303 // 01-postinc, 10-predec). 304 // ST X, Rr : 1001 001r rrrr 1100 305 // ST X+, Rr : 1001 001r rrrr 1101 306 // ST -X, Rr : 1001 001r rrrr 1110 307 // ST Y+, Rr : 1001 001r rrrr 1001 308 // ST -Y, Rr : 1001 001r rrrr 1010 309 // ST Z+, Rr : 1001 001r rrrr 0001 310 // ST -Z, Rr : 1001 001r rrrr 0010 311 // LD Rd, X : 1001 000d dddd 1100 312 // LD Rd, X+ : 1001 000d dddd 1101 313 // LD Rd, -X : 1001 000d dddd 1110 314 // LD Rd, Y+ : 1001 000d dddd 1001 315 // LD Rd, -Y : 1001 000d dddd 1010 316 // LD Rd, Z+ : 1001 000d dddd 0001 317 // LD Rd, -Z : 1001 000d dddd 0010 318 if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) 319 return MCDisassembler::Fail; 320 321 // Get the base address register. 322 unsigned RegBase; 323 switch (Insn & 0xc) { 324 case 0xc: 325 RegBase = AVR::R27R26; 326 break; 327 case 0x8: 328 RegBase = AVR::R29R28; 329 break; 330 case 0x0: 331 RegBase = AVR::R31R30; 332 break; 333 default: 334 return MCDisassembler::Fail; 335 } 336 337 // Set the opcode. 338 switch (Insn & 0x203) { 339 case 0x200: 340 Inst.setOpcode(AVR::STPtrRr); 341 Inst.addOperand(MCOperand::createReg(RegBase)); 342 Inst.addOperand(MCOperand::createReg(RegVal)); 343 return MCDisassembler::Success; 344 case 0x201: 345 Inst.setOpcode(AVR::STPtrPiRr); 346 break; 347 case 0x202: 348 Inst.setOpcode(AVR::STPtrPdRr); 349 break; 350 case 0: 351 Inst.setOpcode(AVR::LDRdPtr); 352 Inst.addOperand(MCOperand::createReg(RegVal)); 353 Inst.addOperand(MCOperand::createReg(RegBase)); 354 return MCDisassembler::Success; 355 case 1: 356 Inst.setOpcode(AVR::LDRdPtrPi); 357 break; 358 case 2: 359 Inst.setOpcode(AVR::LDRdPtrPd); 360 break; 361 default: 362 return MCDisassembler::Fail; 363 } 364 365 // Build postinc/predec machine instructions. 366 if ((Insn & 0x200) == 0) { // This is a load instruction. 367 Inst.addOperand(MCOperand::createReg(RegVal)); 368 Inst.addOperand(MCOperand::createReg(RegBase)); 369 Inst.addOperand(MCOperand::createReg(RegBase)); 370 } else { // This is a store instruction. 371 Inst.addOperand(MCOperand::createReg(RegBase)); 372 Inst.addOperand(MCOperand::createReg(RegBase)); 373 Inst.addOperand(MCOperand::createReg(RegVal)); 374 // STPtrPiRr and STPtrPdRr have an extra immediate operand. 375 Inst.addOperand(MCOperand::createImm(1)); 376 } 377 378 return MCDisassembler::Success; 379 } 380 381 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 382 uint64_t &Size, uint32_t &Insn) { 383 if (Bytes.size() < 2) { 384 Size = 0; 385 return MCDisassembler::Fail; 386 } 387 388 Size = 2; 389 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 390 391 return MCDisassembler::Success; 392 } 393 394 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 395 uint64_t &Size, uint32_t &Insn) { 396 397 if (Bytes.size() < 4) { 398 Size = 0; 399 return MCDisassembler::Fail; 400 } 401 402 Size = 4; 403 Insn = 404 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); 405 406 return MCDisassembler::Success; 407 } 408 409 static const uint8_t *getDecoderTable(uint64_t Size) { 410 411 switch (Size) { 412 case 2: 413 return DecoderTable16; 414 case 4: 415 return DecoderTable32; 416 default: 417 llvm_unreachable("instructions must be 16 or 32-bits"); 418 } 419 } 420 421 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 422 ArrayRef<uint8_t> Bytes, 423 uint64_t Address, 424 raw_ostream &CStream) const { 425 uint32_t Insn; 426 427 DecodeStatus Result; 428 429 // Try decode a 16-bit instruction. 430 { 431 Result = readInstruction16(Bytes, Address, Size, Insn); 432 433 if (Result == MCDisassembler::Fail) 434 return MCDisassembler::Fail; 435 436 // Try to auto-decode a 16-bit instruction. 437 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 438 this, STI); 439 if (Result != MCDisassembler::Fail) 440 return Result; 441 442 // Try to decode to a load/store instruction. ST/LD need a specified 443 // DecoderMethod, as they already have a specified PostEncoderMethod. 444 Result = decodeLoadStore(Instr, Insn, Address, this); 445 if (Result != MCDisassembler::Fail) 446 return Result; 447 } 448 449 // Try decode a 32-bit instruction. 450 { 451 Result = readInstruction32(Bytes, Address, Size, Insn); 452 453 if (Result == MCDisassembler::Fail) 454 return MCDisassembler::Fail; 455 456 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 457 this, STI); 458 459 if (Result != MCDisassembler::Fail) { 460 return Result; 461 } 462 463 return MCDisassembler::Fail; 464 } 465 } 466 467 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 468 const MCDisassembler *Decoder); 469