simdjson  3.11.0
Ridiculously Fast JSON
numberparsing_defs.h
1 #ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
2 #define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
3 
4 #include "simdjson/westmere/base.h"
5 #include "simdjson/westmere/intrinsics.h"
6 
7 #ifndef SIMDJSON_CONDITIONAL_INCLUDE
8 #include "simdjson/internal/numberparsing_tables.h"
9 #endif // SIMDJSON_CONDITIONAL_INCLUDE
10 
11 namespace simdjson {
12 namespace westmere {
13 namespace numberparsing {
14 
16 static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
17  // this actually computes *16* values so we are being wasteful.
18  const __m128i ascii0 = _mm_set1_epi8('0');
19  const __m128i mul_1_10 =
20  _mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1);
21  const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1);
22  const __m128i mul_1_10000 =
23  _mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1);
24  const __m128i input = _mm_sub_epi8(
25  _mm_loadu_si128(reinterpret_cast<const __m128i *>(chars)), ascii0);
26  const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10);
27  const __m128i t2 = _mm_madd_epi16(t1, mul_1_100);
28  const __m128i t3 = _mm_packus_epi32(t2, t2);
29  const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000);
30  return _mm_cvtsi128_si32(
31  t4); // only captures the sum of the first 8 digits, drop the rest
32 }
33 
35 simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) {
36  internal::value128 answer;
37 #if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
38 #if SIMDJSON_IS_ARM64
39  // ARM64 has native support for 64-bit multiplications, no need to emultate
40  answer.high = __umulh(value1, value2);
41  answer.low = value1 * value2;
42 #else
43  answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
44 #endif // SIMDJSON_IS_ARM64
45 #else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
46  __uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
47  answer.low = uint64_t(r);
48  answer.high = uint64_t(r >> 64);
49 #endif
50  return answer;
51 }
52 
53 } // namespace numberparsing
54 } // namespace westmere
55 } // namespace simdjson
56 
57 #define SIMDJSON_SWAR_NUMBER_PARSING 1
58 
59 #endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
The top level simdjson namespace, containing everything the library provides.
Definition: base.h:8