summaryrefslogtreecommitdiffstats
path: root/src/bfstd.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2025-02-13 15:27:54 -0500
committerTavian Barnes <tavianator@tavianator.com>2025-02-13 15:27:54 -0500
commitbaa45ab5393b780939de6721a88962fd2293b121 (patch)
tree5da9420fdfd1597d71fb9ce4ccfa5fd81bf947ac /src/bfstd.c
parent690a06a5cef8ef506e52d274965e376d6ea865be (diff)
downloadbfs-baa45ab5393b780939de6721a88962fd2293b121.tar.xz
bfstd: Use load8_leu*() for asciinlen()
Diffstat (limited to 'src/bfstd.c')
-rw-r--r--src/bfstd.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/src/bfstd.c b/src/bfstd.c
index 738c956..f2938ad 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -780,35 +780,31 @@ size_t asciilen(const char *str) {
}
size_t asciinlen(const char *str, size_t n) {
+ const unsigned char *ustr = (const unsigned char *)str;
size_t i = 0;
-#if SIZE_WIDTH % 8 == 0
// Word-at-a-time isascii()
- for (size_t word; i + sizeof(word) <= n; i += sizeof(word)) {
- memcpy(&word, str + i, sizeof(word));
-
- const size_t mask = (SIZE_MAX / 0xFF) << 7; // 0x808080...
- word &= mask;
- if (!word) {
- continue;
- }
-
-#if ENDIAN_NATIVE == ENDIAN_BIG
- word = bswap(word);
-#elif ENDIAN_NATIVE != ENDIAN_LITTLE
- break;
+#define CHUNK(n) CHUNK_(uint##n##_t, load8_leu##n)
+#define CHUNK_(type, load8) \
+ while (n - i >= sizeof(type)) { \
+ type word = load8(ustr + i); \
+ type mask = (((type)-1) / 0xFF) << 7; /* 0x808080.. */ \
+ word &= mask; \
+ i += trailing_zeros(word) / 8; \
+ if (word) { \
+ return i; \
+ } \
+ }
+
+#if SIZE_WIDTH >= 64
+ CHUNK(64);
#endif
+ CHUNK(32);
+ CHUNK(16);
+ CHUNK(8);
- size_t first = trailing_zeros(word) / 8;
- return i + first;
- }
-#endif
-
- for (; i < n; ++i) {
- if (!xisascii(str[i])) {
- break;
- }
- }
+#undef CHUNK_
+#undef CHUNK
return i;
}