|
30 | 30 | #include <stdint.h> /* for uintptr_t */ |
31 | 31 | #include "internal/compilers.h" /* for MSC_VERSION_SINCE */ |
32 | 32 |
|
33 | | -#if defined(_MSC_VER) |
| 33 | +#ifdef _MSC_VER |
34 | 34 | # include <stdlib.h> /* for _byteswap_uint64 */ |
35 | 35 | #endif |
36 | 36 |
|
|
57 | 57 | # pragma intrinsic(_rotl64) |
58 | 58 | # pragma intrinsic(_rotr64) |
59 | 59 | # endif |
60 | | -#endif |
61 | | - |
62 | | -#if defined(_MSC_VER) |
63 | 60 | # pragma intrinsic(_BitScanForward) |
64 | 61 | # pragma intrinsic(_BitScanReverse) |
65 | 62 | # ifdef _WIN64 |
|
90 | 87 |
|
91 | 88 | #define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0) |
92 | 89 |
|
| 90 | +#ifndef MUL_OVERFLOW_SIGNED_INTEGER_P |
93 | 91 | #if __has_builtin(__builtin_mul_overflow_p) |
94 | 92 | # define MUL_OVERFLOW_P(a, b) \ |
95 | 93 | __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0) |
|
118 | 116 | MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX) |
119 | 117 | #endif |
120 | 118 |
|
121 | | -#ifdef MUL_OVERFLOW_P |
| 119 | +#if defined(MUL_OVERFLOW_P) && defined(USE___BUILTIN_MUL_OVERFLOW_LONG_LONG) |
122 | 120 | # define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b) |
| 121 | +#else |
| 122 | +# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX) |
| 123 | +#endif |
| 124 | + |
| 125 | +#ifdef MUL_OVERFLOW_P |
123 | 126 | # define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b) |
124 | 127 | # define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b) |
125 | 128 | #else |
126 | | -# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX) |
127 | 129 | # define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX) |
128 | 130 | # define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX) |
129 | 131 | #endif |
| 132 | +#endif |
| 133 | + |
| 134 | +#ifndef ADD_OVERFLOW_SIGNED_INTEGER_P |
| 135 | +#if __has_builtin(__builtin_add_overflow_p) |
| 136 | +# define ADD_OVERFLOW_P(a, b) \ |
| 137 | + __builtin_add_overflow_p((a), (b), (__typeof__(a * b))0) |
| 138 | +#elif __has_builtin(__builtin_add_overflow) |
| 139 | +# define ADD_OVERFLOW_P(a, b) \ |
| 140 | + __extension__ ({ __typeof__(a) c; __builtin_add_overflow((a), (b), &c); }) |
| 141 | +#endif |
| 142 | + |
| 143 | +#define ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ |
| 144 | + (a) > 0 ? (b) > (max) - (a) : (b) < (min) - (a)) |
| 145 | + |
| 146 | +#if __has_builtin(__builtin_add_overflow_p) |
| 147 | +/* __builtin_add_overflow_p can take bitfield */ |
| 148 | +/* and GCC permits bitfields for integers other than int */ |
| 149 | +# define ADD_OVERFLOW_FIXNUM_P(a, b) \ |
| 150 | + __extension__ ({ \ |
| 151 | + struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \ |
| 152 | + __builtin_add_overflow_p((a), (b), c.fixnum); \ |
| 153 | + }) |
| 154 | +#else |
| 155 | +# define ADD_OVERFLOW_FIXNUM_P(a, b) \ |
| 156 | + ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX) |
| 157 | +#endif |
| 158 | + |
| 159 | +#if defined(ADD_OVERFLOW_P) && defined(USE___BUILTIN_ADD_OVERFLOW_LONG_LONG) |
| 160 | +# define ADD_OVERFLOW_LONG_LONG_P(a, b) ADD_OVERFLOW_P(a, b) |
| 161 | +#else |
| 162 | +# define ADD_OVERFLOW_LONG_LONG_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX) |
| 163 | +#endif |
| 164 | + |
| 165 | +#ifdef ADD_OVERFLOW_P |
| 166 | +# define ADD_OVERFLOW_LONG_P(a, b) ADD_OVERFLOW_P(a, b) |
| 167 | +# define ADD_OVERFLOW_INT_P(a, b) ADD_OVERFLOW_P(a, b) |
| 168 | +#else |
| 169 | +# define ADD_OVERFLOW_LONG_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX) |
| 170 | +# define ADD_OVERFLOW_INT_P(a, b) ADD_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX) |
| 171 | +#endif |
| 172 | +#endif |
| 173 | + |
| 174 | +#ifndef SUB_OVERFLOW_SIGNED_INTEGER_P |
| 175 | +#if __has_builtin(__builtin_sub_overflow_p) |
| 176 | +# define SUB_OVERFLOW_P(a, b) \ |
| 177 | + __builtin_sub_overflow_p((a), (b), (__typeof__(a * b))0) |
| 178 | +#elif __has_builtin(__builtin_sub_overflow) |
| 179 | +# define SUB_OVERFLOW_P(a, b) \ |
| 180 | + __extension__ ({ __typeof__(a) c; __builtin_sub_overflow((a), (b), &c); }) |
| 181 | +#endif |
| 182 | + |
| 183 | +#define SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ |
| 184 | + (b) > 0 ? (a) < (min) + (b) : (a) > (max) + (b)) |
| 185 | + |
| 186 | +#if __has_builtin(__builtin_sub_overflow_p) |
| 187 | +/* __builtin_sub_overflow_p can take bitfield */ |
| 188 | +/* and GCC permits bitfields for integers other than int */ |
| 189 | +# define SUB_OVERFLOW_FIXNUM_P(a, b) \ |
| 190 | + __extension__ ({ \ |
| 191 | + struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \ |
| 192 | + __builtin_sub_overflow_p((a), (b), c.fixnum); \ |
| 193 | + }) |
| 194 | +#else |
| 195 | +# define SUB_OVERFLOW_FIXNUM_P(a, b) \ |
| 196 | + SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX) |
| 197 | +#endif |
| 198 | + |
| 199 | +#if defined(SUB_OVERFLOW_P) && defined(USE___BUILTIN_SUB_OVERFLOW_LONG_LONG) |
| 200 | +# define SUB_OVERFLOW_LONG_LONG_P(a, b) SUB_OVERFLOW_P(a, b) |
| 201 | +#else |
| 202 | +# define SUB_OVERFLOW_LONG_LONG_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX) |
| 203 | +#endif |
| 204 | + |
| 205 | +#ifdef SUB_OVERFLOW_P |
| 206 | +# define SUB_OVERFLOW_LONG_P(a, b) SUB_OVERFLOW_P(a, b) |
| 207 | +# define SUB_OVERFLOW_INT_P(a, b) SUB_OVERFLOW_P(a, b) |
| 208 | +#else |
| 209 | +# define SUB_OVERFLOW_LONG_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX) |
| 210 | +# define SUB_OVERFLOW_INT_P(a, b) SUB_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX) |
| 211 | +#endif |
| 212 | +#endif |
130 | 213 |
|
131 | 214 | #ifdef HAVE_UINT128_T |
132 | 215 | # define bit_length(x) \ |
@@ -394,9 +477,9 @@ rb_popcount32(uint32_t x) |
394 | 477 | #else |
395 | 478 | x = (x & 0x55555555) + (x >> 1 & 0x55555555); |
396 | 479 | x = (x & 0x33333333) + (x >> 2 & 0x33333333); |
397 | | - x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f); |
398 | | - x = (x & 0x001f001f) + (x >> 8 & 0x001f001f); |
399 | | - x = (x & 0x0000003f) + (x >>16 & 0x0000003f); |
| 480 | + x = (x & 0x07070707) + (x >> 4 & 0x07070707); |
| 481 | + x = (x & 0x000f000f) + (x >> 8 & 0x000f000f); |
| 482 | + x = (x & 0x0000001f) + (x >>16 & 0x0000001f); |
400 | 483 | return (unsigned int)x; |
401 | 484 |
|
402 | 485 | #endif |
@@ -424,9 +507,9 @@ rb_popcount64(uint64_t x) |
424 | 507 | x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555); |
425 | 508 | x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333); |
426 | 509 | x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707); |
427 | | - x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f); |
428 | | - x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f); |
429 | | - x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f); |
| 510 | + x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f); |
| 511 | + x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f); |
| 512 | + x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f); |
430 | 513 | return (unsigned int)x; |
431 | 514 |
|
432 | 515 | #endif |
|
0 commit comments