On 10/11/11 03:57, Joey Ye wrote:
> Trunk gcc mis-handles following volatile bitfield case on ARM target:
> 
> $ cat a.c
> extern void check(int);
> typedef struct {
>   volatile unsigned short a:8, b:8;
> } BitStruct;
> BitStruct bits = {1, 2};
> int main ()
> {
>   check(bits.a);
>   return 0;
> }
> $ arm-none-eabi-gcc -v 2>&1 |grep "gcc version"
> gcc version 4.7.0 20111024 (experimental) [trunk revision 180388] (GCC) 
> $ arm-none-eabi-gcc -S a.c -mthumb -mcpu=cortex-m3
> $ grep -v "^\s*\." a.s
> bits:
> main:
>       @ args = 0, pretend = 0, frame = 0
>       @ frame_needed = 1, uses_anonymous_args = 0
>       push    {r7, lr}
>       add     r7, sp, #0
>       movw    r3, #:lower16:bits
>       movt    r3, #:upper16:bits
>       ldrh    r3, [r3, #0]    @ movhi
>       uxth    r3, r3  // Should be uxtb here. As a result,
>                     // the output becomes 2056, instead of 8 as expected
>       mov     r0, r3
>       bl      check
>       mov     r3, #0
>       mov     r0, r3
>       pop     {r7, pc}
> 
> Root cause is that when restrict-volatile-bitfields is enabled, which is ARM
> default. Volatile bitfields isn't loaded as bitfield even if bitfield size
> is less than load size.
> 
> It is actually a regression introduced by:
> http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01477.html
> 
> 
> Patch to fix this:
> 2011-11-10  Joey Ye  <joey...@arm.com>
> 
>         Fix volatile bitfield load
>         * gcc/expr.c (expand_expr_real_1): Check bitfield size
>           smaller than mode size.

Normally it would be best to write

        * expr.c (expand_expr_real_1): Correctly handle strict volatile
        bitfield loads smaller than mode size.


> 
> Testcase:
> 2011-11-10  Joey Ye  <joey...@arm.com>
> 
>         * gcc.dg/volatile-bitfields-1.c: New.
> 

OK.

R.

Reply via email to