memchr.h (1462B)
1 2 3 #ifndef FAST_MEMCHR_H 4 #define FAST_MEMCHR_H 5 6 #include <string.h> 7 8 #ifdef __ARM_NEON 9 #define vector_strchr neon_strchr 10 #else 11 #define vector_strchr native_memchr 12 #endif 13 14 #ifdef __ARM_NEON 15 #include <arm_neon.h> 16 static const char *neon_strchr(const char *str, char c, size_t length) { 17 const char* end = str + length; 18 19 // Alignment handling 20 while (str < end && ((size_t)str & 0xF)) { 21 if (*str == c) 22 return str; 23 ++str; 24 } 25 26 uint8x16_t searchChar = vdupq_n_u8(c); 27 28 while (str + 16 <= end) { 29 uint8x16_t chunk = vld1q_u8((const uint8_t*)str); 30 uint8x16_t comparison = vceqq_u8(chunk, searchChar); 31 32 // Check first 64 bits 33 uint64_t result0 = 34 vgetq_lane_u64(vreinterpretq_u64_u8(comparison), 0); 35 36 if (result0) 37 return str + __builtin_ctzll(result0)/8; 38 39 // Check second 64 bits 40 uint64_t result1 = vgetq_lane_u64(vreinterpretq_u64_u8(comparison), 1); 41 if (result1) 42 return str + 8 + __builtin_ctzll(result1)/8; 43 44 str += 16; 45 } 46 47 // Handle remaining unaligned characters 48 for (; str < end; ++str) { 49 if (*str == c) 50 return str; 51 } 52 53 return NULL; 54 } 55 #endif 56 57 static inline const char *native_memchr(const char *str, char c, size_t length) { 58 const void *result = memchr(str, c, length); 59 return (const char *) result; 60 } 61 62 static inline const char *fast_strchr(const char *str, char c, size_t length) 63 { 64 if (length >= 16) { 65 return vector_strchr(str, c, length); 66 } 67 68 return native_memchr(str, c, length); 69 } 70 71 72 #endif // FAST_MEMCHR_H