123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #include <string.h>
- #include <stdlib.h>
- #include <limits.h>
- #include "memcopy.h"
- #define LONG_MAX_32_BITS 2147483647
- #undef memchr
- void *memchr (const void * s, int c_in, size_t n)
- {
- const unsigned char *char_ptr;
- const unsigned long int *longword_ptr;
- unsigned long int longword, magic_bits, charmask;
- unsigned reg_char c;
- c = (unsigned char) c_in;
-
- for (char_ptr = (const unsigned char *) s;
- n > 0 && ((unsigned long int) char_ptr
- & (sizeof (longword) - 1)) != 0;
- --n, ++char_ptr)
- if (*char_ptr == c)
- return (void *) char_ptr;
-
- longword_ptr = (unsigned long int *) char_ptr;
-
- if (sizeof (longword) != 4 && sizeof (longword) != 8)
- abort ();
- #if LONG_MAX <= LONG_MAX_32_BITS
- magic_bits = 0x7efefeff;
- #else
- magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;
- #endif
-
- charmask = c | (c << 8);
- charmask |= charmask << 16;
- #if LONG_MAX > LONG_MAX_32_BITS
- charmask |= charmask << 32;
- #endif
-
- while (n >= sizeof (longword))
- {
-
- longword = *longword_ptr++ ^ charmask;
-
- if ((((longword + magic_bits)
-
- ^ ~longword)
-
- & ~magic_bits) != 0)
- {
-
- const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);
- if (cp[0] == c)
- return (void *) cp;
- if (cp[1] == c)
- return (void *) &cp[1];
- if (cp[2] == c)
- return (void *) &cp[2];
- if (cp[3] == c)
- return (void *) &cp[3];
- #if LONG_MAX > 2147483647
- if (cp[4] == c)
- return (void *) &cp[4];
- if (cp[5] == c)
- return (void *) &cp[5];
- if (cp[6] == c)
- return (void *) &cp[6];
- if (cp[7] == c)
- return (void *) &cp[7];
- #endif
- }
- n -= sizeof (longword);
- }
- char_ptr = (const unsigned char *) longword_ptr;
- while (n-- > 0)
- {
- if (*char_ptr == c)
- return (void *) char_ptr;
- else
- ++char_ptr;
- }
- return 0;
- }
- libc_hidden_weak(memchr)
|