[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