/src/simdjson/include/simdjson/icelake/bitmanipulation.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef SIMDJSON_ICELAKE_BITMANIPULATION_H |
2 | | #define SIMDJSON_ICELAKE_BITMANIPULATION_H |
3 | | |
4 | | #ifndef SIMDJSON_CONDITIONAL_INCLUDE |
5 | | #include "simdjson/icelake/base.h" |
6 | | #include "simdjson/icelake/intrinsics.h" |
7 | | #endif // SIMDJSON_CONDITIONAL_INCLUDE |
8 | | |
9 | | namespace simdjson { |
10 | | namespace icelake { |
11 | | namespace { |
12 | | |
13 | | // We sometimes call trailing_zero on inputs that are zero, |
14 | | // but the algorithms do not end up using the returned value. |
15 | | // Sadly, sanitizers are not smart enough to figure it out. |
16 | | SIMDJSON_NO_SANITIZE_UNDEFINED |
17 | | // This function can be used safely even if not all bytes have been |
18 | | // initialized. |
19 | | // See issue https://github.com/simdjson/simdjson/issues/1965 |
20 | | SIMDJSON_NO_SANITIZE_MEMORY |
21 | 0 | simdjson_inline int trailing_zeroes(uint64_t input_num) { |
22 | | #if SIMDJSON_REGULAR_VISUAL_STUDIO |
23 | | return (int)_tzcnt_u64(input_num); |
24 | | #else // SIMDJSON_REGULAR_VISUAL_STUDIO |
25 | | //////// |
26 | | // You might expect the next line to be equivalent to |
27 | | // return (int)_tzcnt_u64(input_num); |
28 | | // but the generated code differs and might be less efficient? |
29 | | //////// |
30 | 0 | return __builtin_ctzll(input_num); |
31 | 0 | #endif // SIMDJSON_REGULAR_VISUAL_STUDIO |
32 | 0 | } |
33 | | |
34 | | /* result might be undefined when input_num is zero */ |
35 | 0 | simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) { |
36 | 0 | return _blsr_u64(input_num); |
37 | 0 | } |
38 | | |
39 | | /* result might be undefined when input_num is zero */ |
40 | 0 | simdjson_inline int leading_zeroes(uint64_t input_num) { |
41 | 0 | return int(_lzcnt_u64(input_num)); |
42 | 0 | } |
43 | | |
44 | | #if SIMDJSON_REGULAR_VISUAL_STUDIO |
45 | | simdjson_inline unsigned __int64 count_ones(uint64_t input_num) { |
46 | | // note: we do not support legacy 32-bit Windows |
47 | | return __popcnt64(input_num);// Visual Studio wants two underscores |
48 | | } |
49 | | #else |
50 | 0 | simdjson_inline long long int count_ones(uint64_t input_num) { |
51 | 0 | return _popcnt64(input_num); |
52 | 0 | } |
53 | | #endif |
54 | | |
55 | | simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, |
56 | 0 | uint64_t *result) { |
57 | 0 | #if SIMDJSON_REGULAR_VISUAL_STUDIO |
58 | 0 | return _addcarry_u64(0, value1, value2, |
59 | 0 | reinterpret_cast<unsigned __int64 *>(result)); |
60 | 0 | #else |
61 | 0 | return __builtin_uaddll_overflow(value1, value2, |
62 | 0 | reinterpret_cast<unsigned long long *>(result)); |
63 | 0 | #endif |
64 | 0 | } |
65 | | |
66 | | } // unnamed namespace |
67 | | } // namespace icelake |
68 | | } // namespace simdjson |
69 | | |
70 | | #endif // SIMDJSON_ICELAKE_BITMANIPULATION_H |