Problems migrating to gcc 4.4.3&eabi - apparently a gcc bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I'm trying to migrate to gcc 4.4.3 and eabi (from 4.0.3 non-eabi) for the ARM targets of Rockbox[1]. I have the strong feeling I stumbled upon a gcc bug here.

The story:
The core and codecs run fine under the new compiler, however at least 1 plugin is problematic: mpegplayer[2]. The cpu throws a data abort when rendering begins.

I've narrowed down the problem to the following function call:

mpeg2_idct_add (last, decoder->DCTblock, dest, stride);[3]

mpeg2_idct_add itself is written entirely in assembler. gcc doesn't touch it. However, its prototype for C callers is[4]:

void mpeg2_idct_add(const int last, int16_t * block,
                    uint8_t * dest, const int stride);


According to the (E)ABI, all parameters are supposed to be passed in the registers r0-3.

The disassembly shows that this only happens for the old gcc4.0.3
new gcc:

30788e98:    ebfff984     bl    307874b0 <get_non_intra_block>
30788e9c:    e1a03000     mov    r3, r0
30788ea0:    e58d301c     str    r3, [sp, #28]
30788ea4:    e59d3014     ldr    r3, [sp, #20]
30788ea8:    e59330d0     ldr    r3, [r3, #208]    ; 0xd0
30788eac:    e59d2008     ldr    r2, [sp, #8]
30788eb0:    e58d2000     str    r2, [sp]
30788eb4:    e59d001c     ldr    r0, [sp, #28]
30788eb8:    e1a02003     mov    r2, r3
30788ebc:    e59d300c     ldr    r3, [sp, #12]
30788ec0:    ebffe28a     bl    307818f0 <mpeg2_idct_add>

old gcc:

30794760:    ebffc861     bl    307868ec <get_non_intra_block>
30794764:    e1a03000     mov    r3, r0
30794768:    e58d3014     str    r3, [sp, #20]
3079476c:    e59d3010     ldr    r3, [sp, #16]
30794770:    e59330d0     ldr    r3, [r3, #208]
30794774:    e59d0014     ldr    r0, [sp, #20]
30794778:    e1a01003     mov    r1, r3
3079477c:    e59d2008     ldr    r2, [sp, #8]
30794780:    e59d3004     ldr    r3, [sp, #4]
30794784:    ebffb4ea     bl    30781b34 <mpeg2_idct_add>

(the above disassemblies are from code generated with -O0 to make the parameter passig obvious)

On 4.4.3, 1 parameter is passed via the stack (I figured it goes like this from the old to the new compiler: r0 = r0; r1 > r2; r2 > r3; r3 > stack). So, this call works fine with 4.0.3, but does not with 4.4.3.

Now the reason why I think this is a gcc bug:

If I change the prototype to (the 2nd and 4th argument are swapped, I didn't change the callee or the caller, so gcc obviously throws warnings but the effective parameter passing was the same):

void mpeg2_idct_add(const int last, const int stride,
                    uint8_t * dest, int16_t * block);


then the plugin runs fine, without data abort. And the disassembly shows correct parameter passing.


EABI IIRC only mentions changed rules for passing 64bit types. This call should have been the same with 4.4.3. It eventually is if the parameters are in a different order.

If this is really a gcc bug, how should we proceed? I assume a bug report on bugzilla?

Best regards.


[1]: http://www.rockbox.org/
[2]: http://www.rockbox.org/wiki/PluginMpegplayer
[3]: http://svn.rockbox.org/viewvc.cgi/trunk/apps/plugins/mpegplayer/slice.c?revision=17904&view=markup [4]: http://svn.rockbox.org/viewvc.cgi/trunk/apps/plugins/mpegplayer/mpeg2_internal.h?revision=23677&view=markup



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux