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