| 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 | |