1 | #ifndef SIMDJSON_WESTMERE_NUMBERPARSING_H |
2 | #define SIMDJSON_WESTMERE_NUMBERPARSING_H |
3 | |
4 | #ifdef IS_X86_64 |
5 | |
6 | #include "simdjson/common_defs.h" |
7 | #include "simdjson/portability.h" |
8 | #include "westmere/intrinsics.h" |
9 | #include "simdjson/common_defs.h" |
10 | #include "simdjson/portability.h" |
11 | #include "westmere/intrinsics.h" |
12 | #include "simdjson/parsedjson.h" |
13 | #include "jsoncharutils.h" |
14 | #include <cmath> |
15 | #include <limits> |
16 | |
17 | |
18 | #ifdef JSON_TEST_NUMBERS // for unit testing |
19 | void found_invalid_number(const uint8_t *buf); |
20 | void found_integer(int64_t result, const uint8_t *buf); |
21 | void found_unsigned_integer(uint64_t result, const uint8_t *buf); |
22 | void found_float(double result, const uint8_t *buf); |
23 | #endif |
24 | |
25 | |
26 | TARGET_WESTMERE |
27 | namespace simdjson::westmere { |
28 | static inline uint32_t parse_eight_digits_unrolled(const char *chars) { |
29 | // this actually computes *16* values so we are being wasteful. |
30 | const __m128i ascii0 = _mm_set1_epi8('0'); |
31 | const __m128i mul_1_10 = |
32 | _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1); |
33 | const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1); |
34 | const __m128i mul_1_10000 = |
35 | _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1); |
36 | const __m128i input = _mm_sub_epi8( |
37 | _mm_loadu_si128(reinterpret_cast<const __m128i *>(chars)), ascii0); |
38 | const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10); |
39 | const __m128i t2 = _mm_madd_epi16(t1, mul_1_100); |
40 | const __m128i t3 = _mm_packus_epi32(t2, t2); |
41 | const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000); |
42 | return _mm_cvtsi128_si32( |
43 | t4); // only captures the sum of the first 8 digits, drop the rest |
44 | } |
45 | |
46 | #define SWAR_NUMBER_PARSING |
47 | |
48 | #include "generic/numberparsing.h" |
49 | |
50 | } // namespace simdjson::westmere |
51 | UNTARGET_REGION |
52 | |
53 | |
54 | |
55 | #endif // IS_X86_64 |
56 | #endif // SIMDJSON_WESTMERE_NUMBERPARSING_H |
57 | |