[llvm] [AVR] Add AVR MOVW/ADIW/SUBIW disassembly (PR #146360)

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


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

>From fcb60b224ff92d17a5d413fae6a4aca79f86b547 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 15:12:51 +0200
Subject: [PATCH 1/4] [AVR] Add MOVW 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..dd7d6b0ab3389 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -328,6 +328,22 @@ static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeMoveWord(MCInst &Inst, unsigned Insn,
+                                   uint64_t Address,
+                                   const MCDisassembler *Decoder) {
+  // Get the registers
+  unsigned RegValD = GPRDecoderTable[2 * ((Insn >> 4) & 0xf)];
+  unsigned RegValR = GPRDecoderTable[2 * (Insn & 0xf)];
+
+  if ((Insn & 0xff00) == 0x0100) {
+    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 +518,11 @@ 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 load/store instruction. ST/LD need a specified
     // DecoderMethod, as they already have a specified PostEncoderMethod.
     Result = decodeLoadStore(Instr, Insn, Address, this);

>From 2f48e117a11812b800181df3e65c0686b2dc7a85 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 15:51:51 +0200
Subject: [PATCH 2/4] [AVR] Add ADIW 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 dd7d6b0ab3389..1bf68daeef192 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -328,6 +328,22 @@ static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeAddWordImm(MCInst &Inst, unsigned Insn,
+                                     uint64_t Address,
+                                     const MCDisassembler *Decoder) {
+  // Get the register
+  unsigned RegVal = GPRDecoderTable[24 + 2 * ((Insn >> 4) & 0x3)];
+
+  if ((Insn & 0xff00) == 0x9600) {
+    Inst.setOpcode(AVR::ADIWRdK);
+    Inst.addOperand(MCOperand::createReg(RegVal));
+    Inst.addOperand(
+        MCOperand::createImm(((Insn & 0x00C0) >> 2) | (Insn & 0xF)));
+    return MCDisassembler::Success;
+  }
+  return MCDisassembler::Fail;
+}
+
 static DecodeStatus decodeMoveWord(MCInst &Inst, unsigned Insn,
                                    uint64_t Address,
                                    const MCDisassembler *Decoder) {
@@ -522,6 +538,11 @@ DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
     Result = decodeMoveWord(Instr, Insn, Address, this);
     if (Result != MCDisassembler::Fail)
       return Result;
+    
+    // Try to decode to a ADIW instruction
+    Result = decodeAddWordImm(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.

>From b9eeb0c34ca5e1631c1136417aacab0ec9dd6569 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 16:29:22 +0200
Subject: [PATCH 3/4] [AVR] Add SUBIW disassembly

---
 llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index 1bf68daeef192..5af0fa78929e8 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -328,14 +328,14 @@ static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
   return MCDisassembler::Success;
 }
 
-static DecodeStatus decodeAddWordImm(MCInst &Inst, unsigned Insn,
-                                     uint64_t Address,
-                                     const MCDisassembler *Decoder) {
+static DecodeStatus decodeAddSubWordImm(MCInst &Inst, unsigned Insn,
+                                        uint64_t Address,
+                                        const MCDisassembler *Decoder) {
   // Get the register
   unsigned RegVal = GPRDecoderTable[24 + 2 * ((Insn >> 4) & 0x3)];
 
-  if ((Insn & 0xff00) == 0x9600) {
-    Inst.setOpcode(AVR::ADIWRdK);
+  if ((Insn & 0xfe00) == 0x9600) {
+    Inst.setOpcode((Insn & 0xff00) == 0x9600 ? AVR::ADIWRdK : AVR::SUBIWRdK);
     Inst.addOperand(MCOperand::createReg(RegVal));
     Inst.addOperand(
         MCOperand::createImm(((Insn & 0x00C0) >> 2) | (Insn & 0xF)));
@@ -540,7 +540,7 @@ DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
       return Result;
     
     // Try to decode to a ADIW instruction
-    Result = decodeAddWordImm(Instr, Insn, Address, this);
+    Result = decodeAddSubWordImm(Instr, Insn, Address, this);
     if (Result != MCDisassembler::Fail)
       return Result;
 

>From 9e26c524a40ee39f6a5c3451c559a72387b556a2 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Mon, 30 Jun 2025 17:02:32 +0200
Subject: [PATCH 4/4] fix formatting

---
 llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index 5af0fa78929e8..dfa3724d0081b 100644
--- a/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -337,8 +337,8 @@ static DecodeStatus decodeAddSubWordImm(MCInst &Inst, unsigned Insn,
   if ((Insn & 0xfe00) == 0x9600) {
     Inst.setOpcode((Insn & 0xff00) == 0x9600 ? AVR::ADIWRdK : AVR::SUBIWRdK);
     Inst.addOperand(MCOperand::createReg(RegVal));
-    Inst.addOperand(
-        MCOperand::createImm(((Insn & 0x00C0) >> 2) | (Insn & 0xF)));
+    unsigned imm = ((Insn & 0x00C0) >> 2) | (Insn & 0xF);
+    Inst.addOperand(MCOperand::createImm(imm));
     return MCDisassembler::Success;
   }
   return MCDisassembler::Fail;
@@ -538,8 +538,8 @@ DecodeStatus AVRDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
     Result = decodeMoveWord(Instr, Insn, Address, this);
     if (Result != MCDisassembler::Fail)
       return Result;
-    
-    // Try to decode to a ADIW instruction
+
+    // Try to decode to a ADIW /SBIW instruction
     Result = decodeAddSubWordImm(Instr, Insn, Address, this);
     if (Result != MCDisassembler::Fail)
       return Result;



More information about the llvm-commits mailing list