32
32
#include "bcmath.h"
33
33
#include "convert.h"
34
34
#include "private.h"
35
+ #include "simd.h"
35
36
#include <stdbool.h>
36
37
#include <stddef.h>
37
- #ifdef __SSE2__
38
- # include <emmintrin.h>
39
- #endif
40
38
41
39
/* Convert strings to bc numbers. Base 10 only.*/
42
40
static const char * bc_count_digits (const char * str , const char * end )
43
41
{
44
42
/* 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' ));
47
45
/* 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' ));
49
47
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 );
52
50
/* Wrapping-add the offset to the bytes, such that all bytes below '0' are positive and others are negative.
53
51
* 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 );
55
53
/* 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 );
57
55
58
- int mask = _mm_movemask_epi8 (bytes );
56
+ int mask = bc_simd_movemask_8x16 (bytes );
59
57
if (mask != 0xffff ) {
60
58
/* At least one of the bytes is not within range. Move to the first offending byte. */
61
59
#ifdef PHP_HAVE_BUILTIN_CTZL
@@ -65,7 +63,7 @@ static const char *bc_count_digits(const char *str, const char *end)
65
63
#endif
66
64
}
67
65
68
- str += sizeof (__m128i );
66
+ str += sizeof (bc_simd_128_t );
69
67
}
70
68
#endif
71
69
@@ -79,19 +77,19 @@ static const char *bc_count_digits(const char *str, const char *end)
79
77
static inline const char * bc_skip_zero_reverse (const char * scanner , const char * stop )
80
78
{
81
79
/* 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 );
87
85
/* 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 );
89
87
90
- int mask = _mm_movemask_epi8 (bytes );
88
+ int mask = bc_simd_movemask_8x16 (bytes );
91
89
/* The probability of having 16 trailing 0s in a row is very low, so we use EXPECTED. */
92
90
if (EXPECTED (mask != 0xffff )) {
93
91
/* Move the pointer back and check each character in loop. */
94
- scanner += sizeof (__m128i );
92
+ scanner += sizeof (bc_simd_128_t );
95
93
break ;
96
94
}
97
95
}
0 commit comments