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