@@ -2531,27 +2531,47 @@ bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
2531
2531
unsigned Flags = MI.getFlags ();
2532
2532
TRI->splitReg (SrcReg, SrcLoReg, SrcHiReg);
2533
2533
2534
- buildMI (MBB, MBBI, AVR::INRdA)
2535
- .addReg (STI.getTmpRegister (), RegState::Define)
2536
- .addImm (STI.getIORegSREG ())
2537
- .setMIFlags (Flags);
2538
-
2539
- buildMI (MBB, MBBI, AVR::BCLRs).addImm (0x07 ).setMIFlags (Flags);
2540
-
2541
- buildMI (MBB, MBBI, AVR::OUTARr)
2542
- .addImm (0x3e )
2543
- .addReg (SrcHiReg, getKillRegState (SrcIsKill))
2544
- .setMIFlags (Flags);
2534
+ // From the XMEGA series manual:
2535
+ // To prevent corruption when updating the stack pointer from software,
2536
+ // a write to SPL will automatically disable interrupts
2537
+ // for up to four instructions or until the next I/O memory write.
2538
+ if (STI.getELFArch () >= 102 ) { // An XMEGA device
2539
+
2540
+ buildMI (MBB, MBBI, AVR::OUTARr)
2541
+ .addImm (STI.getIORegSPL ())
2542
+ .addReg (SrcLoReg, getKillRegState (SrcIsKill))
2543
+ .setMIFlags (Flags);
2544
+
2545
+ buildMI (MBB, MBBI, AVR::OUTARr)
2546
+ .addImm (STI.getIORegSPH ())
2547
+ .addReg (SrcHiReg, getKillRegState (SrcIsKill))
2548
+ .setMIFlags (Flags);
2549
+
2550
+ } else { // Disable interrupts for older devices (3 extra instructions)
2551
+
2552
+ buildMI (MBB, MBBI, AVR::INRdA)
2553
+ .addReg (STI.getTmpRegister (), RegState::Define)
2554
+ .addImm (STI.getIORegSREG ())
2555
+ .setMIFlags (Flags);
2556
+
2557
+ buildMI (MBB, MBBI, AVR::BCLRs).addImm (0x07 ).setMIFlags (Flags);
2558
+
2559
+ if (STI.getIORegSPH () != -1 )
2560
+ buildMI (MBB, MBBI, AVR::OUTARr)
2561
+ .addImm (STI.getIORegSPH ())
2562
+ .addReg (SrcHiReg, getKillRegState (SrcIsKill))
2563
+ .setMIFlags (Flags);
2545
2564
2546
- buildMI (MBB, MBBI, AVR::OUTARr)
2547
- .addImm (STI.getIORegSREG ())
2548
- .addReg (STI.getTmpRegister (), RegState::Kill)
2549
- .setMIFlags (Flags);
2565
+ buildMI (MBB, MBBI, AVR::OUTARr)
2566
+ .addImm (STI.getIORegSREG ())
2567
+ .addReg (STI.getTmpRegister (), RegState::Kill)
2568
+ .setMIFlags (Flags);
2550
2569
2551
- buildMI (MBB, MBBI, AVR::OUTARr)
2552
- .addImm (0x3d )
2553
- .addReg (SrcLoReg, getKillRegState (SrcIsKill))
2554
- .setMIFlags (Flags);
2570
+ buildMI (MBB, MBBI, AVR::OUTARr)
2571
+ .addImm (STI.getIORegSPL ())
2572
+ .addReg (SrcLoReg, getKillRegState (SrcIsKill))
2573
+ .setMIFlags (Flags);
2574
+ }
2555
2575
2556
2576
MI.eraseFromParent ();
2557
2577
return true ;
0 commit comments