[PATCH] memchr: scan word at a time when not on __GNUC__
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 11 Sep 2023 10:00:31 UTC
---
lib/libc/string/memchr.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/lib/libc/string/memchr.c b/lib/libc/string/memchr.c
index 10df015c5b64..d83fb08f7221 100644
--- a/lib/libc/string/memchr.c
+++ b/lib/libc/string/memchr.c
@@ -26,6 +26,7 @@
#include <limits.h>
#include <stdint.h>
#include <string.h>
+#ifndef __GNUC__
+#include <sys/endian.h>
+#endif
#define SS (sizeof(size_t))
#define ALIGN (sizeof(size_t) - 1)
@@ -33,25 +34,38 @@
#define HIGHS (ONES * (UCHAR_MAX / 2 + 1))
#define HASZERO(x) (((x)-ONES) & ~(x)&HIGHS)
+#ifndef __GNUC__
+# if _BYTE_ORDER == _LITTLE_ENDIAN
+# define TOWORD(x) ((word)x[7] << 56 | (word)x[6] << 48 | (word)x[5] << 40 | (word)x[4] << 32 | (word)x[3] << 24 | (word)x[2] << 16 | (word)x[1] << 8 | (word)x[0])
+# else
+# define TOWORD(x) ((word)x[7] >> 56 | (word)x[6] >> 48 | (word)x[5] >> 40 | (word)x[4] >> 32 | (word)x[3] >> 24 | (word)x[2] >> 16 | (word)x[1] >> 8 | (word)x[0])
+# endif
+#endif
+
void *
memchr(const void *src, int c, size_t n)
{
const unsigned char *s = src;
c = (unsigned char)c;
-#ifdef __GNUC__
for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--)
;
if (n && *s != c) {
+ size_t k = ONES * c;
+#ifdef __GNUC__
typedef size_t __attribute__((__may_alias__)) word;
const word *w;
- size_t k = ONES * c;
for (w = (const void *)s; n >= SS && !HASZERO(*w ^ k);
w++, n -= SS)
;
s = (const void *)w;
- }
+#else
+ typedef size_t word;
+ word w = TOWORD(s);
+ for (; n >= SS && !HASZERO(w ^ k);
+ w = TOWORD(s), s += SS, n -= SS)
+ ;
#endif
- for (; n && *s != c; s++, n--)
- ;
+ }
return n ? (void *)s : 0;
}
--
2.42.0