>Number: 6039 >Category: target >Synopsis: ARM interrupt attribute generats wrong code >Confidential: no >Severity: critical >Priority: high >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Fri Mar 22 07:56:00 PST 2002 >Closed-Date: >Last-Modified: >Originator: Tobias Ringstrom >Release: gcc-3.0.4 >Organization: >Environment: Crosscompiler for arm-elf (cygwin and Linux host) >Description: Compile the following code with arm-elf-gcc -S tmp.c: void foo(void) __attribute__((__interrupt__)); void bar(void); void foo() { int a=0, b=0, c=a+b; bar(); } gives you the following: @ Generated by gcc 3.0.4 for ARM/elf .file "tmp.c" .text .align 2 .global foo .type foo,function foo: @ Interrupt Service Routine. @ args = 0, pretend = 0, frame = 12 @ frame_needed = 1, current_function_anonymous_args = 0 mov ip, sp stmfd sp!, {r2, r3, fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #12 mov r3, #0 str r3, [fp, #-16] str r3, [fp, #-20] ldr r2, [fp, #-16] ldr r3, [fp, #-20] add r3, r2, r3 str r3, [fp, #-24] bl bar ldmea fp, {r2, r3, fp, sp, lr} subs pc, lr, #4 .Lfe1: .size foo,.Lfe1-foo Major problem 1: The ip register is overwritten and not restored. Major problem 2: The local variables overlap the pushed registers. In this case variable a occupies the same space as the stored lr. Major problem 3: A function is called which has every right to alter r0 and r1, and still those registers are not saved/restored in the prologue/epilogue. Question: Why is the register pc stored? If this bug is not fixed for the next gcc-3.0.x, I strongly recommend that you disable the interrupt attribute since it is unusable in its current form. I have tried the later pre-3.1 CVS version as well, and the above bugs seem to be fixed there, but unfortunately there is another (actually much worse) showstopper there. I will generate ASM stubs for my ISRs for now, but it would be very nice to use the interrupt attribute in the future. /Tobias >How-To-Repeat: Compile the program in the Description above. Note that no optimization is neccessary. It may even hide the real problems. >Fix: >Release-Note: >Audit-Trail: >Unformatted:
Synopsis: ARM interrupt attribute generats wrong code State-Changed-From-To: open->analyzed State-Changed-By: mmitchel State-Changed-When: Thu Apr 18 09:03:27 2002 State-Changed-Why: Confirmed. http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6039
The following reply was made to PR target/6039; it has been noted by GNATS. From: Dara Hazeghi <dhazeghi@yahoo.com> To: tori@unhappy.mine.nu, gcc-gnats@gcc.gnu.org, nobody@gcc.gnu.org Cc: Subject: Re: target/6039: [ARM] interrupt attribute generats wrong code Date: Fri, 16 May 2003 19:48:47 -0700 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit- trail&database=gcc&pr=6039 Hello, gcc 3.0.4 and 3.1 cvs are rather ancient at this point. Would it be possible for you to check whether this problem is still present. I don't know much about arm assembly, but this is what 3.3 produces: .file "junk.c" .text .align 2 .global foo .type foo, %function foo: @ Interrupt Service Routine. @ args = 0, pretend = 0, frame = 12 @ frame_needed = 1, uses_anonymous_args = 0 str ip, [sp, #-4]! mov ip, sp sub lr, lr, #4 stmfd sp!, {r0, r1, r2, r3, fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #12 mov r3, #0 str r3, [fp, #-40] mov r3, #0 str r3, [fp, #-44] ldr r2, [fp, #-40] ldr r3, [fp, #-44] add r3, r2, r3 str r3, [fp, #-48] bl bar ldmea fp, {r0, r1, r2, r3, fp, ip, pc}^ .size foo, .-foo .ident "GCC: (GNU) 3.3 20030508 (prerelease)" gcc mainline produces: .file "junk.c" .text .align 2 .global foo .type foo, %function foo: @ Interrupt Service Routine. @ args = 0, pretend = 0, frame = 12 @ frame_needed = 1, uses_anonymous_args = 0 str ip, [sp, #-4]! mov ip, sp stmfd sp!, {r0, r1, r2, r3, fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #12 mov r3, #0 str r3, [fp, #-40] mov r3, #0 str r3, [fp, #-44] ldr r2, [fp, #-40] ldr r3, [fp, #-44] add r3, r2, r3 str r3, [fp, #-48] bl bar ldmea fp, {r0, r1, r2, r3, fp, sp, lr} ldmfd sp!, {ip} subs pc, lr, #4 .size foo, .-foo .ident "GCC: (GNU) 3.4 20030508 (experimental)" Can you confirm if these are correct? Thanks, Dara
Synopsis: [ARM] interrupt attribute generats wrong code State-Changed-From-To: analyzed->feedback State-Changed-By: bajo State-Changed-When: Sat May 17 06:58:54 2003 State-Changed-Why: See Dara's question. http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6039