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/ADT/DenseMap.h" 20 #include "llvm/ADT/STLExtras.h" 21 22 #include "llvm/MC/MCAsmInfo.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCDecoderOps.h" 25 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 26 #include "llvm/MC/MCInst.h" 27 #include "llvm/MC/TargetRegistry.h" 28 29 using namespace llvm; 30 31 #define DEBUG_TYPE "avr-disassembler" 32 33 typedef MCDisassembler::DecodeStatus DecodeStatus; 34 35 namespace { 36 37 /// A disassembler class for AVR. 38 class AVRDisassembler : public MCDisassembler { 39 public: 40 AVRDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 41 : MCDisassembler(STI, Ctx) {} 42 virtual ~AVRDisassembler() = default; 43 44 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 45 ArrayRef<uint8_t> Bytes, uint64_t Address, 46 raw_ostream &CStream) const override; 47 }; 48 } // namespace 49 50 static MCDisassembler *createAVRDisassembler(const Target &T, 51 const MCSubtargetInfo &STI, 52 MCContext &Ctx) { 53 return new AVRDisassembler(STI, Ctx); 54 } 55 56 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { 57 // Register the disassembler. 58 TargetRegistry::RegisterMCDisassembler(getTheAVRTarget(), 59 createAVRDisassembler); 60 } 61 62 static const uint16_t GPRDecoderTable[] = { 63 AVR::R0, AVR::R1, AVR::R2, AVR::R3, AVR::R4, AVR::R5, AVR::R6, 64 AVR::R7, AVR::R8, AVR::R9, AVR::R10, AVR::R11, AVR::R12, AVR::R13, 65 AVR::R14, AVR::R15, AVR::R16, AVR::R17, AVR::R18, AVR::R19, AVR::R20, 66 AVR::R21, AVR::R22, AVR::R23, AVR::R24, AVR::R25, AVR::R26, AVR::R27, 67 AVR::R28, AVR::R29, AVR::R30, AVR::R31, 68 }; 69 70 static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, 71 uint64_t Address, 72 const MCDisassembler *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, 83 const MCDisassembler *Decoder) { 84 if (RegNo > 15) 85 return MCDisassembler::Fail; 86 87 unsigned Register = GPRDecoderTable[RegNo + 16]; 88 Inst.addOperand(MCOperand::createReg(Register)); 89 return MCDisassembler::Success; 90 } 91 92 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 93 const MCDisassembler *Decoder); 94 95 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 96 const MCDisassembler *Decoder); 97 98 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 99 const MCDisassembler *Decoder); 100 101 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, 102 uint64_t Address, 103 const MCDisassembler *Decoder); 104 105 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 106 const MCDisassembler *Decoder); 107 108 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 109 const MCDisassembler *Decoder); 110 111 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 112 uint64_t Address, 113 const MCDisassembler *Decoder); 114 115 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 116 uint64_t Address, 117 const MCDisassembler *Decoder); 118 119 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 120 const MCDisassembler *Decoder); 121 122 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 123 uint64_t Address, 124 const MCDisassembler *Decoder); 125 126 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, 127 const MCDisassembler *Decoder); 128 129 static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address, 130 const MCDisassembler *Decoder); 131 132 static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn, 133 uint64_t Address, 134 const MCDisassembler *Decoder); 135 136 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, 137 uint64_t Address, 138 const MCDisassembler *Decoder); 139 140 #include "AVRGenDisassemblerTables.inc" 141 142 static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, uint64_t Address, 143 const MCDisassembler *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 Inst.addOperand(MCOperand::createImm(addr)); 149 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 150 MCDisassembler::Fail) 151 return MCDisassembler::Fail; 152 return MCDisassembler::Success; 153 } 154 155 static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, uint64_t Address, 156 const MCDisassembler *Decoder) { 157 unsigned addr = 0; 158 addr |= fieldFromInstruction(Insn, 0, 4); 159 addr |= fieldFromInstruction(Insn, 9, 2) << 4; 160 unsigned reg = fieldFromInstruction(Insn, 4, 5); 161 if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == 162 MCDisassembler::Fail) 163 return MCDisassembler::Fail; 164 Inst.addOperand(MCOperand::createImm(addr)); 165 return MCDisassembler::Success; 166 } 167 168 static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, uint64_t Address, 169 const MCDisassembler *Decoder) { 170 unsigned addr = fieldFromInstruction(Insn, 3, 5); 171 unsigned b = fieldFromInstruction(Insn, 0, 3); 172 Inst.addOperand(MCOperand::createImm(addr)); 173 Inst.addOperand(MCOperand::createImm(b)); 174 return MCDisassembler::Success; 175 } 176 177 static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, 178 uint64_t Address, 179 const MCDisassembler *Decoder) { 180 // Call targets need to be shifted left by one so this needs a custom 181 // decoder. 182 Inst.addOperand(MCOperand::createImm(Field << 1)); 183 return MCDisassembler::Success; 184 } 185 186 static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, uint64_t Address, 187 const MCDisassembler *Decoder) { 188 unsigned d = fieldFromInstruction(Insn, 4, 5); 189 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 190 MCDisassembler::Fail) 191 return MCDisassembler::Fail; 192 return MCDisassembler::Success; 193 } 194 195 static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, uint64_t Address, 196 const MCDisassembler *Decoder) { 197 if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) 198 return MCDisassembler::Fail; 199 Inst.addOperand(MCOperand::createReg(AVR::R31R30)); 200 return MCDisassembler::Success; 201 } 202 203 static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, 204 uint64_t Address, 205 const MCDisassembler *Decoder) { 206 unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; 207 unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; 208 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 209 MCDisassembler::Fail) 210 return MCDisassembler::Fail; 211 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 212 MCDisassembler::Fail) 213 return MCDisassembler::Fail; 214 return MCDisassembler::Success; 215 } 216 217 static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, 218 uint64_t Address, 219 const MCDisassembler *Decoder) { 220 unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; 221 unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; 222 if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == 223 MCDisassembler::Fail) 224 return MCDisassembler::Fail; 225 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 226 MCDisassembler::Fail) 227 return MCDisassembler::Fail; 228 return MCDisassembler::Success; 229 } 230 231 static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, uint64_t Address, 232 const MCDisassembler *Decoder) { 233 unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 234 unsigned k = 0; 235 k |= fieldFromInstruction(Insn, 0, 4); 236 k |= fieldFromInstruction(Insn, 6, 2) << 4; 237 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 238 MCDisassembler::Fail) 239 return MCDisassembler::Fail; 240 if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == 241 MCDisassembler::Fail) 242 return MCDisassembler::Fail; 243 Inst.addOperand(MCOperand::createImm(k)); 244 return MCDisassembler::Success; 245 } 246 247 static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, 248 uint64_t Address, 249 const MCDisassembler *Decoder) { 250 unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; 251 unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; 252 if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == 253 MCDisassembler::Fail) 254 return MCDisassembler::Fail; 255 if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == 256 MCDisassembler::Fail) 257 return MCDisassembler::Fail; 258 return MCDisassembler::Success; 259 } 260 261 static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address, 262 const MCDisassembler *Decoder) { 263 // As in the EncoderMethod `AVRMCCodeEmitter::encodeMemri`, the memory 264 // address is encoded into 7-bit, in which bits 0-5 are the immediate offset, 265 // and the bit-6 is the pointer register bit (Z=0, Y=1). 266 if (Insn > 127) 267 return MCDisassembler::Fail; 268 269 // Append the base register operand. 270 Inst.addOperand( 271 MCOperand::createReg((Insn & 0x40) ? AVR::R29R28 : AVR::R31R30)); 272 // Append the immediate offset operand. 273 Inst.addOperand(MCOperand::createImm(Insn & 0x3f)); 274 275 return MCDisassembler::Success; 276 } 277 278 static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address, 279 const MCDisassembler *Decoder) { 280 // Decode the opcode. 281 switch (Insn & 0xf000) { 282 case 0xc000: 283 Inst.setOpcode(AVR::RJMPk); 284 break; 285 case 0xd000: 286 Inst.setOpcode(AVR::RCALLk); 287 break; 288 default: // Unknown relative branch instruction. 289 return MCDisassembler::Fail; 290 } 291 // Decode the relative offset. 292 int16_t Offset = ((int16_t)((Insn & 0xfff) << 4)) >> 3; 293 Inst.addOperand(MCOperand::createImm(Offset)); 294 return MCDisassembler::Success; 295 } 296 297 static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn, 298 uint64_t Address, 299 const MCDisassembler *Decoder) { 300 // These 8 instructions are not defined as aliases of BRBS/BRBC. 301 DenseMap<unsigned, unsigned> brInsts = { 302 {0x000, AVR::BRLOk}, {0x400, AVR::BRSHk}, {0x001, AVR::BREQk}, 303 {0x401, AVR::BRNEk}, {0x002, AVR::BRMIk}, {0x402, AVR::BRPLk}, 304 {0x004, AVR::BRLTk}, {0x404, AVR::BRGEk}}; 305 306 // Get the relative offset. 307 int16_t Offset = ((int16_t)((Insn & 0x3f8) << 6)) >> 8; 308 309 // Search the instruction pattern. 310 auto NotAlias = [&Insn](const std::pair<unsigned, unsigned> &I) { 311 return (Insn & 0x407) != I.first; 312 }; 313 llvm::partition(brInsts, NotAlias); 314 auto It = llvm::partition_point(brInsts, NotAlias); 315 316 // Decode the instruction. 317 if (It != brInsts.end()) { 318 // This instruction is not an alias of BRBC/BRBS. 319 Inst.setOpcode(It->second); 320 Inst.addOperand(MCOperand::createImm(Offset)); 321 } else { 322 // Fall back to an ordinary BRBS/BRBC. 323 Inst.setOpcode(Insn & 0x400 ? AVR::BRBCsk : AVR::BRBSsk); 324 Inst.addOperand(MCOperand::createImm(Insn & 7)); 325 Inst.addOperand(MCOperand::createImm(Offset)); 326 } 327 328 return MCDisassembler::Success; 329 } 330 331 static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, 332 uint64_t Address, 333 const MCDisassembler *Decoder) { 334 // Get the register will be loaded or stored. 335 unsigned RegVal = GPRDecoderTable[(Insn >> 4) & 0x1f]; 336 337 // Decode LDD/STD with offset less than 8. 338 if ((Insn & 0xf000) == 0x8000) { 339 unsigned RegBase = (Insn & 0x8) ? AVR::R29R28 : AVR::R31R30; 340 unsigned Offset = Insn & 7; // We need not consider offset > 7. 341 if ((Insn & 0x200) == 0) { // Decode LDD. 342 Inst.setOpcode(AVR::LDDRdPtrQ); 343 Inst.addOperand(MCOperand::createReg(RegVal)); 344 Inst.addOperand(MCOperand::createReg(RegBase)); 345 Inst.addOperand(MCOperand::createImm(Offset)); 346 } else { // Decode STD. 347 Inst.setOpcode(AVR::STDPtrQRr); 348 Inst.addOperand(MCOperand::createReg(RegBase)); 349 Inst.addOperand(MCOperand::createImm(Offset)); 350 Inst.addOperand(MCOperand::createReg(RegVal)); 351 } 352 return MCDisassembler::Success; 353 } 354 355 // Decode the following 14 instructions. Bit 9 indicates load(0) or store(1), 356 // bits 8~4 indicate the value register, bits 3-2 indicate the base address 357 // register (11-X, 10-Y, 00-Z), bits 1~0 indicate the mode (00-basic, 358 // 01-postinc, 10-predec). 359 // ST X, Rr : 1001 001r rrrr 1100 360 // ST X+, Rr : 1001 001r rrrr 1101 361 // ST -X, Rr : 1001 001r rrrr 1110 362 // ST Y+, Rr : 1001 001r rrrr 1001 363 // ST -Y, Rr : 1001 001r rrrr 1010 364 // ST Z+, Rr : 1001 001r rrrr 0001 365 // ST -Z, Rr : 1001 001r rrrr 0010 366 // LD Rd, X : 1001 000d dddd 1100 367 // LD Rd, X+ : 1001 000d dddd 1101 368 // LD Rd, -X : 1001 000d dddd 1110 369 // LD Rd, Y+ : 1001 000d dddd 1001 370 // LD Rd, -Y : 1001 000d dddd 1010 371 // LD Rd, Z+ : 1001 000d dddd 0001 372 // LD Rd, -Z : 1001 000d dddd 0010 373 if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) 374 return MCDisassembler::Fail; 375 376 // Get the base address register. 377 unsigned RegBase; 378 switch (Insn & 0xc) { 379 case 0xc: 380 RegBase = AVR::R27R26; 381 break; 382 case 0x8: 383 RegBase = AVR::R29R28; 384 break; 385 case 0x0: 386 RegBase = AVR::R31R30; 387 break; 388 default: 389 return MCDisassembler::Fail; 390 } 391 392 // Set the opcode. 393 switch (Insn & 0x203) { 394 case 0x200: 395 Inst.setOpcode(AVR::STPtrRr); 396 Inst.addOperand(MCOperand::createReg(RegBase)); 397 Inst.addOperand(MCOperand::createReg(RegVal)); 398 return MCDisassembler::Success; 399 case 0x201: 400 Inst.setOpcode(AVR::STPtrPiRr); 401 break; 402 case 0x202: 403 Inst.setOpcode(AVR::STPtrPdRr); 404 break; 405 case 0: 406 Inst.setOpcode(AVR::LDRdPtr); 407 Inst.addOperand(MCOperand::createReg(RegVal)); 408 Inst.addOperand(MCOperand::createReg(RegBase)); 409 return MCDisassembler::Success; 410 case 1: 411 Inst.setOpcode(AVR::LDRdPtrPi); 412 break; 413 case 2: 414 Inst.setOpcode(AVR::LDRdPtrPd); 415 break; 416 default: 417 return MCDisassembler::Fail; 418 } 419 420 // Build postinc/predec machine instructions. 421 if ((Insn & 0x200) == 0) { // This is a load instruction. 422 Inst.addOperand(MCOperand::createReg(RegVal)); 423 Inst.addOperand(MCOperand::createReg(RegBase)); 424 Inst.addOperand(MCOperand::createReg(RegBase)); 425 } else { // This is a store instruction. 426 Inst.addOperand(MCOperand::createReg(RegBase)); 427 Inst.addOperand(MCOperand::createReg(RegBase)); 428 Inst.addOperand(MCOperand::createReg(RegVal)); 429 // STPtrPiRr and STPtrPdRr have an extra immediate operand. 430 Inst.addOperand(MCOperand::createImm(1)); 431 } 432 433 return MCDisassembler::Success; 434 } 435 436 static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 437 uint64_t &Size, uint32_t &Insn) { 438 if (Bytes.size() < 2) { 439 Size = 0; 440 return MCDisassembler::Fail; 441 } 442 443 Size = 2; 444 Insn = (Bytes[0] << 0) | (Bytes[1] << 8); 445 446 return MCDisassembler::Success; 447 } 448 449 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 450 uint64_t &Size, uint32_t &Insn) { 451 452 if (Bytes.size() < 4) { 453 Size = 0; 454 return MCDisassembler::Fail; 455 } 456 457 Size = 4; 458 Insn = 459 (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); 460 461 return MCDisassembler::Success; 462 } 463 464 static const uint8_t *getDecoderTable(uint64_t Size) { 465 466 switch (Size) { 467 case 2: 468 return DecoderTable16; 469 case 4: 470 return DecoderTable32; 471 default: 472 llvm_unreachable("instructions must be 16 or 32-bits"); 473 } 474 } 475 476 DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 477 ArrayRef<uint8_t> Bytes, 478 uint64_t Address, 479 raw_ostream &CStream) const { 480 uint32_t Insn; 481 482 DecodeStatus Result; 483 484 // Try decode a 16-bit instruction. 485 { 486 Result = readInstruction16(Bytes, Address, Size, Insn); 487 488 if (Result == MCDisassembler::Fail) 489 return MCDisassembler::Fail; 490 491 // Try to decode AVRTiny instructions. 492 if (STI.hasFeature(AVR::FeatureTinyEncoding)) { 493 Result = decodeInstruction(DecoderTableAVRTiny16, Instr, Insn, Address, 494 this, STI); 495 if (Result != MCDisassembler::Fail) 496 return Result; 497 } 498 499 // Try to auto-decode a 16-bit instruction. 500 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 501 this, STI); 502 if (Result != MCDisassembler::Fail) 503 return Result; 504 505 // Try to decode to a load/store instruction. ST/LD need a specified 506 // DecoderMethod, as they already have a specified PostEncoderMethod. 507 Result = decodeLoadStore(Instr, Insn, Address, this); 508 if (Result != MCDisassembler::Fail) 509 return Result; 510 } 511 512 // Try decode a 32-bit instruction. 513 { 514 Result = readInstruction32(Bytes, Address, Size, Insn); 515 516 if (Result == MCDisassembler::Fail) 517 return MCDisassembler::Fail; 518 519 Result = decodeInstruction(getDecoderTable(Size), Instr, Insn, Address, 520 this, STI); 521 522 if (Result != MCDisassembler::Fail) { 523 return Result; 524 } 525 526 return MCDisassembler::Fail; 527 } 528 } 529 530 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, 531 const MCDisassembler *Decoder); 532