| .. | .. |
|---|
| 209 | 209 | /* we might want to write optimized versions of these later */ |
|---|
| 210 | 210 | #define __constant_count_memset(s, c, count) __memset_generic((s), (c), (count)) |
|---|
| 211 | 211 | |
|---|
| 212 | | -/* |
|---|
| 213 | | - * memset(x, 0, y) is a reasonably common thing to do, so we want to fill |
|---|
| 214 | | - * things 32 bits at a time even when we don't know the size of the |
|---|
| 215 | | - * area at compile-time.. |
|---|
| 216 | | - */ |
|---|
| 217 | | -static __always_inline |
|---|
| 218 | | -void *__constant_c_memset(void *s, unsigned long c, size_t count) |
|---|
| 219 | | -{ |
|---|
| 220 | | - int d0, d1; |
|---|
| 221 | | - asm volatile("rep ; stosl\n\t" |
|---|
| 222 | | - "testb $2,%b3\n\t" |
|---|
| 223 | | - "je 1f\n\t" |
|---|
| 224 | | - "stosw\n" |
|---|
| 225 | | - "1:\ttestb $1,%b3\n\t" |
|---|
| 226 | | - "je 2f\n\t" |
|---|
| 227 | | - "stosb\n" |
|---|
| 228 | | - "2:" |
|---|
| 229 | | - : "=&c" (d0), "=&D" (d1) |
|---|
| 230 | | - : "a" (c), "q" (count), "0" (count/4), "1" ((long)s) |
|---|
| 231 | | - : "memory"); |
|---|
| 232 | | - return s; |
|---|
| 233 | | -} |
|---|
| 234 | | - |
|---|
| 235 | 212 | /* Added by Gertjan van Wingerde to make minix and sysv module work */ |
|---|
| 236 | 213 | #define __HAVE_ARCH_STRNLEN |
|---|
| 237 | 214 | extern size_t strnlen(const char *s, size_t count); |
|---|
| .. | .. |
|---|
| 239 | 216 | |
|---|
| 240 | 217 | #define __HAVE_ARCH_STRSTR |
|---|
| 241 | 218 | extern char *strstr(const char *cs, const char *ct); |
|---|
| 242 | | - |
|---|
| 243 | | -/* |
|---|
| 244 | | - * This looks horribly ugly, but the compiler can optimize it totally, |
|---|
| 245 | | - * as we by now know that both pattern and count is constant.. |
|---|
| 246 | | - */ |
|---|
| 247 | | -static __always_inline |
|---|
| 248 | | -void *__constant_c_and_count_memset(void *s, unsigned long pattern, |
|---|
| 249 | | - size_t count) |
|---|
| 250 | | -{ |
|---|
| 251 | | - switch (count) { |
|---|
| 252 | | - case 0: |
|---|
| 253 | | - return s; |
|---|
| 254 | | - case 1: |
|---|
| 255 | | - *(unsigned char *)s = pattern & 0xff; |
|---|
| 256 | | - return s; |
|---|
| 257 | | - case 2: |
|---|
| 258 | | - *(unsigned short *)s = pattern & 0xffff; |
|---|
| 259 | | - return s; |
|---|
| 260 | | - case 3: |
|---|
| 261 | | - *(unsigned short *)s = pattern & 0xffff; |
|---|
| 262 | | - *((unsigned char *)s + 2) = pattern & 0xff; |
|---|
| 263 | | - return s; |
|---|
| 264 | | - case 4: |
|---|
| 265 | | - *(unsigned long *)s = pattern; |
|---|
| 266 | | - return s; |
|---|
| 267 | | - } |
|---|
| 268 | | - |
|---|
| 269 | | -#define COMMON(x) \ |
|---|
| 270 | | - asm volatile("rep ; stosl" \ |
|---|
| 271 | | - x \ |
|---|
| 272 | | - : "=&c" (d0), "=&D" (d1) \ |
|---|
| 273 | | - : "a" (eax), "0" (count/4), "1" ((long)s) \ |
|---|
| 274 | | - : "memory") |
|---|
| 275 | | - |
|---|
| 276 | | - { |
|---|
| 277 | | - int d0, d1; |
|---|
| 278 | | - unsigned long eax = pattern; |
|---|
| 279 | | - |
|---|
| 280 | | - switch (count % 4) { |
|---|
| 281 | | - case 0: |
|---|
| 282 | | - COMMON(""); |
|---|
| 283 | | - return s; |
|---|
| 284 | | - case 1: |
|---|
| 285 | | - COMMON("\n\tstosb"); |
|---|
| 286 | | - return s; |
|---|
| 287 | | - case 2: |
|---|
| 288 | | - COMMON("\n\tstosw"); |
|---|
| 289 | | - return s; |
|---|
| 290 | | - default: |
|---|
| 291 | | - COMMON("\n\tstosw\n\tstosb"); |
|---|
| 292 | | - return s; |
|---|
| 293 | | - } |
|---|
| 294 | | - } |
|---|
| 295 | | - |
|---|
| 296 | | -#undef COMMON |
|---|
| 297 | | -} |
|---|
| 298 | | - |
|---|
| 299 | | -#define __constant_c_x_memset(s, c, count) \ |
|---|
| 300 | | - (__builtin_constant_p(count) \ |
|---|
| 301 | | - ? __constant_c_and_count_memset((s), (c), (count)) \ |
|---|
| 302 | | - : __constant_c_memset((s), (c), (count))) |
|---|
| 303 | 219 | |
|---|
| 304 | 220 | #define __memset(s, c, count) \ |
|---|
| 305 | 221 | (__builtin_constant_p(count) \ |
|---|