[llvm] [AVR] No cli for SPWRITE on XMEGA (PR #147210)

Tom Vijlbrief via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 7 00:48:43 PDT 2025


================
@@ -2531,27 +2531,46 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
   unsigned Flags = MI.getFlags();
   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
 
-  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(STI.getIORegSREG())
-      .addReg(STI.getTmpRegister(), RegState::Kill)
-      .setMIFlags(Flags);
-
-  buildMI(MBB, MBBI, AVR::OUTARr)
-      .addImm(0x3d)
-      .addReg(SrcLoReg, getKillRegState(SrcIsKill))
-      .setMIFlags(Flags);
+  // 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::OUTARr)
+        .addImm(0x3e)
+        .addReg(SrcHiReg, getKillRegState(SrcIsKill))
+        .setMIFlags(Flags);
+
+    buildMI(MBB, MBBI, AVR::OUTARr)
----------------
tomtor wrote:

Ah, from SEI in the manual:

Sets the Global Interrupt Enable (I) bit in SREG (Status Register). The instruction following SEI will be executed
before any pending interrupts.

https://github.com/llvm/llvm-project/pull/147210


More information about the llvm-commits mailing list