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
19void found_invalid_number(const uint8_t *buf);
20void found_integer(int64_t result, const uint8_t *buf);
21void found_unsigned_integer(uint64_t result, const uint8_t *buf);
22void found_float(double result, const uint8_t *buf);
23#endif
24
25
26TARGET_WESTMERE
27namespace simdjson::westmere {
28static 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
51UNTARGET_REGION
52
53
54
55#endif // IS_X86_64
56#endif // SIMDJSON_WESTMERE_NUMBERPARSING_H
57