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

Reply via email to