[llvm] [AVR] Add AVR MOVW/ADIW/SUBIW disassembly (PR #146360)
Tom Vijlbrief via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 30 07:36:36 PDT 2025
https://github.com/tomtor created https://github.com/llvm/llvm-project/pull/146360
Fix `<unknown>` in `llvm-objdump -d` output
>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/3] [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/3] [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/3] [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;
More information about the llvm-commits
mailing list