diff options
| author | Xinchen Hui <laruence@gmail.com> | 2020-04-28 11:11:58 +0800 |
|---|---|---|
| committer | Xinchen Hui <laruence@gmail.com> | 2020-04-28 11:11:58 +0800 |
| commit | 6e2c1d7234cb17c312268191db4958d7db3e6424 (patch) | |
| tree | b3d0f6d3004cb34d24e8bf443d53b1e02dcffc4d /Zend/zend_operators.c | |
| parent | 7ce8c5ad892b8ce65426d7a8a6cf7376d56c98ee (diff) | |
| parent | 11491b63f800d150a00e9855f3a0a49e7bca50f7 (diff) | |
| download | php-git-6e2c1d7234cb17c312268191db4958d7db3e6424.tar.gz | |
Merge branch 'sse2_strtolower' of https://github.com/laruence/php-src
* 'sse2_strtolower' of https://github.com/laruence/php-src:
Also zend_str_tolower_dup_ex
Remove unnecessary register qualifier
SSE2 str_tolower
Diffstat (limited to 'Zend/zend_operators.c')
| -rw-r--r-- | Zend/zend_operators.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 7f9b804f1e..e420dd962e 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -30,6 +30,10 @@ #include "zend_exceptions.h" #include "zend_closures.h" +#ifdef __SSE2__ +#include <emmintrin.h> +#endif + #if ZEND_USE_TOLOWER_L #include <locale.h> static _locale_t current_locale = NULL; @@ -2456,17 +2460,38 @@ ZEND_API void zend_update_current_locale(void) /* {{{ */ /* }}} */ #endif -ZEND_API char* ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */ -{ - register unsigned char *str = (unsigned char*)source; - register unsigned char *result = (unsigned char*)dest; - register unsigned char *end = str + length; - - while (str < end) { - *result++ = zend_tolower_ascii(*str++); +static zend_always_inline void zend_str_tolower_impl(char *dest, const char *str, size_t length) /* {{{ */ { + register unsigned char *p = (unsigned char*)str; + register unsigned char *q = (unsigned char*)dest; + unsigned char *end = p + length; +#ifdef __SSE2__ + if (length >= 16) { + const __m128i _A = _mm_set1_epi8('A' - 1); + const __m128i Z_ = _mm_set1_epi8('Z' + 1); + const __m128i delta = _mm_set1_epi8('a' - 'A'); + do { + __m128i op = _mm_loadu_si128((__m128i*)p); + __m128i gt = _mm_cmpgt_epi8(op, _A); + __m128i lt = _mm_cmplt_epi8(op, Z_); + __m128i mingle = _mm_and_si128(gt, lt); + __m128i add = _mm_and_si128(mingle, delta); + __m128i lower = _mm_add_epi8(op, add); + _mm_storeu_si128((__m128i *)q, lower); + p += 16; + q += 16; + } while (p + 16 <= end); } - *result = '\0'; +#endif + while (p < end) { + *q++ = zend_tolower_ascii(*p++); + } +} +/* }}} */ +ZEND_API char* ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */ +{ + zend_str_tolower_impl(dest, source, length); + dest[length] = '\0'; return dest; } /* }}} */ @@ -2479,13 +2504,7 @@ ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t len ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length) /* {{{ */ { - register unsigned char *p = (unsigned char*)str; - register unsigned char *end = p + length; - - while (p < end) { - *p = zend_tolower_ascii(*p); - p++; - } + zend_str_tolower_impl(str, (const char*)str, length); } /* }}} */ @@ -2503,12 +2522,8 @@ ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t memcpy(res, source, p - (const unsigned char*)source); } r = (unsigned char*)p + (res - source); - while (p < end) { - *r = zend_tolower_ascii(*p); - p++; - r++; - } - *r = '\0'; + zend_str_tolower_impl((char *)r, (const char*)p, end - p); + res[length] = '\0'; return res; } p++; @@ -2521,7 +2536,6 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, int { register unsigned char *p = (unsigned char*)ZSTR_VAL(str); register unsigned char *end = p + ZSTR_LEN(str); - while (p < end) { if (*p != zend_tolower_ascii(*p)) { zend_string *res = zend_string_alloc(ZSTR_LEN(str), persistent); @@ -2531,12 +2545,8 @@ ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower_ex(zend_string *str, int memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*)ZSTR_VAL(str)); } r = p + (ZSTR_VAL(res) - ZSTR_VAL(str)); - while (p < end) { - *r = zend_tolower_ascii(*p); - p++; - r++; - } - *r = '\0'; + zend_str_tolower_impl((char*)r, (const char*)p, end - p); + ZSTR_VAL(res)[ZSTR_LEN(res)] = '\0'; return res; } p++; |
