[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