[llvm] [AVR] Add ELPM disassembly (PR #146333)

Tom Vijlbrief via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 30 05:08:14 PDT 2025


https://github.com/tomtor updated https://github.com/llvm/llvm-project/pull/146333

>From 5abd1ca812c06d36c9f8dc45633ab47a2b9acf2f Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 13:03:50 +0200
Subject: [PATCH 1/2] [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 <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 14:07:48 +0200
Subject: [PATCH 2/2] [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) {



More information about the llvm-commits mailing list