diff options
| -rw-r--r-- | arch/tile/lib/memchr_32.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/arch/tile/lib/memchr_32.c b/arch/tile/lib/memchr_32.c index 6235283b485..cc3d9badf03 100644 --- a/arch/tile/lib/memchr_32.c +++ b/arch/tile/lib/memchr_32.c | |||
| @@ -18,12 +18,24 @@ | |||
| 18 | 18 | ||
| 19 | void *memchr(const void *s, int c, size_t n) | 19 | void *memchr(const void *s, int c, size_t n) |
| 20 | { | 20 | { |
| 21 | const uint32_t *last_word_ptr; | ||
| 22 | const uint32_t *p; | ||
| 23 | const char *last_byte_ptr; | ||
| 24 | uintptr_t s_int; | ||
| 25 | uint32_t goal, before_mask, v, bits; | ||
| 26 | char *ret; | ||
| 27 | |||
| 28 | if (__builtin_expect(n == 0, 0)) { | ||
| 29 | /* Don't dereference any memory if the array is empty. */ | ||
| 30 | return NULL; | ||
| 31 | } | ||
| 32 | |||
| 21 | /* Get an aligned pointer. */ | 33 | /* Get an aligned pointer. */ |
| 22 | const uintptr_t s_int = (uintptr_t) s; | 34 | s_int = (uintptr_t) s; |
| 23 | const uint32_t *p = (const uint32_t *)(s_int & -4); | 35 | p = (const uint32_t *)(s_int & -4); |
| 24 | 36 | ||
| 25 | /* Create four copies of the byte for which we are looking. */ | 37 | /* Create four copies of the byte for which we are looking. */ |
| 26 | const uint32_t goal = 0x01010101 * (uint8_t) c; | 38 | goal = 0x01010101 * (uint8_t) c; |
| 27 | 39 | ||
| 28 | /* Read the first word, but munge it so that bytes before the array | 40 | /* Read the first word, but munge it so that bytes before the array |
| 29 | * will not match goal. | 41 | * will not match goal. |
| @@ -31,23 +43,14 @@ void *memchr(const void *s, int c, size_t n) | |||
| 31 | * Note that this shift count expression works because we know | 43 | * Note that this shift count expression works because we know |
| 32 | * shift counts are taken mod 32. | 44 | * shift counts are taken mod 32. |
| 33 | */ | 45 | */ |
| 34 | const uint32_t before_mask = (1 << (s_int << 3)) - 1; | 46 | before_mask = (1 << (s_int << 3)) - 1; |
| 35 | uint32_t v = (*p | before_mask) ^ (goal & before_mask); | 47 | v = (*p | before_mask) ^ (goal & before_mask); |
| 36 | 48 | ||
| 37 | /* Compute the address of the last byte. */ | 49 | /* Compute the address of the last byte. */ |
| 38 | const char *const last_byte_ptr = (const char *)s + n - 1; | 50 | last_byte_ptr = (const char *)s + n - 1; |
| 39 | 51 | ||
| 40 | /* Compute the address of the word containing the last byte. */ | 52 | /* Compute the address of the word containing the last byte. */ |
| 41 | const uint32_t *const last_word_ptr = | 53 | last_word_ptr = (const uint32_t *)((uintptr_t) last_byte_ptr & -4); |
| 42 | (const uint32_t *)((uintptr_t) last_byte_ptr & -4); | ||
| 43 | |||
| 44 | uint32_t bits; | ||
| 45 | char *ret; | ||
| 46 | |||
| 47 | if (__builtin_expect(n == 0, 0)) { | ||
| 48 | /* Don't dereference any memory if the array is empty. */ | ||
| 49 | return NULL; | ||
| 50 | } | ||
| 51 | 54 | ||
| 52 | while ((bits = __insn_seqb(v, goal)) == 0) { | 55 | while ((bits = __insn_seqb(v, goal)) == 0) { |
| 53 | if (__builtin_expect(p == last_word_ptr, 0)) { | 56 | if (__builtin_expect(p == last_word_ptr, 0)) { |
