This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/622: incorrect arm-elf codegen with -mthumb-interwork
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/622: incorrect arm-elf codegen with -mthumb-interwork
- From: swetland at frotz dot net
- Date: 8 Oct 2000 20:24:54 -0000
- Cc: swetland at frotz dot net
- Reply-To: swetland at frotz dot net
- Resent-Cc: gcc-prs at gcc dot gnu dot org, gcc-bugs at gcc dot gnu dot org, swetland at frotz dot net
- Resent-Reply-To: gcc-gnats@gcc.gnu.org, swetland@frotz.net
>Number: 622
>Category: c
>Synopsis: incorrect arm-elf codegen with -mthumb-interwork
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Sun Oct 08 13:26:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Brian Swetland
>Release: gcc version 2.96 20000821 (experimental)
>Organization:
>Environment:
target=arm-elf crosscompiler built on Linux
>Description:
When -mthumb-interwork is enabled, gcc (targeting arm-elf)
will generate wrong code on some conditional returns.
The 'how to repeat' section includes a simple testcase
and the disassembly of the resulting code when compiled
at -O2 with and without thumb interworking.
In the case of thumb interworking, a ldmdb { ..., pc } is
replaced with a ldmdb and bx (to allow branching back into
thumb code) -- unfortunately the condition (eq) is lost.
>How-To-Repeat:
/* testcase.c */
typedef struct {
void *p;
} s1;
void *somefunc();
void testcase(s1 *s)
{
void *p;
label:
if(p == 0) {
s->p = p;
return;
}
p = somefunc();
goto label;
}
/* results of arm-elf-gcc -O2 -o test0.o testcase.c */
00000000 <testcase>:
0: e1a0c00d mov r12, sp
4: e92dd810 stmdb sp!, {r4, r11, r12, lr, pc}
8: e24cb004 sub r11, r12, #4 ; 0x4
c: e1a04000 mov r4, r0
10: e3530000 cmp r3, #0 ; 0x0
14: 05843000 streq r3, [r4]
18: 091ba810 ldmeqdb r11, {r4, r11, sp, pc}
1c: ebfffffe bl 1c <testcase+0x1c>
20: e1a03000 mov r3, r0
24: ea000002 b 34 <testcase+0x34>
/* results of arm-elf-gcc -mthumb-interwork -O2 -o test0.o testcase.c */
<testcase>:
0: e1a0c00d mov r12, sp
4: e92dd810 stmdb sp!, {r4, r11, r12, lr, pc}
8: e24cb004 sub r11, r12, #4 ; 0x4
c: e1a04000 mov r4, r0
10: e3530000 cmp r3, #0 ; 0x0
14: 05843000 streq r3, [r4]
18: e91b6810 ldmdb r11, {r4, r11, sp, lr}
1c: e12fff1e bx lr
20: ebfffffe bl 20 <testcase+0x20>
24: e1a03000 mov r3, r0
28: ea000002 b 38 <testcase+0x38>
The ldmdb and bx should be conditionally executed on 'eq' like the non-
interwork version previously. Apparently the condition gets lost somewhere
along the way.
>Fix:
Minor changes to the sources can cause the compiler to
generate a branch instead of conditionally executed code,
but this isn't a very good workaround.
>Release-Note:
>Audit-Trail:
>Unformatted: