This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

c/622: incorrect arm-elf codegen with -mthumb-interwork



>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:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]