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