Rev 3427 | Rev 3728 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3427 | Rev 3727 | ||
---|---|---|---|
Line 72... | Line 72... | ||
72 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
72 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
73 | 73 | ||
74 | return (char *) dst; |
74 | return (char *) dst; |
75 | } |
75 | } |
76 | 76 | ||
- | 77 | /** Copy memory block. */ |
|
77 | void *memcpy(void *dst, const void *src, size_t n) |
78 | void *memcpy(void *dst, const void *src, size_t n) |
78 | { |
79 | { |
79 | int i, j; |
80 | size_t i; |
- | 81 | size_t mod, fill; |
|
- | 82 | size_t word_size; |
|
- | 83 | size_t n_words; |
|
- | 84 | ||
- | 85 | const unsigned long *srcw; |
|
- | 86 | unsigned long *dstw; |
|
- | 87 | const uint8_t *srcb; |
|
- | 88 | uint8_t *dstb; |
|
- | 89 | ||
- | 90 | word_size = sizeof(unsigned long); |
|
80 | 91 | ||
- | 92 | /* |
|
- | 93 | * Are source and destination addresses congruent modulo word_size? |
|
- | 94 | * If not, use unaligned_memcpy(). |
|
- | 95 | */ |
|
- | 96 | ||
81 | if (((long) dst & (sizeof(long) - 1)) || |
97 | if (((uintptr_t) dst & (word_size - 1)) != |
82 | ((long) src & (sizeof(long) - 1))) |
98 | ((uintptr_t) src & (word_size - 1))) |
83 | return unaligned_memcpy(dst, src, n); |
99 | return unaligned_memcpy(dst, src, n); |
84 | 100 | ||
- | 101 | /* |
|
85 | for (i = 0; i < n / sizeof(unsigned long); i++) |
102 | * mod is the address modulo word size. fill is the length of the |
- | 103 | * initial buffer segment before the first word boundary. |
|
86 | ((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
104 | * If the buffer is very short, use unaligned_memcpy(), too. |
87 | 105 | */ |
|
- | 106 | ||
88 | for (j = 0; j < n % sizeof(unsigned long); j++) |
107 | mod = (uintptr_t) dst & (word_size - 1); |
- | 108 | fill = word_size - mod; |
|
- | 109 | if (fill > n) fill = n; |
|
- | 110 | ||
- | 111 | /* Copy the initial segment. */ |
|
- | 112 | ||
- | 113 | srcb = src; |
|
- | 114 | dstb = dst; |
|
- | 115 | ||
- | 116 | i = fill; |
|
- | 117 | while (i-- > 0) |
|
- | 118 | *dstb++ = *srcb++; |
|
- | 119 | ||
- | 120 | /* Compute remaining length. */ |
|
- | 121 | ||
- | 122 | n -= fill; |
|
- | 123 | if (n == 0) return dst; |
|
- | 124 | ||
- | 125 | /* Pointers to aligned segment. */ |
|
- | 126 | ||
89 | ((unsigned char *) (((unsigned long *) dst) + i))[j] = |
127 | dstw = (unsigned long *) dstb; |
90 | ((unsigned char *) (((unsigned long *) src) + i))[j]; |
128 | srcw = (const unsigned long *) srcb; |
- | 129 | ||
- | 130 | n_words = n / word_size; /* Number of whole words to copy. */ |
|
- | 131 | n -= n_words * word_size; /* Remaining bytes at the end. */ |
|
- | 132 | ||
- | 133 | /* "Fast" copy. */ |
|
- | 134 | i = n_words; |
|
- | 135 | while (i-- > 0) |
|
- | 136 | *dstw++ = *srcw++; |
|
- | 137 | ||
91 | 138 | /* |
|
- | 139 | * Copy the rest. |
|
- | 140 | */ |
|
- | 141 | ||
- | 142 | srcb = (const uint8_t *) srcw; |
|
- | 143 | dstb = (uint8_t *) dstw; |
|
- | 144 | ||
- | 145 | i = n; |
|
- | 146 | while (i-- > 0) |
|
- | 147 | *dstb++ = *srcb++; |
|
- | 148 | ||
92 | return (char *) dst; |
149 | return dst; |
93 | } |
150 | } |
94 | 151 | ||
95 | void *memmove(void *dst, const void *src, size_t n) |
152 | void *memmove(void *dst, const void *src, size_t n) |
96 | { |
153 | { |
97 | int i, j; |
154 | int i, j; |