The code generated for a ppc32 for the 1 line function f below is incorrect.
Not that it should matter but this is a cross compiler, built with cross-tool.

typedef struct {
        unsigned char c;
        unsigned int i:24;
} e_t;

f(e_t *p)
{
        p->i<<= 8;
}

#include <stdio.h>
int
main(int argc, char *argv[])
{
        e_t x = { .c='a', .i=0x12345 };
        f(&x);
        printf("(0x12345 << 8 ) & 0xffffff = %x\n", x.i);
}

Compiled with "-O".
The output is
(0x12345 << 8 ) & 0xffffff = 234561
The bottom 8 bits should be zero, not the contents of x.c.
If one comments out the driver function, so all that you are left with is the f
function, one gets the following assembler. I have added pseudo-C comments.


        .file   "t.c"
        .section        ".text"
        .align 2
        .globl f
        .type   f, @function
f:
        lwz 9,0(3)                      ;; r9 = *p
        mr 0,9                          ;; r0 = r9
        rlwimi 0,9,8,8,31       ;; low24(r0) = low24(rotate8(r9)) ****** Wrong
        stw 0,0(3)                      ;; *p = r0
        blr                                     ;; return
        .size   f, .-f
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.4.6"

gcc2.95 generates the correct code, and answer
(0x12345 << 8 ) & 0xffffff = 234500


-- 
           Summary: gcc3.4.6 generates incorrect ppc32 code for combination
                    of bitfields and shifts
           Product: gcc
           Version: 3.4.6
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ISPARRY at BROCADE dot COM
 GCC build triplet: i686-host_pc-linux-gnu
  GCC host triplet: i686-host_pc-linux-gnu
GCC target triplet: powerpc-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30595

Reply via email to