The stack pointer is erroneously adjusted in the prologue of an FIQ interrupt
handler, and not corrected before popping the pc in the epilogue. The same
error occurs with IRQ handlers if frame pointers are not omitted. I believe
the compiler is attempting to align the stack to an 8 byte boundary, and not
reversing the adjustment before popping.
The input
-------------
void foo(void);
__attribute((interrupt("FIQ"))) void fiq_handler()
{
foo();
}
The output
-------------
fiq_handler:
sub lr, lr, #4
stmfd sp!, {r0, r1, r2, r3, lr}
sub sp, sp, #4 ; <-- why is this here?
bl foo
ldmfd sp!, {r0, r1, r2, r3, pc}^ ; <-- this is now wrong
compile line:
---------------
$ arm-none-eabi-gcc -march=armv5 -save-temps -fomit-frame-pointer -S fiq_test.c
arm-none-eabi-gcc -v:
-------------------------
Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/opt/arm-eabi-toolchain/libexec/gcc/arm-none-eabi/4.5.0/lto-wrapper
Target: arm-none-eabi
Configured with: ../gcc-4.5.0/configure --target=arm-none-eabi
--prefix=/opt/arm-eabi-toolchain --enable-multilib --enable-languages=c,c++
--with-newlib --disable-shared --with-gnu-as --with-gnu-ld --with-fpu=vfp
--with-float=softfp --with-cpu=arm926ej-s --with-arch=armv5te
--with-system-zlib
Thread model: single
gcc version 4.5.0 (GCC)
pre-processed source:
--------------------------
# 1 "fiq_test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "fiq_test.c"
void foo(void);
__attribute((interrupt("FIQ"))) void fiq_handler()
{
foo();
}
--
Summary: interrupt handler stack pointer is wrong
Product: gcc
Version: 4.5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: ethan at evolution dot com
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: arm-none-eabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45540