[llvm] [AVR] No cli for SPWRITE on XMEGA (PR #147210)
Tom Vijlbrief via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 8 02:33:41 PDT 2025
https://github.com/tomtor updated https://github.com/llvm/llvm-project/pull/147210
>From a0088b4bd3ccd93c0eeae9cbfdf355dea825d22c Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 6 Jul 2025 21:34:20 +0200
Subject: [PATCH 1/6] [AVR] No cli for SPWRITE on XMEGA
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 25 ++++++++++++++++----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 440d852fa4bc8..1c00010c76ff8 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2531,27 +2531,42 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
unsigned Flags = MI.getFlags();
TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
- buildMI(MBB, MBBI, AVR::INRdA)
+ // From the XMEGA series manual:
+ // To prevent corruption when updating the stack pointer from software,
+ // a write to SPL will automatically disable interrupts
+ // for up to four instructions or until the next I/O memory write.
+ if (STI.getELFArch() >= 102) { // An XMEGA device
+ buildMI(MBB, MBBI, AVR::OUTARr)
+ .addImm(0x3d)
+ .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
+ buildMI(MBB, MBBI, AVR::OUTARr)
+ .addImm(0x3e)
+ .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
+ } else { // Disable interrupts for older devices (3 extra instructions)
+ buildMI(MBB, MBBI, AVR::INRdA)
.addReg(STI.getTmpRegister(), RegState::Define)
.addImm(STI.getIORegSREG())
.setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
+ buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::OUTARr)
+ buildMI(MBB, MBBI, AVR::OUTARr)
.addImm(0x3e)
.addReg(SrcHiReg, getKillRegState(SrcIsKill))
.setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::OUTARr)
+ buildMI(MBB, MBBI, AVR::OUTARr)
.addImm(STI.getIORegSREG())
.addReg(STI.getTmpRegister(), RegState::Kill)
.setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::OUTARr)
+ buildMI(MBB, MBBI, AVR::OUTARr)
.addImm(0x3d)
.addReg(SrcLoReg, getKillRegState(SrcIsKill))
.setMIFlags(Flags);
+ }
MI.eraseFromParent();
return true;
>From 065e8a3ff79776939f2af815bb1b2ca111312455 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Sun, 6 Jul 2025 21:56:08 +0200
Subject: [PATCH 2/6] formatting
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 40 +++++++++++---------
1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 1c00010c76ff8..23a50945bed88 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2536,36 +2536,40 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
// a write to SPL will automatically disable interrupts
// for up to four instructions or until the next I/O memory write.
if (STI.getELFArch() >= 102) { // An XMEGA device
+
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3d)
- .addReg(SrcLoReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ .addImm(0x3d)
+ .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
+
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3e)
- .addReg(SrcHiReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ .addImm(0x3e)
+ .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
+
} else { // Disable interrupts for older devices (3 extra instructions)
+
buildMI(MBB, MBBI, AVR::INRdA)
- .addReg(STI.getTmpRegister(), RegState::Define)
- .addImm(STI.getIORegSREG())
- .setMIFlags(Flags);
+ .addReg(STI.getTmpRegister(), RegState::Define)
+ .addImm(STI.getIORegSREG())
+ .setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3e)
- .addReg(SrcHiReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ .addImm(0x3e)
+ .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(STI.getIORegSREG())
- .addReg(STI.getTmpRegister(), RegState::Kill)
- .setMIFlags(Flags);
+ .addImm(STI.getIORegSREG())
+ .addReg(STI.getTmpRegister(), RegState::Kill)
+ .setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3d)
- .addReg(SrcLoReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ .addImm(0x3d)
+ .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
}
MI.eraseFromParent();
>From 24afcd7c514fa153f9fe64e1f55c48e3ede49407 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 10:42:53 +0200
Subject: [PATCH 3/6] reorder
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 35 ++++++++------------
1 file changed, 13 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 23a50945bed88..817684e9ee7df 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2535,42 +2535,33 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
// To prevent corruption when updating the stack pointer from software,
// a write to SPL will automatically disable interrupts
// for up to four instructions or until the next I/O memory write.
- if (STI.getELFArch() >= 102) { // An XMEGA device
-
- buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3d)
- .addReg(SrcLoReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
-
- buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3e)
- .addReg(SrcHiReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
-
- } else { // Disable interrupts for older devices (3 extra instructions)
+ //
+ // For old devices disable interrupts (3 extra instructions)
+ if (STI.getELFArch() < 102) { // Not an XMEGA device
buildMI(MBB, MBBI, AVR::INRdA)
.addReg(STI.getTmpRegister(), RegState::Define)
.addImm(STI.getIORegSREG())
.setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
+ }
- buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3e)
- .addReg(SrcHiReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ buildMI(MBB, MBBI, AVR::OUTARr)
+ .addImm(0x3d)
+ .addReg(SrcLoReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
+ if (STI.getELFArch() < 102) // Not an XMEGA device
buildMI(MBB, MBBI, AVR::OUTARr)
.addImm(STI.getIORegSREG())
.addReg(STI.getTmpRegister(), RegState::Kill)
.setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3d)
- .addReg(SrcLoReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
- }
+ buildMI(MBB, MBBI, AVR::OUTARr)
+ .addImm(0x3e)
+ .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
MI.eraseFromParent();
return true;
>From f80f924bf212e3938f2f552aedbbe3532472a6c9 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:04:00 +0200
Subject: [PATCH 4/6] no constants for SP location
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 817684e9ee7df..32cb19962cf23 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2548,7 +2548,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
}
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3d)
+ .addImm(STI.getIORegSPL())
.addReg(SrcLoReg, getKillRegState(SrcIsKill))
.setMIFlags(Flags);
@@ -2559,7 +2559,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
.setMIFlags(Flags);
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(0x3e)
+ .addImm(STI.getIORegSPH())
.addReg(SrcHiReg, getKillRegState(SrcIsKill))
.setMIFlags(Flags);
>From 2e7629e65a1333598c63a8cd8a0b753a1342dd42 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:27:53 +0200
Subject: [PATCH 5/6] Test and optimize for SPL only device
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 32cb19962cf23..eb0ebfa8634b7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,7 +2538,7 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
//
// For old devices disable interrupts (3 extra instructions)
- if (STI.getELFArch() < 102) { // Not an XMEGA device
+ if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
buildMI(MBB, MBBI, AVR::INRdA)
.addReg(STI.getTmpRegister(), RegState::Define)
.addImm(STI.getIORegSREG())
@@ -2558,7 +2558,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
.addReg(STI.getTmpRegister(), RegState::Kill)
.setMIFlags(Flags);
- buildMI(MBB, MBBI, AVR::OUTARr)
+ if (STI.getIORegSPH() >= 0)
+ buildMI(MBB, MBBI, AVR::OUTARr)
.addImm(STI.getIORegSPH())
.addReg(SrcHiReg, getKillRegState(SrcIsKill))
.setMIFlags(Flags);
>From 28b238abb31eda84a3f8892d1d5e0f78cb128d79 Mon Sep 17 00:00:00 2001
From: Tom Vijlbrief <tvijlbrief at gmail.com>
Date: Tue, 8 Jul 2025 11:33:25 +0200
Subject: [PATCH 6/6] Formatting for SPL only test
---
llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index eb0ebfa8634b7..79313b147d6e7 100644
--- a/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -2538,7 +2538,8 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
//
// For old devices disable interrupts (3 extra instructions)
- if (STI.getELFArch() < 102 && STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
+ if (STI.getELFArch() < 102 &&
+ STI.getIORegSPH() >= 0) { // Not an XMEGA device and not just SPL
buildMI(MBB, MBBI, AVR::INRdA)
.addReg(STI.getTmpRegister(), RegState::Define)
.addImm(STI.getIORegSREG())
@@ -2560,9 +2561,9 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
if (STI.getIORegSPH() >= 0)
buildMI(MBB, MBBI, AVR::OUTARr)
- .addImm(STI.getIORegSPH())
- .addReg(SrcHiReg, getKillRegState(SrcIsKill))
- .setMIFlags(Flags);
+ .addImm(STI.getIORegSPH())
+ .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+ .setMIFlags(Flags);
MI.eraseFromParent();
return true;
More information about the llvm-commits
mailing list