3232#include "bcmath.h"
3333#include "convert.h"
3434#include "private.h"
35+ #include "simd.h"
3536#include <stdbool.h>
3637#include <stddef.h>
37- #ifdef __SSE2__
38- # include <emmintrin.h>
39- #endif
4038
4139/* Convert strings to bc numbers. Base 10 only.*/
42- static const char * bc_count_digits (const char * str , const char * end )
40+ static inline const char * bc_count_digits (const char * str , const char * end )
4341{
4442 /* Process in bulk */
45- #ifdef __SSE2__
46- const __m128i offset = _mm_set1_epi8 ((signed char ) (SCHAR_MIN - '0' ));
43+ #ifdef HAVE_BC_SIMD_128
44+ const bc_simd_128_t offset = bc_simd_set_8x16 ((signed char ) (SCHAR_MIN - '0' ));
4745 /* we use the less than comparator, so add 1 */
48- const __m128i threshold = _mm_set1_epi8 (SCHAR_MIN + ('9' + 1 - '0' ));
46+ const bc_simd_128_t threshold = bc_simd_set_8x16 (SCHAR_MIN + ('9' + 1 - '0' ));
4947
50- while (str + sizeof (__m128i ) <= end ) {
51- __m128i bytes = _mm_loadu_si128 ((const __m128i * ) str );
48+ while (str + sizeof (bc_simd_128_t ) <= end ) {
49+ bc_simd_128_t bytes = bc_simd_load_8x16 ((const bc_simd_128_t * ) str );
5250 /* Wrapping-add the offset to the bytes, such that all bytes below '0' are positive and others are negative.
5351 * More specifically, '0' will be -128 and '9' will be -119. */
54- bytes = _mm_add_epi8 (bytes , offset );
52+ bytes = bc_simd_add_8x16 (bytes , offset );
5553 /* Now mark all bytes that are <= '9', i.e. <= -119, i.e. < -118, i.e. the threshold. */
56- bytes = _mm_cmplt_epi8 (bytes , threshold );
54+ bytes = bc_simd_cmplt_8x16 (bytes , threshold );
5755
58- int mask = _mm_movemask_epi8 (bytes );
56+ int mask = bc_simd_movemask_8x16 (bytes );
5957 if (mask != 0xffff ) {
6058 /* At least one of the bytes is not within range. Move to the first offending byte. */
6159#ifdef PHP_HAVE_BUILTIN_CTZL
@@ -65,7 +63,7 @@ static const char *bc_count_digits(const char *str, const char *end)
6563#endif
6664 }
6765
68- str += sizeof (__m128i );
66+ str += sizeof (bc_simd_128_t );
6967 }
7068#endif
7169
@@ -79,19 +77,19 @@ static const char *bc_count_digits(const char *str, const char *end)
7977static inline const char * bc_skip_zero_reverse (const char * scanner , const char * stop )
8078{
8179 /* Check in bulk */
82- #ifdef __SSE2__
83- const __m128i c_zero_repeat = _mm_set1_epi8 ('0' );
84- while (scanner - sizeof (__m128i ) >= stop ) {
85- scanner -= sizeof (__m128i );
86- __m128i bytes = _mm_loadu_si128 ((const __m128i * ) scanner );
80+ #ifdef HAVE_BC_SIMD_128
81+ const bc_simd_128_t c_zero_repeat = bc_simd_set_8x16 ('0' );
82+ while (scanner - sizeof (bc_simd_128_t ) >= stop ) {
83+ scanner -= sizeof (bc_simd_128_t );
84+ bc_simd_128_t bytes = bc_simd_load_8x16 ((const bc_simd_128_t * ) scanner );
8785 /* Checks if all numeric strings are equal to '0'. */
88- bytes = _mm_cmpeq_epi8 (bytes , c_zero_repeat );
86+ bytes = bc_simd_cmpeq_8x16 (bytes , c_zero_repeat );
8987
90- int mask = _mm_movemask_epi8 (bytes );
88+ int mask = bc_simd_movemask_8x16 (bytes );
9189 /* The probability of having 16 trailing 0s in a row is very low, so we use EXPECTED. */
9290 if (EXPECTED (mask != 0xffff )) {
9391 /* Move the pointer back and check each character in loop. */
94- scanner += sizeof (__m128i );
92+ scanner += sizeof (bc_simd_128_t );
9593 break ;
9694 }
9795 }
0 commit comments