From 5abd1ca812c06d36c9f8dc45633ab47a2b9acf2f Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Mon, 30 Jun 2025 13:03:50 +0200 Subject: [PATCH 1/3] [AVR] Add ELPM disassembly --- .../AVR/Disassembler/AVRDisassembler.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index c7a584868f4e6..4d0190854de40 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -370,9 +370,30 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, // LD Rd, -Y : 1001 000d dddd 1010 // LD Rd, Z+ : 1001 000d dddd 0001 // LD Rd, -Z : 1001 000d dddd 0010 + // + // and 3 ELPM instructions + // ELPM Rd,Z : 1001 000d dddd 0110 + // ELPM Rd,Z+: 1001 000d dddd 0111 + // ELPM R0,Z : 1001 0101 1101 1000 + if (Insn == 0x95d8) { + Inst.setOpcode(AVR::ELPM); + return MCDisassembler::Success; + } + if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) return MCDisassembler::Fail; + // ELPM Rd,Z(+) + if ((Insn & 0xfe00) == 0x9000) { + switch (Insn & 0xf) { + case 0x6: + case 0x7: + Inst.setOpcode((Insn & 0xf) == 6 ? AVR::ELPMRdZ : AVR::ELPMRdZPi); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; + } + } + // Get the base address register. unsigned RegBase; switch (Insn & 0xc) { From 373a0199eef91062ed73a5f53285c26d10b12c48 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Mon, 30 Jun 2025 14:07:48 +0200 Subject: [PATCH 2/3] [AVR] Add PUSH/POP disassembly --- .../AVR/Disassembler/AVRDisassembler.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 4d0190854de40..26537dfb3e4a5 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -383,17 +383,31 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) return MCDisassembler::Fail; - // ELPM Rd,Z(+) + // ELPM Rd,Z(+) and POP if ((Insn & 0xfe00) == 0x9000) { switch (Insn & 0xf) { + case 0xF: + Inst.setOpcode(AVR::POPRd); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; case 0x6: + Inst.setOpcode(AVR::ELPMRdZ); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; case 0x7: - Inst.setOpcode((Insn & 0xf) == 6 ? AVR::ELPMRdZ : AVR::ELPMRdZPi); + Inst.setOpcode(AVR::ELPMRdZPi); Inst.addOperand(MCOperand::createReg(RegVal)); return MCDisassembler::Success; } } + // PUSH + if ((Insn & 0xfe0f) == 0x920f) { + Inst.setOpcode(AVR::PUSHRr); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; + } + // Get the base address register. unsigned RegBase; switch (Insn & 0xc) { From 9a3a6d11bdbea61912b18ada57db25746624daa3 Mon Sep 17 00:00:00 2001 From: Tom Vijlbrief Date: Mon, 30 Jun 2025 15:32:05 +0200 Subject: [PATCH 3/3] [AVR] Add LPM disassembly --- .../AVR/Disassembler/AVRDisassembler.cpp | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp index 26537dfb3e4a5..c5006a4f28ce1 100644 --- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp +++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp @@ -371,10 +371,19 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, // LD Rd, Z+ : 1001 000d dddd 0001 // LD Rd, -Z : 1001 000d dddd 0010 // + // and 3 LPM instructions + // LPM Rd,Z : 1001 000d dddd 0100 + // LPM Rd,Z+: 1001 000d dddd 0101 + // LPM R0,Z : 1001 0101 1100 1000 + // // and 3 ELPM instructions // ELPM Rd,Z : 1001 000d dddd 0110 // ELPM Rd,Z+: 1001 000d dddd 0111 // ELPM R0,Z : 1001 0101 1101 1000 + if (Insn == 0x95c8) { + Inst.setOpcode(AVR::LPM); + return MCDisassembler::Success; + } if (Insn == 0x95d8) { Inst.setOpcode(AVR::ELPM); return MCDisassembler::Success; @@ -383,11 +392,15 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, if ((Insn & 0xfc00) != 0x9000 || (Insn & 0xf) == 0) return MCDisassembler::Fail; - // ELPM Rd,Z(+) and POP + // (E)LPM Rd,Z(+) and POP if ((Insn & 0xfe00) == 0x9000) { switch (Insn & 0xf) { - case 0xF: - Inst.setOpcode(AVR::POPRd); + case 0x4: + Inst.setOpcode(AVR::LPMRdZ); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; + case 0x5: + Inst.setOpcode(AVR::LPMRdZPi); Inst.addOperand(MCOperand::createReg(RegVal)); return MCDisassembler::Success; case 0x6: @@ -398,6 +411,10 @@ static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn, Inst.setOpcode(AVR::ELPMRdZPi); Inst.addOperand(MCOperand::createReg(RegVal)); return MCDisassembler::Success; + case 0xF: + Inst.setOpcode(AVR::POPRd); + Inst.addOperand(MCOperand::createReg(RegVal)); + return MCDisassembler::Success; } }