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

Tom Vijlbrief via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 30 06:32:20 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/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 <tvijlbrief at gmail.com>
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 <tvijlbrief at gmail.com>
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;
     }
   }
 



More information about the llvm-commits mailing list