diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-30 15:39:02 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-30 15:39:02 +0000 |
commit | 4cf460a7bb258d3d61414d2f74df4c0f83c6a3af (patch) | |
tree | da5b3754ad1910426086dc4a7f4dd7cca7b65b92 /string.c | |
parent | c19c8ef4aedadd52b9354188f36aa590ec319200 (diff) |
* string.c (search_nonascii): unroll and use ntz
* configure.in (__builtin_ctz): check.
* configure.in (__builtin_ctzll): check.
* internal.h (rb_popcount32): defined for ntz_int32.
it can use __builtin_popcount but this function is not used on
GCC environment because it uses __builtin_ctz.
When another function uses this, using __builtin_popcount
should be re-considered.
* internal.h (rb_popcount64): ditto.
* internal.h (ntz_int32): defined for ntz_intptr.
* internal.h (ntz_int64): defined for ntz_intptr.
* internal.h (ntz_intptr): defined as ntz for uintptr_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54854 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 60 |
1 files changed, 37 insertions, 23 deletions
@@ -427,32 +427,46 @@ search_nonascii(const char *p, const char *e) #elif SIZEOF_VOIDP == 4 # define NONASCII_MASK 0x80808080UL #endif -#ifdef NONASCII_MASK - if ((int)SIZEOF_VOIDP * 2 < e - p) { - const uintptr_t *s, *t; - const uintptr_t lowbits = SIZEOF_VOIDP - 1; - s = (const uintptr_t*)(~lowbits & ((uintptr_t)p + lowbits)); - while (p < (const char *)s) { - if (!ISASCII(*p)) - return p; - p++; - } - t = (const uintptr_t*)(~lowbits & (uintptr_t)e); - while (s < t) { - if (*s & NONASCII_MASK) { - t = s; - break; - } - s++; - } - p = (const char *)t; + +#if !UNALIGNED_WORD_ACCESS + if (e - p > SIZEOF_VOIDP) { + switch (8 - (uintptr_t)p % 8) { +#if SIZEOF_VOIDP > 4 + case 7: if (*p&0x80) return p; p++; + case 6: if (*p&0x80) return p; p++; + case 5: if (*p&0x80) return p; p++; + case 4: if (*p&0x80) return p; p++; +#endif + case 3: if (*p&0x80) return p; p++; + case 2: if (*p&0x80) return p; p++; + case 1: if (*p&0x80) return p; p++; + } } #endif - while (p < e) { - if (!ISASCII(*p)) - return p; - p++; + + { + const uintptr_t *s = (const uintptr_t *)p; + const uintptr_t *t = (const uintptr_t *)(e - (SIZEOF_VOIDP-1)); + for (;s < t; s++) { + if (*s & NONASCII_MASK) { + return (const char *)s + (ntz_intptr(*s&NONASCII_MASK)>>3); + } + } + p = (const char *)s; } + + switch ((e - p) % SIZEOF_VOIDP) { +#if SIZEOF_VOIDP > 4 + case 7: if (*p&0x80) return p; p++; + case 6: if (*p&0x80) return p; p++; + case 5: if (*p&0x80) return p; p++; + case 4: if (*p&0x80) return p; p++; +#endif + case 3: if (*p&0x80) return p; p++; + case 2: if (*p&0x80) return p; p++; + case 1: if (*p&0x80) return p; + } + return NULL; } |