[llvm] 7b808b1 - [AVR] Generalize the previous interrupt bugfix to signal handlers too

Dylan McKay via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 30 23:34:34 PDT 2020


Author: Dylan McKay
Date: 2020-03-31T19:33:34+13:00
New Revision: 7b808b105f6aedc4066502b68b71cf205bafa582

URL: https://github.com/llvm/llvm-project/commit/7b808b105f6aedc4066502b68b71cf205bafa582
DIFF: https://github.com/llvm/llvm-project/commit/7b808b105f6aedc4066502b68b71cf205bafa582.diff

LOG: [AVR] Generalize the previous interrupt bugfix to signal handlers too

Added: 
    

Modified: 
    llvm/lib/Target/AVR/AVRFrameLowering.cpp
    llvm/lib/Target/AVR/AVRISelLowering.cpp
    llvm/lib/Target/AVR/AVRMachineFunctionInfo.h
    llvm/lib/Target/AVR/AVRRegisterInfo.cpp
    llvm/test/CodeGen/AVR/interrupts.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
index f327f9b68a81..27b987317123 100644
--- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
@@ -60,7 +60,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
   bool HasFP = hasFP(MF);
 
   // Interrupt handlers re-enable interrupts in function entry.
-  if (AFI->isInterruptHandler() && CallConv != CallingConv::AVR_SIGNAL) {
+  if (AFI->isInterruptHandler()) {
     BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs))
         .addImm(0x07)
         .setMIFlag(MachineInstr::FrameSetup);
@@ -75,7 +75,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
 
   // Emit special prologue code to save R1, R0 and SREG in interrupt/signal
   // handlers before saving any other registers.
-  if (AFI->isInterruptHandler()) {
+  if (AFI->isInterruptOrSignalHandler()) {
     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
         .addReg(AVR::R1R0, RegState::Kill)
         .setMIFlag(MachineInstr::FrameSetup);
@@ -145,7 +145,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
 
   // Early exit if the frame pointer is not needed in this function except for
   // signal/interrupt handlers where special code generation is required.
-  if (!hasFP(MF) && !AFI->isInterruptHandler()) {
+  if (!hasFP(MF) && !AFI->isInterruptOrSignalHandler()) {
     return;
   }
 
@@ -161,7 +161,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
 
   // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
   // handlers at the very end of the function, just before reti.
-  if (AFI->isInterruptHandler()) {
+  if (AFI->isInterruptOrSignalHandler()) {
     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0);
     BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
         .addImm(0x3f)

diff  --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 159a3ca19200..be8f8f75a21e 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -1432,7 +1432,7 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
 
   unsigned RetOpc =
-    AFI->isInterruptHandler()
+    AFI->isInterruptOrSignalHandler()
         ? AVRISD::RETI_FLAG
         : AVRISD::RET_FLAG;
 

diff  --git a/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h b/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h
index 5fa6bb513348..5432fac122ef 100644
--- a/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h
+++ b/llvm/lib/Target/AVR/AVRMachineFunctionInfo.h
@@ -34,6 +34,9 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
   /// Whether or not the function is an interrupt handler.
   bool IsInterruptHandler;
 
+  /// Whether or not the function is an non-blocking interrupt handler.
+  bool IsSignalHandler;
+
   /// Size of the callee-saved register portion of the
   /// stack frame in bytes.
   unsigned CalleeSavedFrameSize;
@@ -44,18 +47,16 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
 public:
   AVRMachineFunctionInfo()
       : HasSpills(false), HasAllocas(false), HasStackArgs(false),
-        IsInterruptHandler(false), CalleeSavedFrameSize(0),
-        VarArgsFrameIndex(0) {}
+        IsInterruptHandler(false), IsSignalHandler(false),
+        CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {}
 
   explicit AVRMachineFunctionInfo(MachineFunction &MF)
       : HasSpills(false), HasAllocas(false), HasStackArgs(false),
         CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {
     unsigned CallConv = MF.getFunction().getCallingConv();
 
-    this->IsInterruptHandler =
-      CallConv == CallingConv::AVR_INTR ||
-      CallConv == CallingConv::AVR_SIGNAL ||
-      MF.getFunction().hasFnAttribute("interrupt");
+    this->IsInterruptHandler = CallConv == CallingConv::AVR_INTR || MF.getFunction().hasFnAttribute("interrupt");
+    this->IsSignalHandler = CallConv == CallingConv::AVR_SIGNAL || MF.getFunction().hasFnAttribute("signal");
   }
 
   bool getHasSpills() const { return HasSpills; }
@@ -67,7 +68,11 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
   bool getHasStackArgs() const { return HasStackArgs; }
   void setHasStackArgs(bool B) { HasStackArgs = B; }
 
+  /// Checks if the function is some form of interrupt service routine.
+  bool isInterruptOrSignalHandler() const { return isInterruptHandler() || isSignalHandler(); }
+
   bool isInterruptHandler() const { return IsInterruptHandler; }
+  bool isSignalHandler() const { return IsSignalHandler; }
 
   unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
   void setCalleeSavedFrameSize(unsigned Bytes) { CalleeSavedFrameSize = Bytes; }

diff  --git a/llvm/lib/Target/AVR/AVRRegisterInfo.cpp b/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
index 6caa460eb6d3..2a4905ce2461 100644
--- a/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
+++ b/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
@@ -37,7 +37,7 @@ const uint16_t *
 AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
   const AVRMachineFunctionInfo *AFI = MF->getInfo<AVRMachineFunctionInfo>();
 
-  return AFI->isInterruptHandler()
+  return AFI->isInterruptOrSignalHandler()
               ? CSR_Interrupts_SaveList
               : CSR_Normal_SaveList;
 }
@@ -47,7 +47,7 @@ AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
                                       CallingConv::ID CC) const {
   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
 
-  return AFI->isInterruptHandler()
+  return AFI->isInterruptOrSignalHandler()
               ? CSR_Interrupts_RegMask
               : CSR_Normal_RegMask;
 }

diff  --git a/llvm/test/CodeGen/AVR/interrupts.ll b/llvm/test/CodeGen/AVR/interrupts.ll
index da8a5ce46f46..b402d867e12b 100644
--- a/llvm/test/CodeGen/AVR/interrupts.ll
+++ b/llvm/test/CodeGen/AVR/interrupts.ll
@@ -48,5 +48,21 @@ define avr_signalcc void @signal_handler() {
   ret void
 }
 
+define void @signal_handler_via_attribute() #1 {
+; CHECK-LABEL: signal_handler_via_attribute:
+; CHECK-NOT: sei
+; CHECK: push r0
+; CHECK-NEXT: push r1
+; CHECK-NEXT: in r0, 63
+; CHECK-NEXT: push r0
+; CHECK: clr r0
+; CHECK: pop r0
+; CHECK-NEXT: out 63, r0
+; CHECK-NEXT: pop r1
+; CHECK-NEXT: pop r0
+; CHECK-NEXT: reti
+  ret void
+}
+
 attributes #0 = { "interrupt" }
 attributes #1 = { "signal" }


        


More information about the llvm-commits mailing list