On Mon, 2010-03-01 at 09:03 -0800, Michel Dänzer wrote:
> On Fri, 2010-02-26 at 08:47 -0800, Jose Fonseca wrote: 
> > Module: Mesa
> > Branch: master
> > Commit: 9beb302212a2afac408016cbd7b93c8b859e4910
> > URL:    
> > http://cgit.freedesktop.org/mesa/mesa/commit/?id=9beb302212a2afac408016cbd7b93c8b859e4910
> > 
> > Author: José Fonseca <jfons...@vmware.com>
> > Date:   Fri Feb 26 16:45:22 2010 +0000
> > 
> > util: Code generate functions to pack and unpack a single pixel.
> > 
> > Should work correctly for all pixel formats except SRGB formats.
> > 
> > Generated code made much simpler by defining the pixel format as
> > a C structure. For example this is the generated structure for
> > PIPE_FORMAT_B6UG5SR5S_NORM:
> > 
> > union util_format_b6ug5sr5s_norm {
> >    uint16_t value;
> >    struct {
> >       int r:5;
> >       int g:5;
> >       unsigned b:6;
> >    } chan;
> > };
> 
> José, are you aware that the memory layout of bitfields is mostly
> implementation dependent? IME this makes them mostly unusable for
> modelling hardware in a portable manner.

It's not only implementation dependent and slow -- it is also buggy!

gcc-4.4.3 is doing something very fishy to single bit fields. 

See the attached code. ff ff ff ff is expected, but ff ff ff 01 is
printed with gcc-4.4.3. Even without any optimization. gcc-4.3.4 works
fine.

Am I missing something or is this effectively a bug?

Jose
#include <stdint.h>
#include <string.h>
#include <stdio.h>

union util_format_b5g5r5a1_unorm {
   uint16_t value;
   struct {
      unsigned b:5;
      unsigned g:5;
      unsigned r:5;
      unsigned a:1;
   } chan;
};

void
util_format_b5g5r5a1_unorm_unpack_4ub(uint8_t *dst, const void *src)
{
   union util_format_b5g5r5a1_unorm pixel;
   memcpy(&pixel, src, sizeof pixel);
   dst[0] = (uint8_t)(((uint32_t)pixel.chan.r) * 0xff / 0x1f); /* r */
   dst[1] = (uint8_t)(((uint32_t)pixel.chan.g) * 0xff / 0x1f); /* g */
   dst[2] = (uint8_t)(((uint32_t)pixel.chan.b) * 0xff / 0x1f); /* b */
   dst[3] = (uint8_t)(((uint32_t)pixel.chan.a) * 0xff / 0x1); /* a */
}

int main()
{
	uint16_t packed = 0xffff;
	uint8_t unpacked[4];

	util_format_b5g5r5a1_unorm_unpack_4ub(unpacked, &packed);
	
	/* ff ff ff ff is expected, but ff ff ff 01 is printed */
	printf("%02x %02x %02x %02x\n", unpacked[0], unpacked[1], unpacked[2], unpacked[3]);

	return 0;
}
        .file   "test.c"
        .text
.globl util_format_b5g5r5a1_unorm_unpack_4ub
        .type   util_format_b5g5r5a1_unorm_unpack_4ub, @function
util_format_b5g5r5a1_unorm_unpack_4ub:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $36, %esp
        movl    $4, 8(%esp)
        movl    12(%ebp), %eax
        movl    %eax, 4(%esp)
        leal    -8(%ebp), %eax
        movl    %eax, (%esp)
        call    memcpy
        movzbl  -7(%ebp), %eax
        shrb    $2, %al
        andl    $31, %eax
        movzbl  %al, %edx
        movl    %edx, %eax
        sall    $8, %eax
        movl    %eax, %ecx
        subl    %edx, %ecx
        movl    %ecx, -24(%ebp)
        movl    $138547333, -28(%ebp)
        movl    -28(%ebp), %eax
        mull    -24(%ebp)
        movl    %edx, %ecx
        movl    -24(%ebp), %eax
        subl    %ecx, %eax
        shrl    %eax
        leal    (%ecx,%eax), %eax
        shrl    $4, %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        movb    %dl, (%eax)
        movl    8(%ebp), %eax
        leal    1(%eax), %ebx
        movzwl  -8(%ebp), %eax
        shrw    $5, %ax
        andl    $31, %eax
        movzbl  %al, %edx
        movl    %edx, %eax
        sall    $8, %eax
        movl    %eax, %ecx
        subl    %edx, %ecx
        movl    %ecx, -24(%ebp)
        movl    $138547333, -28(%ebp)
        movl    -28(%ebp), %eax
        mull    -24(%ebp)
        movl    %edx, %ecx
        movl    -24(%ebp), %eax
        subl    %ecx, %eax
        shrl    %eax
        leal    (%ecx,%eax), %eax
        shrl    $4, %eax
        movb    %al, (%ebx)
        movl    8(%ebp), %eax
        leal    2(%eax), %ebx
        movzbl  -8(%ebp), %eax
        andl    $31, %eax
        movzbl  %al, %edx
        movl    %edx, %eax
        sall    $8, %eax
        movl    %eax, %ecx
        subl    %edx, %ecx
        movl    %ecx, -24(%ebp)
        movl    $138547333, -28(%ebp)
        movl    -28(%ebp), %eax
        mull    -24(%ebp)
        movl    %edx, %ecx
        movl    -24(%ebp), %eax
        subl    %ecx, %eax
        shrl    %eax
        leal    (%ecx,%eax), %eax
        shrl    $4, %eax
        movb    %al, (%ebx)
        movl    8(%ebp), %eax
        leal    3(%eax), %ecx
        movzbl  -7(%ebp), %eax
        shrb    $7, %al
        movzbl  %al, %edx
        movl    %edx, %eax
        sall    $8, %eax
        subl    %edx, %eax
        movb    %al, (%ecx)
        addl    $36, %esp
        popl    %ebx
        popl    %ebp
        ret
        .size   util_format_b5g5r5a1_unorm_unpack_4ub, 
.-util_format_b5g5r5a1_unorm_unpack_4ub
        .section        .rodata
.LC0:
        .string "%02x %02x %02x %02x\n"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        pushl   %ecx
        subl    $48, %esp
        movw    $-1, -10(%ebp)
        leal    -10(%ebp), %eax
        movl    %eax, 4(%esp)
        leal    -14(%ebp), %eax
        movl    %eax, (%esp)
        call    util_format_b5g5r5a1_unorm_unpack_4ub
        movzbl  -11(%ebp), %eax
        movzbl  %al, %ecx
        movzbl  -12(%ebp), %eax
        movzbl  %al, %ebx
        movzbl  -13(%ebp), %eax
        movzbl  %al, %edx
        movzbl  -14(%ebp), %eax
        movzbl  %al, %eax
        movl    %ecx, 16(%esp)
        movl    %ebx, 12(%esp)
        movl    %edx, 8(%esp)
        movl    %eax, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, %eax
        addl    $48, %esp
        popl    %ecx
        popl    %ebx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (Debian 4.3.4-5) 4.3.4"
        .section        .note.GNU-stack,"",@progbits
        .file   "test.c"
        .text
.globl util_format_b5g5r5a1_unorm_unpack_4ub
        .type   util_format_b5g5r5a1_unorm_unpack_4ub, @function
util_format_b5g5r5a1_unorm_unpack_4ub:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $36, %esp
        movl    $4, 8(%esp)
        movl    12(%ebp), %eax
        movl    %eax, 4(%esp)
        leal    -12(%ebp), %eax
        movl    %eax, (%esp)
        call    memcpy
        movzbl  -11(%ebp), %eax
        shrb    $2, %al
        andl    $31, %eax
        movzbl  %al, %eax
        movl    %eax, %edx
        sall    $8, %edx
        movl    %edx, %ecx
        subl    %eax, %ecx
        movl    $138547333, %edx
        movl    %ecx, %eax
        mull    %edx
        movl    %ecx, %eax
        subl    %edx, %eax
        shrl    %eax
        leal    (%edx,%eax), %eax
        shrl    $4, %eax
        movl    %eax, %edx
        movl    8(%ebp), %eax
        movb    %dl, (%eax)
        movl    8(%ebp), %eax
        leal    1(%eax), %ebx
        movzwl  -12(%ebp), %eax
        shrw    $5, %ax
        andl    $31, %eax
        movzbl  %al, %eax
        movl    %eax, %edx
        sall    $8, %edx
        movl    %edx, %ecx
        subl    %eax, %ecx
        movl    $138547333, %edx
        movl    %ecx, %eax
        mull    %edx
        movl    %ecx, %eax
        subl    %edx, %eax
        shrl    %eax
        leal    (%edx,%eax), %eax
        shrl    $4, %eax
        movb    %al, (%ebx)
        movl    8(%ebp), %eax
        leal    2(%eax), %ebx
        movzbl  -12(%ebp), %eax
        andl    $31, %eax
        movzbl  %al, %eax
        movl    %eax, %edx
        sall    $8, %edx
        movl    %edx, %ecx
        subl    %eax, %ecx
        movl    $138547333, %edx
        movl    %ecx, %eax
        mull    %edx
        movl    %ecx, %eax
        subl    %edx, %eax
        shrl    %eax
        leal    (%edx,%eax), %eax
        shrl    $4, %eax
        movb    %al, (%ebx)
        movl    8(%ebp), %eax
        leal    3(%eax), %edx
        movzbl  -11(%ebp), %eax
        shrb    $7, %al
        negl    %eax
        andl    $1, %eax
        movb    %al, (%edx)
        addl    $36, %esp
        popl    %ebx
        popl    %ebp
        ret
        .size   util_format_b5g5r5a1_unorm_unpack_4ub, 
.-util_format_b5g5r5a1_unorm_unpack_4ub
        .section        .rodata
.LC0:
        .string "%02x %02x %02x %02x\n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        andl    $-16, %esp
        pushl   %esi
        pushl   %ebx
        subl    $56, %esp
        movw    $-1, 46(%esp)
        leal    46(%esp), %eax
        movl    %eax, 4(%esp)
        leal    42(%esp), %eax
        movl    %eax, (%esp)
        call    util_format_b5g5r5a1_unorm_unpack_4ub
        movzbl  45(%esp), %eax
        movzbl  %al, %esi
        movzbl  44(%esp), %eax
        movzbl  %al, %ebx
        movzbl  43(%esp), %eax
        movzbl  %al, %ecx
        movzbl  42(%esp), %eax
        movzbl  %al, %edx
        movl    $.LC0, %eax
        movl    %esi, 16(%esp)
        movl    %ebx, 12(%esp)
        movl    %ecx, 8(%esp)
        movl    %edx, 4(%esp)
        movl    %eax, (%esp)
        call    printf
        movl    $0, %eax
        addl    $56, %esp
        popl    %ebx
        popl    %esi
        movl    %ebp, %esp
        popl    %ebp
        ret
        .size   main, .-main
        .ident  "GCC: (Debian 4.4.3-1) 4.4.3"
        .section        .note.GNU-stack,"",@progbits
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to