Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down