|
146 | 146 | const char *s_start = s; |
147 | 147 | while (*s) |
148 | 148 | ++s; |
149 | | - return (size_t)s - (size_t)s_start; |
| 149 | + return (size_t)((uintptr_t)s - (uintptr_t)s_start); |
150 | 150 | } |
151 | 151 |
|
152 | 152 | #include <linux/string.h> |
|
157 | 157 | (sizeof(s) - 1) : strlen(s)) |
158 | 158 |
|
159 | 159 | static inline void *my_memcpy(void *dest, const void *src, size_t n) { |
160 | | - u8 *src_bytes = (u8 *)src, |
161 | | - *dest_bytes = (u8 *)dest, |
162 | | - *endp = src_bytes + n; |
163 | | - while (src_bytes < endp) |
164 | | - *dest_bytes++ = *src_bytes++; |
| 160 | + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { |
| 161 | + uintptr_t *src_longs = (uintptr_t *)src, |
| 162 | + *dest_longs = (uintptr_t *)dest, |
| 163 | + *endp = (uintptr_t *)((u8 *)src + n); |
| 164 | + while (src_longs < endp) |
| 165 | + *dest_longs++ = *src_longs++; |
| 166 | + } else { |
| 167 | + u8 *src_bytes = (u8 *)src, |
| 168 | + *dest_bytes = (u8 *)dest, |
| 169 | + *endp = src_bytes + n; |
| 170 | + while (src_bytes < endp) |
| 171 | + *dest_bytes++ = *src_bytes++; |
| 172 | + } |
165 | 173 | return dest; |
166 | 174 | } |
167 | 175 | #undef memcpy |
168 | 176 | #define memcpy my_memcpy |
169 | 177 |
|
170 | 178 | static inline void *my_memset(void *dest, int c, size_t n) { |
171 | | - u8 *dest_bytes = (u8 *)dest, *endp = dest_bytes + n; |
172 | | - while (dest_bytes < endp) |
173 | | - *dest_bytes++ = (u8)c; |
| 179 | + if (! (((uintptr_t)dest | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { |
| 180 | + uintptr_t c_long = __builtin_choose_expr( |
| 181 | + sizeof(uintptr_t) == 8, |
| 182 | + (uintptr_t)(u8)c * 0x0101010101010101UL, |
| 183 | + (uintptr_t)(u8)c * 0x01010101U |
| 184 | + ); |
| 185 | + uintptr_t *dest_longs = (uintptr_t *)dest, *endp = (uintptr_t *)((u8 *)dest_longs + n); |
| 186 | + while (dest_longs < endp) |
| 187 | + *dest_longs++ = c_long; |
| 188 | + } else { |
| 189 | + u8 *dest_bytes = (u8 *)dest, *endp = dest_bytes + n; |
| 190 | + while (dest_bytes < endp) |
| 191 | + *dest_bytes++ = (u8)c; |
| 192 | + } |
174 | 193 | return dest; |
175 | 194 | } |
176 | 195 | #undef memset |
177 | 196 | #define memset my_memset |
178 | 197 |
|
179 | 198 | static inline void *my_memmove(void *dest, const void *src, size_t n) { |
180 | | - u8 *src_bytes = (u8 *)src, *dest_bytes = (u8 *)dest; |
181 | | - if (src_bytes < dest_bytes) { |
182 | | - u8 *startp = src_bytes; |
183 | | - src_bytes += n - 1; |
184 | | - dest_bytes += n - 1; |
185 | | - while (src_bytes >= startp) |
186 | | - *dest_bytes-- = *src_bytes--; |
187 | | - } else if (src_bytes > dest_bytes) { |
188 | | - u8 *endp = src_bytes + n; |
189 | | - while (src_bytes < endp) |
190 | | - *dest_bytes++ = *src_bytes++; |
| 199 | + if (! (((uintptr_t)dest | (uintptr_t)src | (uintptr_t)n) & (uintptr_t)(sizeof(uintptr_t) - 1))) { |
| 200 | + uintptr_t *src_longs = (uintptr_t *)src, *dest_longs = (uintptr_t *)dest; |
| 201 | + n >>= __builtin_choose_expr( |
| 202 | + sizeof(uintptr_t) == 8, |
| 203 | + 3U, |
| 204 | + 2U); |
| 205 | + if (src_longs < dest_longs) { |
| 206 | + uintptr_t *startp = src_longs; |
| 207 | + src_longs += n - 1; |
| 208 | + dest_longs += n - 1; |
| 209 | + while (src_longs >= startp) |
| 210 | + *dest_longs-- = *src_longs--; |
| 211 | + } else if (src_longs > dest_longs) { |
| 212 | + uintptr_t *endp = src_longs + n; |
| 213 | + while (src_longs < endp) |
| 214 | + *dest_longs++ = *src_longs++; |
| 215 | + } |
| 216 | + } else { |
| 217 | + u8 *src_bytes = (u8 *)src, *dest_bytes = (u8 *)dest; |
| 218 | + if (src_bytes < dest_bytes) { |
| 219 | + u8 *startp = src_bytes; |
| 220 | + src_bytes += n - 1; |
| 221 | + dest_bytes += n - 1; |
| 222 | + while (src_bytes >= startp) |
| 223 | + *dest_bytes-- = *src_bytes--; |
| 224 | + } else if (src_bytes > dest_bytes) { |
| 225 | + u8 *endp = src_bytes + n; |
| 226 | + while (src_bytes < endp) |
| 227 | + *dest_bytes++ = *src_bytes++; |
| 228 | + } |
191 | 229 | } |
192 | 230 | return dest; |
193 | 231 | } |
|
0 commit comments