diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..57b4ee819cbd3 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -328,6 +328,51 @@ static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn, return MCDisassembler::Success; } +static DecodeStatus decodeAddSubWordImm(MCInst &Inst, unsigned Insn, + uint64_t Address, + const MCDisassembler *Decoder) { + if ((Insn & 0xfe00) == 0x9600) { + // Get the register + unsigned RegVal; + switch ((Insn >> 4) & 0x3) { + case 0: + RegVal = AVR::R25R24; + break; + case 1: + RegVal = AVR::R27R26; + break; + case 2: + RegVal = AVR::R29R28; + break; + case 3: + RegVal = AVR::R31R30; + } + + Inst.setOpcode((Insn & 0xff00) == 0x9600 ? AVR::ADIWRdK : AVR::SUBIWRdK); + Inst.addOperand(MCOperand::createReg(RegVal)); + Inst.addOperand(MCOperand::createReg(RegVal)); + unsigned imm = ((Insn & 0x00C0) >> 2) | (Insn & 0xF); + Inst.addOperand(MCOperand::createImm(imm)); + return MCDisassembler::Success; + } + return MCDisassembler::Fail; +} + +static DecodeStatus decodeMoveWord(MCInst &Inst, unsigned Insn, + uint64_t Address, + const MCDisassembler *Decoder) { + if ((Insn & 0xff00) == 0x0100) { + // Get the registers + unsigned RegValD = GPRDecoderTable[2 * ((Insn >> 4) & 0xf)]; + unsigned RegValR = GPRDecoderTable[2 * (Insn & 0xf)]; + Inst.setOpcode(AVR::MOVWRdRr); + Inst.addOperand(MCOperand::createReg(RegValD)); + Inst.addOperand(MCOperand::createReg(RegValR)); + return MCDisassembler::Success; + } + return MCDisassembler::Fail; +} + static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder) { @@ -502,6 +547,16 @@ DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, if (Result != MCDisassembler::Fail) return Result; + // Try to decode to a MOVW instruction + Result = decodeMoveWord(Instr, Insn, Address, this); + if (Result != MCDisassembler::Fail) + return Result; + + // Try to decode to a ADIW /SBIW instruction + Result = decodeAddSubWordImm(Instr, Insn, Address, this); + if (Result != MCDisassembler::Fail) + return Result; + // Try to decode to a load/store instruction. ST/LD need a specified // DecoderMethod, as they already have a specified PostEncoderMethod. Result = decodeLoadStore(Instr, Insn, Address, this);