summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2006-05-13 13:10:24 +0200
committerMichael Brown2006-05-13 13:10:24 +0200
commit97d265f8dc93f85863c3be802951a85879499fed (patch)
tree3952c3517199b066e0447f889fc595152f203bd6
parentAdded tunctl (since it is difficult to find for many distros). (diff)
downloadipxe-97d265f8dc93f85863c3be802951a85879499fed.tar.gz
ipxe-97d265f8dc93f85863c3be802951a85879499fed.tar.xz
ipxe-97d265f8dc93f85863c3be802951a85879499fed.zip
(Redoing check-in lost by SourceForge's failure.)
Avoid optimisation errors under -fstrict-aliasing.
-rw-r--r--src/arch/i386/include/bits/string.h32
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;
}