diff options
Diffstat (limited to 'llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp | 159 |
1 files changed, 158 insertions, 1 deletions
diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 694aee818f7c..8e7251a74dfd 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -57,23 +57,180 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRDisassembler() { createAVRDisassembler); } +static const uint16_t GPRDecoderTable[] = { + AVR::R0, AVR::R1, AVR::R2, AVR::R3, + AVR::R4, AVR::R5, AVR::R6, AVR::R7, + AVR::R8, AVR::R9, AVR::R10, AVR::R11, + AVR::R12, AVR::R13, AVR::R14, AVR::R15, + AVR::R16, AVR::R17, AVR::R18, AVR::R19, + AVR::R20, AVR::R21, AVR::R22, AVR::R23, + AVR::R24, AVR::R25, AVR::R26, AVR::R27, + AVR::R28, AVR::R29, AVR::R30, AVR::R31, +}; + static DecodeStatus DecodeGPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + if (RegNo > 31) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); return MCDisassembler::Success; } static DecodeStatus DecodeLD8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + if (RegNo > 15) + return MCDisassembler::Fail; + + unsigned Register = GPRDecoderTable[RegNo+16]; + Inst.addOperand(MCOperand::createReg(Register)); return MCDisassembler::Success; } static DecodeStatus DecodePTRREGSRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { + // Note: this function must be defined but does not seem to be called. + assert(false && "unimplemented: PTRREGS register class"); return MCDisassembler::Success; } +static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); + #include "AVRGenDisassemblerTables.inc" +static DecodeStatus decodeFIOARr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = 0; + addr |= fieldFromInstruction(Insn, 0, 4); + addr |= fieldFromInstruction(Insn, 9, 2) << 4; + unsigned reg = fieldFromInstruction(Insn, 4, 5); + Inst.addOperand(MCOperand::createImm(addr)); + if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFIORdA(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = 0; + addr |= fieldFromInstruction(Insn, 0, 4); + addr |= fieldFromInstruction(Insn, 9, 2) << 4; + unsigned reg = fieldFromInstruction(Insn, 4, 5); + if (DecodeGPR8RegisterClass(Inst, reg, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(addr)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFIOBIT(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned addr = fieldFromInstruction(Insn, 3, 5); + unsigned b = fieldFromInstruction(Insn, 0, 3); + Inst.addOperand(MCOperand::createImm(addr)); + Inst.addOperand(MCOperand::createImm(b)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeCallTarget(MCInst &Inst, unsigned Field, + uint64_t Address, const void *Decoder) { + // Call targets need to be shifted left by one so this needs a custom + // decoder. + Inst.addOperand(MCOperand::createImm(Field << 1)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFRd(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 5); + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFLPMX(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + if (decodeFRd(Inst, Insn, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createReg(AVR::R31R30)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFFMULRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 3) + 16; + unsigned r = fieldFromInstruction(Insn, 0, 3) + 16; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFMOVWRdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned r = fieldFromInstruction(Insn, 4, 4) * 2; + unsigned d = fieldFromInstruction(Insn, 0, 4) * 2; + if (DecodeGPR8RegisterClass(Inst, r, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + +static DecodeStatus decodeFWRdK(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned d = fieldFromInstruction(Insn, 4, 2) * 2 + 24; // starts at r24:r25 + unsigned k = 0; + k |= fieldFromInstruction(Insn, 0, 4); + k |= fieldFromInstruction(Insn, 6, 2) << 4; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, d, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(k)); + return MCDisassembler::Success; +} + +static DecodeStatus decodeFMUL2RdRr(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + unsigned rd = fieldFromInstruction(Insn, 4, 4) + 16; + unsigned rr = fieldFromInstruction(Insn, 0, 4) + 16; + if (DecodeGPR8RegisterClass(Inst, rd, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + if (DecodeGPR8RegisterClass(Inst, rr, Address, Decoder) == MCDisassembler::Fail) + return MCDisassembler::Fail; + return MCDisassembler::Success; +} + static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn) { if (Bytes.size() < 2) { @@ -96,7 +253,7 @@ static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, } Size = 4; - Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | (Bytes[3] << 24); + Insn = (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8); return MCDisassembler::Success; } |