mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
40b414d184
* add Windows ARM64EC support * add ARM64EC to vs17-arm-ci workflow
60 lines
2.1 KiB
C++
60 lines
2.1 KiB
C++
#ifndef SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
|
|
#define SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
|
|
|
|
#include "simdjson/westmere/base.h"
|
|
#include "simdjson/westmere/intrinsics.h"
|
|
|
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
|
#include "simdjson/internal/numberparsing_tables.h"
|
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
|
|
|
namespace simdjson {
|
|
namespace westmere {
|
|
namespace numberparsing {
|
|
|
|
/** @private */
|
|
static simdjson_inline uint32_t parse_eight_digits_unrolled(const uint8_t *chars) {
|
|
// this actually computes *16* values so we are being wasteful.
|
|
const __m128i ascii0 = _mm_set1_epi8('0');
|
|
const __m128i mul_1_10 =
|
|
_mm_setr_epi8(10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1);
|
|
const __m128i mul_1_100 = _mm_setr_epi16(100, 1, 100, 1, 100, 1, 100, 1);
|
|
const __m128i mul_1_10000 =
|
|
_mm_setr_epi16(10000, 1, 10000, 1, 10000, 1, 10000, 1);
|
|
const __m128i input = _mm_sub_epi8(
|
|
_mm_loadu_si128(reinterpret_cast<const __m128i *>(chars)), ascii0);
|
|
const __m128i t1 = _mm_maddubs_epi16(input, mul_1_10);
|
|
const __m128i t2 = _mm_madd_epi16(t1, mul_1_100);
|
|
const __m128i t3 = _mm_packus_epi32(t2, t2);
|
|
const __m128i t4 = _mm_madd_epi16(t3, mul_1_10000);
|
|
return _mm_cvtsi128_si32(
|
|
t4); // only captures the sum of the first 8 digits, drop the rest
|
|
}
|
|
|
|
/** @private */
|
|
simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t value2) {
|
|
internal::value128 answer;
|
|
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
|
|
#if SIMDJSON_IS_ARM64
|
|
// ARM64 has native support for 64-bit multiplications, no need to emultate
|
|
answer.high = __umulh(value1, value2);
|
|
answer.low = value1 * value2;
|
|
#else
|
|
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
|
|
#endif // SIMDJSON_IS_ARM64
|
|
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
|
|
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
|
|
answer.low = uint64_t(r);
|
|
answer.high = uint64_t(r >> 64);
|
|
#endif
|
|
return answer;
|
|
}
|
|
|
|
} // namespace numberparsing
|
|
} // namespace westmere
|
|
} // namespace simdjson
|
|
|
|
#define SIMDJSON_SWAR_NUMBER_PARSING 1
|
|
|
|
#endif // SIMDJSON_WESTMERE_NUMBERPARSING_DEFS_H
|