|
@@ -34,6 +34,16 @@ __memcpy ( void *dest, const void *src, size_t len ) {
|
34
|
34
|
|
35
|
35
|
static inline __attribute__ (( always_inline )) void *
|
36
|
36
|
__constant_memcpy ( void *dest, const void *src, size_t len ) {
|
|
37
|
+ union {
|
|
38
|
+ uint32_t u32[2];
|
|
39
|
+ uint16_t u16[4];
|
|
40
|
+ uint8_t u8[8];
|
|
41
|
+ } __attribute__ (( __may_alias__ )) *dest_u = dest;
|
|
42
|
+ const union {
|
|
43
|
+ uint32_t u32[2];
|
|
44
|
+ uint16_t u16[4];
|
|
45
|
+ uint8_t u8[8];
|
|
46
|
+ } __attribute__ (( __may_alias__ )) *src_u = src;
|
37
|
47
|
const void *esi;
|
38
|
48
|
void *edi;
|
39
|
49
|
|
|
@@ -49,33 +59,33 @@ __constant_memcpy ( void *dest, const void *src, size_t len ) {
|
49
|
59
|
*
|
50
|
60
|
*/
|
51
|
61
|
case 1 : /* 4 bytes */
|
52
|
|
- * ( uint8_t * ) ( dest + 0 ) = * ( uint8_t * ) ( src + 0 );
|
|
62
|
+ dest_u->u8[0] = src_u->u8[0];
|
53
|
63
|
return dest;
|
54
|
64
|
case 2 : /* 6 bytes */
|
55
|
|
- * ( uint16_t * ) ( dest + 0 ) = * ( uint16_t * ) ( src + 0 );
|
|
65
|
+ dest_u->u16[0] = src_u->u16[0];
|
56
|
66
|
return dest;
|
57
|
67
|
case 4 : /* 4 bytes */
|
58
|
|
- * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 );
|
|
68
|
+ dest_u->u32[0] = src_u->u32[0];
|
59
|
69
|
return dest;
|
60
|
70
|
/*
|
61
|
71
|
* Double-register moves; these are probably still a win.
|
62
|
72
|
*
|
63
|
73
|
*/
|
64
|
74
|
case 3 : /* 12 bytes */
|
65
|
|
- * ( uint16_t * ) ( dest + 0 ) = * ( uint16_t * ) ( src + 0 );
|
66
|
|
- * ( uint8_t * ) ( dest + 2 ) = * ( uint8_t * ) ( src + 2 );
|
|
75
|
+ dest_u->u16[0] = src_u->u16[0];
|
|
76
|
+ dest_u->u8[2] = src_u->u8[2];
|
67
|
77
|
return dest;
|
68
|
78
|
case 5 : /* 10 bytes */
|
69
|
|
- * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 );
|
70
|
|
- * ( uint8_t * ) ( dest + 4 ) = * ( uint8_t * ) ( src + 4 );
|
|
79
|
+ dest_u->u32[0] = src_u->u32[0];
|
|
80
|
+ dest_u->u8[4] = src_u->u8[4];
|
71
|
81
|
return dest;
|
72
|
82
|
case 6 : /* 12 bytes */
|
73
|
|
- * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 );
|
74
|
|
- * ( uint16_t * ) ( dest + 4 ) = * ( uint16_t * ) ( src + 4 );
|
|
83
|
+ dest_u->u32[0] = src_u->u32[0];
|
|
84
|
+ dest_u->u16[2] = src_u->u16[2];
|
75
|
85
|
return dest;
|
76
|
86
|
case 8 : /* 10 bytes */
|
77
|
|
- * ( uint32_t * ) ( dest + 0 ) = * ( uint32_t * ) ( src + 0 );
|
78
|
|
- * ( uint32_t * ) ( dest + 4 ) = * ( uint32_t * ) ( src + 4 );
|
|
87
|
+ dest_u->u32[0] = src_u->u32[0];
|
|
88
|
+ dest_u->u32[1] = src_u->u32[1];
|
79
|
89
|
return dest;
|
80
|
90
|
}
|
81
|
91
|
|