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