1 #ifndef BIGDECIMAL_BITS_H
2 #define BIGDECIMAL_BITS_H
7 #if defined(__x86_64__) && defined(HAVE_X86INTRIN_H)
8 # include <x86intrin.h>
9 #elif defined(_MSC_VER) && defined(HAVE_INTRIN_H)
13 #if defined(_MSC_VER) && defined(__AVX2__)
14 # pragma intrinsic(__lzcnt)
15 # pragma intrinsic(__lzcnt64)
18 #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
19 #define roomof(x, y) (((x) + (y) - 1) / (y))
20 #define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
22 #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
24 (a) == -1 ? (b) < -(max) : \
26 ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
27 ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
30 # define bit_length(x) \
32 (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
33 sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \
34 128 - nlz_int128((uint128_t)(x)))
36 # define bit_length(x) \
38 (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
39 64 - nlz_int64((uint64_t)(x)))
42 static inline unsigned nlz_int32(
uint32_t x);
43 static inline unsigned nlz_int64(
uint64_t x);
45 static inline unsigned nlz_int128(uint128_t x);
48 static inline unsigned int
51 #if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT)
56 return (
unsigned int)__lzcnt(x);
58 #elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32)
59 return (
unsigned int)_lzcnt_u32(x);
61 #elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE)
63 return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
65 #elif __has_builtin(__builtin_clz)
67 return x ? (
unsigned int)__builtin_clz(x) : 32;
72 y = x >> 16;
if (
y) {n -= 16; x =
y;}
73 y = x >> 8;
if (
y) {n -= 8; x =
y;}
74 y = x >> 4;
if (
y) {n -= 4; x =
y;}
75 y = x >> 2;
if (
y) {n -= 2; x =
y;}
76 y = x >> 1;
if (
y) {
return n - 2;}
77 return (
unsigned int)(n - x);
81 static inline unsigned int
84 #if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64)
85 return (
unsigned int)__lzcnt64(x);
87 #elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64)
88 return (
unsigned int)_lzcnt_u64(x);
90 #elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64)
92 return _BitScanReverse64(&r, x) ? (63u - (
unsigned int)r) : 64;
94 #elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc))
98 else if (
sizeof(
long) *
CHAR_BIT == 64) {
99 return (
unsigned int)__builtin_clzl((
unsigned long)x);
101 else if (
sizeof(
long long) *
CHAR_BIT == 64) {
102 return (
unsigned int)__builtin_clzll((
unsigned long long)x);
106 __builtin_unreachable();
112 y = x >> 32;
if (
y) {n -= 32; x =
y;}
113 y = x >> 16;
if (
y) {n -= 16; x =
y;}
114 y = x >> 8;
if (
y) {n -= 8; x =
y;}
115 y = x >> 4;
if (
y) {n -= 4; x =
y;}
116 y = x >> 2;
if (
y) {n -= 2; x =
y;}
117 y = x >> 1;
if (
y) {
return n - 2;}
118 return (
unsigned int)(n - x);
123 #ifdef HAVE_UINT128_T
124 static inline unsigned int
125 nlz_int128(uint128_t x)
133 return (
unsigned int)nlz_int64(x) + 64;
136 return (
unsigned int)nlz_int64(
y);