diff options
author | Michael Brown | 2006-05-13 13:10:24 +0200 |
---|---|---|
committer | Michael Brown | 2006-05-13 13:10:24 +0200 |
commit | 97d265f8dc93f85863c3be802951a85879499fed (patch) | |
tree | 3952c3517199b066e0447f889fc595152f203bd6 /src | |
parent | Added tunctl (since it is difficult to find for many distros). (diff) | |
download | ipxe-97d265f8dc93f85863c3be802951a85879499fed.tar.gz ipxe-97d265f8dc93f85863c3be802951a85879499fed.tar.xz ipxe-97d265f8dc93f85863c3be802951a85879499fed.zip |
(Redoing check-in lost by SourceForge's failure.)
Avoid optimisation errors under -fstrict-aliasing.
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/i386/include/bits/string.h | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/arch/i386/include/bits/string.h b/src/arch/i386/include/bits/string.h index e47f4c75..46772260 100644 --- a/src/arch/i386/include/bits/string.h +++ b/src/arch/i386/include/bits/string.h @@ -34,6 +34,16 @@ __memcpy ( void *dest, const void *src, size_t len ) { static inline __attribute__ (( always_inline )) void * __constant_memcpy ( void *dest, const void *src, size_t len ) { + union { + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8[8]; + } __attribute__ (( __may_alias__ )) *dest_u = dest; + const union { + uint32_t u32[2]; + uint16_t u16[4]; + uint8_t u8[8]; + } __attribute__ (( __may_alias__ )) *src_u = src; const void *esi; void *edi; @@ -49,33 +59,33 @@ __constant_memcpy ( void *dest, const void *src, size_t len ) { * */ case 1 : /* 4 bytes */ - * ( uint8_t * ) ( dest + 0 ) = * ( uint8_t * ) ( src + 0 ); + dest_u->u8[0] = src_u->u8[0]; return dest; case 2 : /* 6 bytes */ - * ( uint16_t * ) ( dest + 0 ) = * ( uint16_t * ) ( src + 0 ); + dest_u->u16[0] = src_u->u16[0]; return dest; case 4 : /* 4 bytes */ - * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 ); + dest_u->u32[0] = src_u->u32[0]; return dest; /* * Double-register moves; these are probably still a win. * */ case 3 : /* 12 bytes */ - * ( uint16_t * ) ( dest + 0 ) = * ( uint16_t * ) ( src + 0 ); - * ( uint8_t * ) ( dest + 2 ) = * ( uint8_t * ) ( src + 2 ); + dest_u->u16[0] = src_u->u16[0]; + dest_u->u8[2] = src_u->u8[2]; return dest; case 5 : /* 10 bytes */ - * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 ); - * ( uint8_t * ) ( dest + 4 ) = * ( uint8_t * ) ( src + 4 ); + dest_u->u32[0] = src_u->u32[0]; + dest_u->u8[4] = src_u->u8[4]; return dest; case 6 : /* 12 bytes */ - * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 ); - * ( uint16_t * ) ( dest + 4 ) = * ( uint16_t * ) ( src + 4 ); + dest_u->u32[0] = src_u->u32[0]; + dest_u->u16[2] = src_u->u16[2]; return dest; case 8 : /* 10 bytes */ - * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 ); - * ( uint32_t * ) ( dest + 4 ) = * ( uint32_t * ) ( src + 4 ); + dest_u->u32[0] = src_u->u32[0]; + dest_u->u32[1] = src_u->u32[1]; return dest; } |