Bug 27859 - Bug in generation of interrupt function code for ARM processor
Summary: Bug in generation of interrupt function code for ARM processor
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.1.1
: P3 normal
Target Milestone: 4.3.4
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-01 13:01 UTC by Jurij Kotar
Modified: 2009-04-21 13:52 UTC (History)
2 users (show)

See Also:
Host: i386-redhat-linux
Target: arm-none-eabi
Build: i386-redhat-linux
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Patch to fix interrupt handling on entry/exit for ARM (324 bytes, patch)
2008-01-17 11:24 UTC, Francois Lorrain
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jurij Kotar 2006-06-01 13:01:52 UTC
The C compiler generates wrong assembler code for functions with  __attribute__ ((interrupt ("IRQ"))). Link register lr in interrupt function is decremented two times before it is loaded back to the program counter pc. It is decremented at the beginning of interrupt routime (sub     lr, lr, #4) and again at the end (subs    pc, lr, #4). It should be decremented only once. Such a bug was also reported previously (ID 16634, ID 25428). Here is the complete example:


PROGRAM bug.c:

void function( void )
{
        volatile unsigned int *a;

        a = (unsigned int *)2000;
        *a = 1;
        *a = 0;
}

void IRQ_Handler( void ) __attribute__ ((interrupt ("IRQ")));
void IRQ_Handler( void )
{
        volatile unsigned int s, *a;


        a = (unsigned int *)2500;
        s = *a;

        function();

}

COMPILATION OUTPUT:

arm-4.1.1-eabi-gcc -v -save-temps -Wall -c -O  -o bug.o bug.c
Using built-in specs.
Target: arm-none-eabi
Configured with: ./configure --target=arm-none-eabi --program-prefix=arm-4.1.1-eabi-
Thread model: single
gcc version 4.1.1
 /usr/local/packages/arm411/bin/../libexec/gcc/arm-none-eabi/4.1.1/cc1 -E -quiet -v -iprefix /usr/local/packages/arm411/bin/../lib/gcc/arm-none-eabi/4.1.1/ -D__USES_INITFINI__ bug.c -Wall -O -fpch-preprocess -o bug.i
ignoring nonexistent directory "/usr/local/packages/arm411/bin/../lib/gcc/arm-none-eabi/4.1.1/../../../../arm-none-eabi/sys-include"
ignoring nonexistent directory "/usr/local/lib/gcc/arm-none-eabi/4.1.1/include"
ignoring nonexistent directory "/usr/local/lib/../arm-none-eabi/sys-include"
ignoring nonexistent directory "/usr/local/lib/../arm-none-eabi/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/packages/arm411/bin/../lib/gcc/arm-none-eabi/4.1.1/include
 /usr/local/packages/arm411/bin/../lib/gcc/arm-none-eabi/4.1.1/../../../../arm-none-eabi/include
End of search list.
 /usr/local/packages/arm411/bin/../libexec/gcc/arm-none-eabi/4.1.1/cc1 -fpreprocessed bug.i -quiet -dumpbase bug.c -auxbase-strip bug.o -O -Wall -version -o bug.s
GNU C version 4.1.1 (arm-none-eabi)
        compiled by GNU C version 4.1.1 20060525 (Red Hat 4.1.1-1).
GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128878
Compiler executable checksum: 8b248e68ff58c0b76da33bbc4bade307
 /usr/local/packages/arm411/bin/../lib/gcc/arm-none-eabi/4.1.1/../../../../arm-none-eabi/bin/as -meabi=4 -o bug.o bug.s

ASSEMBLER OUTPUT:
        .file   "bug.c"
        .text
        .align  2
        .global function
        .type   function, %function
function:
        @ Function supports interworking.
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        @ lr needed for prologue
        mov     r3, #0
        mov     r2, #1
        str     r2, [r3, #2000]
        str     r3, [r3, #2000]
        bx      lr
        .size   function, .-function
        .align  2
        .global IRQ_Handler
        .type   IRQ_Handler, %function
IRQ_Handler:
        @ Interrupt Service Routine.
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 0, uses_anonymous_args = 0
        sub     lr, lr, #4
        stmfd   sp!, {r0, r1, r2, r3, ip, lr}
        sub     sp, sp, #8
        mov     r3, #0
        ldr     r3, [r3, #2500]
        str     r3, [sp, #4]
        bl      function
        add     sp, sp, #8
        ldmfd   sp!, {r0, r1, r2, r3, ip, lr}
        subs    pc, lr, #4
        .size   IRQ_Handler, .-IRQ_Handler
        .ident  "GCC: (GNU) 4.1.1"


Best regards,
Jurij Kotar
Comment 1 Francois Lorrain 2008-01-17 11:24:22 UTC
Created attachment 14957 [details]
Patch to fix interrupt handling on entry/exit for ARM

The arm backend already decrement the PC by 4 when entering an interrupt routine, so it does not need to have a specific handling for the return of the function, it can be treated as an exception return.
The attached patch fixes this

Regards

Francois
Comment 2 Ramana Radhakrishnan 2009-04-21 13:52:16 UTC
(In reply to comment #1)
> Created an attachment (id=14957) [edit]
> Patch to fix interrupt handling on entry/exit for ARM
> 
> The arm backend already decrement the PC by 4 when entering an interrupt
> routine, so it does not need to have a specific handling for the return of the
> function, it can be treated as an exception return.
> The attached patch fixes this
> 
> Regards
> 
> Francois
> 

This no longer appears on 4.3 , 4.4 or trunk . Hence closing this one out.