Skip to content

Commit 93a3b59

Browse files
committed
[AVR] Generalize the previous interrupt bugfix to signal handlers too
1 parent cc42863 commit 93a3b59

File tree

5 files changed

+34
-13
lines changed

5 files changed

+34
-13
lines changed

llvm/lib/Target/AVR/AVRFrameLowering.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
6161
bool HasFP = hasFP(MF);
6262

6363
// Interrupt handlers re-enable interrupts in function entry.
64-
if (AFI->isInterruptHandler() && CallConv != CallingConv::AVR_SIGNAL) {
64+
if (AFI->isInterruptHandler()) {
6565
BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs))
6666
.addImm(0x07)
6767
.setMIFlag(MachineInstr::FrameSetup);
@@ -76,7 +76,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
7676

7777
// Emit special prologue code to save R1, R0 and SREG in interrupt/signal
7878
// handlers before saving any other registers.
79-
if (AFI->isInterruptHandler()) {
79+
if (AFI->isInterruptOrSignalHandler()) {
8080
BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
8181
.addReg(AVR::R1R0, RegState::Kill)
8282
.setMIFlag(MachineInstr::FrameSetup);
@@ -146,7 +146,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
146146

147147
// Early exit if the frame pointer is not needed in this function except for
148148
// signal/interrupt handlers where special code generation is required.
149-
if (!hasFP(MF) && !AFI->isInterruptHandler()) {
149+
if (!hasFP(MF) && !AFI->isInterruptOrSignalHandler()) {
150150
return;
151151
}
152152

@@ -162,7 +162,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
162162

163163
// Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
164164
// handlers at the very end of the function, just before reti.
165-
if (AFI->isInterruptHandler()) {
165+
if (AFI->isInterruptOrSignalHandler()) {
166166
BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0);
167167
BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
168168
.addImm(0x3f)

llvm/lib/Target/AVR/AVRISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
14181418
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
14191419

14201420
unsigned RetOpc =
1421-
AFI->isInterruptHandler()
1421+
AFI->isInterruptOrSignalHandler()
14221422
? AVRISD::RETI_FLAG
14231423
: AVRISD::RET_FLAG;
14241424

llvm/lib/Target/AVR/AVRMachineFunctionInfo.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
3434
/// Whether or not the function is an interrupt handler.
3535
bool IsInterruptHandler;
3636

37+
/// Whether or not the function is an non-blocking interrupt handler.
38+
bool IsSignalHandler;
39+
3740
/// Size of the callee-saved register portion of the
3841
/// stack frame in bytes.
3942
unsigned CalleeSavedFrameSize;
@@ -44,18 +47,16 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
4447
public:
4548
AVRMachineFunctionInfo()
4649
: HasSpills(false), HasAllocas(false), HasStackArgs(false),
47-
IsInterruptHandler(false), CalleeSavedFrameSize(0),
48-
VarArgsFrameIndex(0) {}
50+
IsInterruptHandler(false), IsSignalHandler(false),
51+
CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {}
4952

5053
explicit AVRMachineFunctionInfo(MachineFunction &MF)
5154
: HasSpills(false), HasAllocas(false), HasStackArgs(false),
5255
CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {
5356
unsigned CallConv = MF.getFunction().getCallingConv();
5457

55-
this->IsInterruptHandler =
56-
CallConv == CallingConv::AVR_INTR ||
57-
CallConv == CallingConv::AVR_SIGNAL ||
58-
MF.getFunction().hasFnAttribute("interrupt");
58+
this->IsInterruptHandler = CallConv == CallingConv::AVR_INTR || MF.getFunction().hasFnAttribute("interrupt");
59+
this->IsSignalHandler = CallConv == CallingConv::AVR_SIGNAL || MF.getFunction().hasFnAttribute("signal");
5960
}
6061

6162
bool getHasSpills() const { return HasSpills; }
@@ -67,7 +68,11 @@ class AVRMachineFunctionInfo : public MachineFunctionInfo {
6768
bool getHasStackArgs() const { return HasStackArgs; }
6869
void setHasStackArgs(bool B) { HasStackArgs = B; }
6970

71+
/// Checks if the function is some form of interrupt service routine.
72+
bool isInterruptOrSignalHandler() const { return isInterruptHandler() || isSignalHandler(); }
73+
7074
bool isInterruptHandler() const { return IsInterruptHandler; }
75+
bool isSignalHandler() const { return IsSignalHandler; }
7176

7277
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
7378
void setCalleeSavedFrameSize(unsigned Bytes) { CalleeSavedFrameSize = Bytes; }

llvm/lib/Target/AVR/AVRRegisterInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const uint16_t *
3737
AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
3838
const AVRMachineFunctionInfo *AFI = MF->getInfo<AVRMachineFunctionInfo>();
3939

40-
return AFI->isInterruptHandler()
40+
return AFI->isInterruptOrSignalHandler()
4141
? CSR_Interrupts_SaveList
4242
: CSR_Normal_SaveList;
4343
}
@@ -47,7 +47,7 @@ AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
4747
CallingConv::ID CC) const {
4848
const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
4949

50-
return AFI->isInterruptHandler()
50+
return AFI->isInterruptOrSignalHandler()
5151
? CSR_Interrupts_RegMask
5252
: CSR_Normal_RegMask;
5353
}

llvm/test/CodeGen/AVR/interrupts.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,21 @@ define avr_signalcc void @signal_handler() {
4848
ret void
4949
}
5050

51+
define void @signal_handler_via_attribute() #1 {
52+
; CHECK-LABEL: signal_handler_via_attribute:
53+
; CHECK-NOT: sei
54+
; CHECK: push r0
55+
; CHECK-NEXT: push r1
56+
; CHECK-NEXT: in r0, 63
57+
; CHECK-NEXT: push r0
58+
; CHECK: clr r0
59+
; CHECK: pop r0
60+
; CHECK-NEXT: out 63, r0
61+
; CHECK-NEXT: pop r1
62+
; CHECK-NEXT: pop r0
63+
; CHECK-NEXT: reti
64+
ret void
65+
}
66+
5167
attributes #0 = { "interrupt" }
5268
attributes #1 = { "signal" }

0 commit comments

Comments
 (0)