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