zscan 2.0.6 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/ext/extconf.rb +9 -1
  3. data/ext/pack/builtin-27.h +79 -0
  4. data/ext/pack/builtin.h +79 -0
  5. data/ext/pack/internal-27.h +96 -0
  6. data/ext/pack/internal-27/array.h +103 -0
  7. data/ext/pack/internal-27/bignum.h +246 -0
  8. data/ext/pack/internal-27/bits.h +566 -0
  9. data/ext/pack/internal-27/class.h +162 -0
  10. data/ext/pack/internal-27/compar.h +50 -0
  11. data/ext/pack/internal-27/compile.h +32 -0
  12. data/ext/pack/internal-27/compilers.h +108 -0
  13. data/ext/pack/internal-27/complex.h +29 -0
  14. data/ext/pack/internal-27/cont.h +23 -0
  15. data/ext/pack/internal-27/dir.h +17 -0
  16. data/ext/pack/internal-27/enc.h +20 -0
  17. data/ext/pack/internal-27/encoding.h +28 -0
  18. data/ext/pack/internal-27/enum.h +19 -0
  19. data/ext/pack/internal-27/enumerator.h +22 -0
  20. data/ext/pack/internal-27/error.h +129 -0
  21. data/ext/pack/internal-27/eval.h +33 -0
  22. data/ext/pack/internal-27/file.h +39 -0
  23. data/ext/pack/internal-27/fixnum.h +185 -0
  24. data/ext/pack/internal-27/gc.h +153 -0
  25. data/ext/pack/internal-27/hash.h +234 -0
  26. data/ext/pack/internal-27/imemo.h +242 -0
  27. data/ext/pack/internal-27/inits.h +51 -0
  28. data/ext/pack/internal-27/io.h +35 -0
  29. data/ext/pack/internal-27/load.h +19 -0
  30. data/ext/pack/internal-27/loadpath.h +17 -0
  31. data/ext/pack/internal-27/math.h +24 -0
  32. data/ext/pack/internal-27/missing.h +19 -0
  33. data/ext/pack/internal-27/mjit.h +29 -0
  34. data/ext/pack/internal-27/numeric.h +249 -0
  35. data/ext/pack/internal-27/object.h +60 -0
  36. data/ext/pack/internal-27/parse.h +23 -0
  37. data/ext/pack/internal-27/proc.h +32 -0
  38. data/ext/pack/internal-27/process.h +130 -0
  39. data/ext/pack/internal-27/random.h +17 -0
  40. data/ext/pack/internal-27/range.h +37 -0
  41. data/ext/pack/internal-27/rational.h +68 -0
  42. data/ext/pack/internal-27/re.h +29 -0
  43. data/ext/pack/internal-27/sanitizers.h +191 -0
  44. data/ext/pack/internal-27/serial.h +24 -0
  45. data/ext/pack/internal-27/signal.h +22 -0
  46. data/ext/pack/internal-27/static_assert.h +17 -0
  47. data/ext/pack/internal-27/string.h +135 -0
  48. data/ext/pack/internal-27/struct.h +154 -0
  49. data/ext/pack/internal-27/symbol.h +41 -0
  50. data/ext/pack/internal-27/thread.h +52 -0
  51. data/ext/pack/internal-27/time.h +35 -0
  52. data/ext/pack/internal-27/transcode.h +21 -0
  53. data/ext/pack/internal-27/util.h +31 -0
  54. data/ext/pack/internal-27/variable.h +92 -0
  55. data/ext/pack/internal-27/vm.h +127 -0
  56. data/ext/pack/internal-27/warnings.h +17 -0
  57. data/ext/pack/internal.h +57 -2102
  58. data/ext/pack/internal/array.h +103 -0
  59. data/ext/pack/internal/bignum.h +246 -0
  60. data/ext/pack/internal/bits.h +566 -0
  61. data/ext/pack/internal/class.h +162 -0
  62. data/ext/pack/internal/compar.h +50 -0
  63. data/ext/pack/internal/compile.h +32 -0
  64. data/ext/pack/internal/compilers.h +108 -0
  65. data/ext/pack/internal/complex.h +29 -0
  66. data/ext/pack/internal/cont.h +23 -0
  67. data/ext/pack/internal/dir.h +17 -0
  68. data/ext/pack/internal/enc.h +20 -0
  69. data/ext/pack/internal/encoding.h +28 -0
  70. data/ext/pack/internal/enum.h +19 -0
  71. data/ext/pack/internal/enumerator.h +22 -0
  72. data/ext/pack/internal/error.h +129 -0
  73. data/ext/pack/internal/eval.h +33 -0
  74. data/ext/pack/internal/file.h +39 -0
  75. data/ext/pack/internal/fixnum.h +185 -0
  76. data/ext/pack/internal/gc.h +153 -0
  77. data/ext/pack/internal/hash.h +234 -0
  78. data/ext/pack/internal/imemo.h +242 -0
  79. data/ext/pack/internal/inits.h +51 -0
  80. data/ext/pack/internal/io.h +35 -0
  81. data/ext/pack/internal/load.h +19 -0
  82. data/ext/pack/internal/loadpath.h +17 -0
  83. data/ext/pack/internal/math.h +24 -0
  84. data/ext/pack/internal/missing.h +19 -0
  85. data/ext/pack/internal/mjit.h +29 -0
  86. data/ext/pack/internal/numeric.h +249 -0
  87. data/ext/pack/internal/object.h +60 -0
  88. data/ext/pack/internal/parse.h +23 -0
  89. data/ext/pack/internal/proc.h +32 -0
  90. data/ext/pack/internal/process.h +130 -0
  91. data/ext/pack/internal/random.h +17 -0
  92. data/ext/pack/internal/range.h +37 -0
  93. data/ext/pack/internal/rational.h +68 -0
  94. data/ext/pack/internal/re.h +29 -0
  95. data/ext/pack/internal/sanitizers.h +191 -0
  96. data/ext/pack/internal/serial.h +24 -0
  97. data/ext/pack/internal/signal.h +22 -0
  98. data/ext/pack/internal/static_assert.h +17 -0
  99. data/ext/pack/internal/string.h +135 -0
  100. data/ext/pack/internal/struct.h +154 -0
  101. data/ext/pack/internal/symbol.h +41 -0
  102. data/ext/pack/internal/thread.h +52 -0
  103. data/ext/pack/internal/time.h +35 -0
  104. data/ext/pack/internal/transcode.h +21 -0
  105. data/ext/pack/internal/util.h +31 -0
  106. data/ext/pack/internal/variable.h +92 -0
  107. data/ext/pack/internal/vm.h +127 -0
  108. data/ext/pack/internal/warnings.h +17 -0
  109. data/ext/pack/pack-26.c +2 -109
  110. data/ext/pack/pack-27.c +1022 -0
  111. data/ext/pack/pack.c +57 -1047
  112. data/lib/zscan.rb +1 -1
  113. data/zscan.gemspec +1 -1
  114. metadata +109 -3
@@ -0,0 +1,103 @@
1
+ #ifndef INTERNAL_ARRAY_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_ARRAY_H
3
+ /**
4
+ * @file
5
+ * @author Ruby developers <ruby-core@ruby-lang.org>
6
+ * @copyright This file is a part of the programming language Ruby.
7
+ * Permission is hereby granted, to either redistribute and/or
8
+ * modify this file, provided that the conditions mentioned in the
9
+ * file COPYING are met. Consult the file for details.
10
+ * @brief Internal header for Array.
11
+ */
12
+ #include "ruby/internal/config.h"
13
+ #include <stddef.h> /* for size_t */
14
+ #include "internal/static_assert.h" /* for STATIC_ASSERT */
15
+ #include "ruby/internal/stdbool.h" /* for bool */
16
+ #include "ruby/ruby.h" /* for RARRAY_LEN */
17
+
18
+ #ifndef ARRAY_DEBUG
19
+ # define ARRAY_DEBUG (0+RUBY_DEBUG)
20
+ #endif
21
+
22
+ #define RARRAY_PTR_IN_USE_FLAG FL_USER14
23
+
24
+ /* array.c */
25
+ VALUE rb_ary_last(int, const VALUE *, VALUE);
26
+ void rb_ary_set_len(VALUE, long);
27
+ void rb_ary_delete_same(VALUE, VALUE);
28
+ VALUE rb_ary_tmp_new_fill(long capa);
29
+ VALUE rb_ary_at(VALUE, VALUE);
30
+ size_t rb_ary_memsize(VALUE);
31
+ VALUE rb_to_array_type(VALUE obj);
32
+ static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
33
+ static inline bool ARY_PTR_USING_P(VALUE ary);
34
+ static inline void RARY_TRANSIENT_SET(VALUE ary);
35
+ static inline void RARY_TRANSIENT_UNSET(VALUE ary);
36
+
37
+ RUBY_SYMBOL_EXPORT_BEGIN
38
+ /* array.c (export) */
39
+ void rb_ary_detransient(VALUE a);
40
+ VALUE *rb_ary_ptr_use_start(VALUE ary);
41
+ void rb_ary_ptr_use_end(VALUE ary);
42
+ RUBY_SYMBOL_EXPORT_END
43
+
44
+ MJIT_SYMBOL_EXPORT_BEGIN
45
+ VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
46
+ VALUE rb_check_to_array(VALUE ary);
47
+ VALUE rb_ary_behead(VALUE, long);
48
+ VALUE rb_ary_aref1(VALUE ary, VALUE i);
49
+ MJIT_SYMBOL_EXPORT_END
50
+
51
+ static inline VALUE
52
+ rb_ary_entry_internal(VALUE ary, long offset)
53
+ {
54
+ long len = RARRAY_LEN(ary);
55
+ const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
56
+ if (len == 0) return Qnil;
57
+ if (offset < 0) {
58
+ offset += len;
59
+ if (offset < 0) return Qnil;
60
+ }
61
+ else if (len <= offset) {
62
+ return Qnil;
63
+ }
64
+ return ptr[offset];
65
+ }
66
+
67
+ static inline bool
68
+ ARY_PTR_USING_P(VALUE ary)
69
+ {
70
+ return FL_TEST_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
71
+ }
72
+
73
+ static inline void
74
+ RARY_TRANSIENT_SET(VALUE ary)
75
+ {
76
+ #if USE_TRANSIENT_HEAP
77
+ FL_SET_RAW(ary, RARRAY_TRANSIENT_FLAG);
78
+ #endif
79
+ }
80
+
81
+ static inline void
82
+ RARY_TRANSIENT_UNSET(VALUE ary)
83
+ {
84
+ #if USE_TRANSIENT_HEAP
85
+ FL_UNSET_RAW(ary, RARRAY_TRANSIENT_FLAG);
86
+ #endif
87
+ }
88
+
89
+ #undef rb_ary_new_from_args
90
+ #if RBIMPL_HAS_WARNING("-Wgnu-zero-variadic-macro-arguments")
91
+ # /* Skip it; clang -pedantic doesn't like the following */
92
+ #elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO)
93
+ #define rb_ary_new_from_args(n, ...) \
94
+ __extension__ ({ \
95
+ const VALUE args_to_new_ary[] = {__VA_ARGS__}; \
96
+ if (__builtin_constant_p(n)) { \
97
+ STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); \
98
+ } \
99
+ rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); \
100
+ })
101
+ #endif
102
+
103
+ #endif /* INTERNAL_ARRAY_H */
@@ -0,0 +1,246 @@
1
+ #ifndef INTERNAL_BIGNUM_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_BIGNUM_H
3
+ /**
4
+ * @file
5
+ * @author Ruby developers <ruby-core@ruby-lang.org>
6
+ * @copyright This file is a part of the programming language Ruby.
7
+ * Permission is hereby granted, to either redistribute and/or
8
+ * modify this file, provided that the conditions mentioned in the
9
+ * file COPYING are met. Consult the file for details.
10
+ * @brief Internal header for Bignums.
11
+ */
12
+ #include "ruby/internal/config.h" /* for HAVE_LIBGMP */
13
+ #include <stddef.h> /* for size_t */
14
+
15
+ #ifdef HAVE_SYS_TYPES_H
16
+ # include <sys/types.h> /* for ssize_t (note: on Windows ssize_t is */
17
+ #endif /* `#define`d in ruby/config.h) */
18
+
19
+ #include "ruby/internal/stdbool.h" /* for bool */
20
+ #include "ruby/ruby.h" /* for struct RBasic */
21
+
22
+ #ifndef BDIGIT
23
+ # if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
24
+ # define BDIGIT unsigned int
25
+ # define SIZEOF_BDIGIT SIZEOF_INT
26
+ # define BDIGIT_DBL unsigned LONG_LONG
27
+ # define BDIGIT_DBL_SIGNED LONG_LONG
28
+ # define PRI_BDIGIT_PREFIX ""
29
+ # define PRI_BDIGIT_DBL_PREFIX PRI_LL_PREFIX
30
+ # elif SIZEOF_INT*2 <= SIZEOF_LONG
31
+ # define BDIGIT unsigned int
32
+ # define SIZEOF_BDIGIT SIZEOF_INT
33
+ # define BDIGIT_DBL unsigned long
34
+ # define BDIGIT_DBL_SIGNED long
35
+ # define PRI_BDIGIT_PREFIX ""
36
+ # define PRI_BDIGIT_DBL_PREFIX "l"
37
+ # elif SIZEOF_SHORT*2 <= SIZEOF_LONG
38
+ # define BDIGIT unsigned short
39
+ # define SIZEOF_BDIGIT SIZEOF_SHORT
40
+ # define BDIGIT_DBL unsigned long
41
+ # define BDIGIT_DBL_SIGNED long
42
+ # define PRI_BDIGIT_PREFIX "h"
43
+ # define PRI_BDIGIT_DBL_PREFIX "l"
44
+ # else
45
+ # define BDIGIT unsigned short
46
+ # define SIZEOF_BDIGIT (SIZEOF_LONG/2)
47
+ # define SIZEOF_ACTUAL_BDIGIT SIZEOF_LONG
48
+ # define BDIGIT_DBL unsigned long
49
+ # define BDIGIT_DBL_SIGNED long
50
+ # define PRI_BDIGIT_PREFIX "h"
51
+ # define PRI_BDIGIT_DBL_PREFIX "l"
52
+ # endif
53
+ #endif
54
+
55
+ #ifndef SIZEOF_ACTUAL_BDIGIT
56
+ # define SIZEOF_ACTUAL_BDIGIT SIZEOF_BDIGIT
57
+ #endif
58
+
59
+ #ifdef PRI_BDIGIT_PREFIX
60
+ # define PRIdBDIGIT PRI_BDIGIT_PREFIX"d"
61
+ # define PRIiBDIGIT PRI_BDIGIT_PREFIX"i"
62
+ # define PRIoBDIGIT PRI_BDIGIT_PREFIX"o"
63
+ # define PRIuBDIGIT PRI_BDIGIT_PREFIX"u"
64
+ # define PRIxBDIGIT PRI_BDIGIT_PREFIX"x"
65
+ # define PRIXBDIGIT PRI_BDIGIT_PREFIX"X"
66
+ #endif
67
+
68
+ #ifdef PRI_BDIGIT_DBL_PREFIX
69
+ # define PRIdBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"d"
70
+ # define PRIiBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"i"
71
+ # define PRIoBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"o"
72
+ # define PRIuBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"u"
73
+ # define PRIxBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"x"
74
+ # define PRIXBDIGIT_DBL PRI_BDIGIT_DBL_PREFIX"X"
75
+ #endif
76
+
77
+ #define RBIGNUM(obj) (R_CAST(RBignum)(obj))
78
+ #define BIGNUM_SIGN_BIT FL_USER1
79
+ #define BIGNUM_EMBED_FLAG ((VALUE)FL_USER2)
80
+ #define BIGNUM_EMBED_LEN_NUMBITS 3
81
+ #define BIGNUM_EMBED_LEN_MASK \
82
+ (~(~(VALUE)0U << BIGNUM_EMBED_LEN_NUMBITS) << BIGNUM_EMBED_LEN_SHIFT)
83
+ #define BIGNUM_EMBED_LEN_SHIFT \
84
+ (FL_USHIFT+3) /* bit offset of BIGNUM_EMBED_LEN_MASK */
85
+ #ifndef BIGNUM_EMBED_LEN_MAX
86
+ # if (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT) < (1 << BIGNUM_EMBED_LEN_NUMBITS)-1
87
+ # define BIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*RVALUE_EMBED_LEN_MAX/SIZEOF_ACTUAL_BDIGIT)
88
+ # else
89
+ # define BIGNUM_EMBED_LEN_MAX ((1 << BIGNUM_EMBED_LEN_NUMBITS)-1)
90
+ # endif
91
+ #endif
92
+
93
+ enum rb_int_parse_flags {
94
+ RB_INT_PARSE_SIGN = 0x01,
95
+ RB_INT_PARSE_UNDERSCORE = 0x02,
96
+ RB_INT_PARSE_PREFIX = 0x04,
97
+ RB_INT_PARSE_ALL = 0x07,
98
+ RB_INT_PARSE_DEFAULT = 0x07,
99
+ };
100
+
101
+ struct RBignum {
102
+ struct RBasic basic;
103
+ union {
104
+ struct {
105
+ size_t len;
106
+ BDIGIT *digits;
107
+ } heap;
108
+ BDIGIT ary[BIGNUM_EMBED_LEN_MAX];
109
+ } as;
110
+ };
111
+
112
+ /* bignum.c */
113
+ extern const char ruby_digitmap[];
114
+ double rb_big_fdiv_double(VALUE x, VALUE y);
115
+ VALUE rb_big_uminus(VALUE x);
116
+ VALUE rb_big_hash(VALUE);
117
+ VALUE rb_big_odd_p(VALUE);
118
+ VALUE rb_big_even_p(VALUE);
119
+ size_t rb_big_size(VALUE);
120
+ VALUE rb_integer_float_cmp(VALUE x, VALUE y);
121
+ VALUE rb_integer_float_eq(VALUE x, VALUE y);
122
+ VALUE rb_str_convert_to_inum(VALUE str, int base, int badcheck, int raise_exception);
123
+ VALUE rb_big_comp(VALUE x);
124
+ VALUE rb_big_aref(VALUE x, VALUE y);
125
+ VALUE rb_big_abs(VALUE x);
126
+ VALUE rb_big_size_m(VALUE big);
127
+ VALUE rb_big_bit_length(VALUE big);
128
+ VALUE rb_big_remainder(VALUE x, VALUE y);
129
+ VALUE rb_big_gt(VALUE x, VALUE y);
130
+ VALUE rb_big_ge(VALUE x, VALUE y);
131
+ VALUE rb_big_lt(VALUE x, VALUE y);
132
+ VALUE rb_big_le(VALUE x, VALUE y);
133
+ VALUE rb_int_powm(int const argc, VALUE * const argv, VALUE const num);
134
+ static inline bool BIGNUM_SIGN(VALUE b);
135
+ static inline bool BIGNUM_POSITIVE_P(VALUE b);
136
+ static inline bool BIGNUM_NEGATIVE_P(VALUE b);
137
+ static inline void BIGNUM_SET_SIGN(VALUE b, bool sign);
138
+ static inline void BIGNUM_NEGATE(VALUE b);
139
+ static inline size_t BIGNUM_LEN(VALUE b);
140
+ static inline BDIGIT *BIGNUM_DIGITS(VALUE b);
141
+ static inline int BIGNUM_LENINT(VALUE b);
142
+ static inline bool BIGNUM_EMBED_P(VALUE b);
143
+
144
+ RUBY_SYMBOL_EXPORT_BEGIN
145
+ /* bignum.c (export) */
146
+ VALUE rb_big_mul_normal(VALUE x, VALUE y);
147
+ VALUE rb_big_mul_balance(VALUE x, VALUE y);
148
+ VALUE rb_big_mul_karatsuba(VALUE x, VALUE y);
149
+ VALUE rb_big_mul_toom3(VALUE x, VALUE y);
150
+ VALUE rb_big_sq_fast(VALUE x);
151
+ VALUE rb_big_divrem_normal(VALUE x, VALUE y);
152
+ VALUE rb_big2str_poweroftwo(VALUE x, int base);
153
+ VALUE rb_big2str_generic(VALUE x, int base);
154
+ VALUE rb_str2big_poweroftwo(VALUE arg, int base, int badcheck);
155
+ VALUE rb_str2big_normal(VALUE arg, int base, int badcheck);
156
+ VALUE rb_str2big_karatsuba(VALUE arg, int base, int badcheck);
157
+ #if defined(HAVE_LIBGMP) && defined(HAVE_GMP_H)
158
+ VALUE rb_big_mul_gmp(VALUE x, VALUE y);
159
+ VALUE rb_big_divrem_gmp(VALUE x, VALUE y);
160
+ VALUE rb_big2str_gmp(VALUE x, int base);
161
+ VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
162
+ #endif
163
+ VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
164
+ RUBY_SYMBOL_EXPORT_END
165
+
166
+ MJIT_SYMBOL_EXPORT_BEGIN
167
+ #if defined(HAVE_INT128_T)
168
+ VALUE rb_int128t2big(int128_t n);
169
+ #endif
170
+ MJIT_SYMBOL_EXPORT_END
171
+
172
+ /* sign: positive:1, negative:0 */
173
+ static inline bool
174
+ BIGNUM_SIGN(VALUE b)
175
+ {
176
+ return FL_TEST_RAW(b, BIGNUM_SIGN_BIT);
177
+ }
178
+
179
+ static inline bool
180
+ BIGNUM_POSITIVE_P(VALUE b)
181
+ {
182
+ return BIGNUM_SIGN(b);
183
+ }
184
+
185
+ static inline bool
186
+ BIGNUM_NEGATIVE_P(VALUE b)
187
+ {
188
+ return ! BIGNUM_POSITIVE_P(b);
189
+ }
190
+
191
+ static inline void
192
+ BIGNUM_SET_SIGN(VALUE b, bool sign)
193
+ {
194
+ if (sign) {
195
+ FL_SET_RAW(b, BIGNUM_SIGN_BIT);
196
+ }
197
+ else {
198
+ FL_UNSET_RAW(b, BIGNUM_SIGN_BIT);
199
+ }
200
+ }
201
+
202
+ static inline void
203
+ BIGNUM_NEGATE(VALUE b)
204
+ {
205
+ FL_REVERSE_RAW(b, BIGNUM_SIGN_BIT);
206
+ }
207
+
208
+ static inline size_t
209
+ BIGNUM_LEN(VALUE b)
210
+ {
211
+ if (! BIGNUM_EMBED_P(b)) {
212
+ return RBIGNUM(b)->as.heap.len;
213
+ }
214
+ else {
215
+ size_t ret = RBASIC(b)->flags;
216
+ ret &= BIGNUM_EMBED_LEN_MASK;
217
+ ret >>= BIGNUM_EMBED_LEN_SHIFT;
218
+ return ret;
219
+ }
220
+ }
221
+
222
+ static inline int
223
+ BIGNUM_LENINT(VALUE b)
224
+ {
225
+ return rb_long2int(BIGNUM_LEN(b));
226
+ }
227
+
228
+ /* LSB:BIGNUM_DIGITS(b)[0], MSB:BIGNUM_DIGITS(b)[BIGNUM_LEN(b)-1] */
229
+ static inline BDIGIT *
230
+ BIGNUM_DIGITS(VALUE b)
231
+ {
232
+ if (BIGNUM_EMBED_P(b)) {
233
+ return RBIGNUM(b)->as.ary;
234
+ }
235
+ else {
236
+ return RBIGNUM(b)->as.heap.digits;
237
+ }
238
+ }
239
+
240
+ static inline bool
241
+ BIGNUM_EMBED_P(VALUE b)
242
+ {
243
+ return FL_TEST_RAW(b, BIGNUM_EMBED_FLAG);
244
+ }
245
+
246
+ #endif /* INTERNAL_BIGNUM_H */
@@ -0,0 +1,566 @@
1
+ #ifndef INTERNAL_BITS_H /*-*-C-*-vi:se ft=c:*/
2
+ #define INTERNAL_BITS_H
3
+ /**
4
+ * @file
5
+ * @author Ruby developers <ruby-core@ruby-lang.org>
6
+ * @copyright This file is a part of the programming language Ruby.
7
+ * Permission is hereby granted, to either redistribute and/or
8
+ * modify this file, provided that the conditions mentioned in the
9
+ * file COPYING are met. Consult the file for details.
10
+ * @brief Internal header for bitwise integer algorithms.
11
+ * @see Henry S. Warren Jr., "Hacker's Delight" (2nd ed.), 2013.
12
+ * @see SEI CERT C Coding Standard INT32-C. "Ensure that operations on
13
+ * signed integers do not result in overflow"
14
+ * @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
15
+ * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateleft
16
+ * @see https://clang.llvm.org/docs/LanguageExtensions.html#builtin-rotateright
17
+ * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/byteswap-uint64-byteswap-ulong-byteswap-ushort
18
+ * @see https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rotl-rotl64-rotr-rotr64
19
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64
20
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64
21
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/lzcnt16-lzcnt-lzcnt64
22
+ * @see https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64
23
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_lzcnt_u32
24
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_tzcnt_u32
25
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotl64
26
+ * @see https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_rotr64
27
+ * @see https://stackoverflow.com/a/776523
28
+ */
29
+ #include "ruby/internal/config.h"
30
+ #include <limits.h> /* for CHAR_BITS */
31
+ #include <stdint.h> /* for uintptr_t */
32
+ #include "internal/compilers.h" /* for MSC_VERSION_SINCE */
33
+
34
+ #if MSC_VERSION_SINCE(1310)
35
+ # include <stdlib.h> /* for _byteswap_uint64 */
36
+ #endif
37
+
38
+ #if defined(HAVE_X86INTRIN_H) && ! defined(MJIT_HEADER)
39
+ # /* Rule out MJIT_HEADER, which does not interface well with <immintrin.h> */
40
+ # include <x86intrin.h> /* for _lzcnt_u64 */
41
+ #elif MSC_VERSION_SINCE(1310)
42
+ # include <intrin.h> /* for the following intrinsics */
43
+ #endif
44
+
45
+ #if defined(_MSC_VER) && defined(__AVX__)
46
+ # pragma intrinsic(__popcnt)
47
+ # pragma intrinsic(__popcnt64)
48
+ #endif
49
+
50
+ #if defined(_MSC_VER) && defined(__AVX2__)
51
+ # pragma intrinsic(__lzcnt)
52
+ # pragma intrinsic(__lzcnt64)
53
+ #endif
54
+
55
+ #if MSC_VERSION_SINCE(1310)
56
+ # pragma intrinsic(_rotl)
57
+ # pragma intrinsic(_rotr)
58
+ # ifdef _WIN64
59
+ # pragma intrinsic(_rotl64)
60
+ # pragma intrinsic(_rotr64)
61
+ # endif
62
+ #endif
63
+
64
+ #if MSC_VERSION_SINCE(1400)
65
+ # pragma intrinsic(_BitScanForward)
66
+ # pragma intrinsic(_BitScanReverse)
67
+ # ifdef _WIN64
68
+ # pragma intrinsic(_BitScanForward64)
69
+ # pragma intrinsic(_BitScanReverse64)
70
+ # endif
71
+ #endif
72
+
73
+ #include "ruby/ruby.h" /* for VALUE */
74
+ #include "internal/static_assert.h" /* for STATIC_ASSERT */
75
+
76
+ /* The most significant bit of the lower part of half-long integer.
77
+ * If sizeof(long) == 4, this is 0x8000.
78
+ * If sizeof(long) == 8, this is 0x80000000.
79
+ */
80
+ #define HALF_LONG_MSB ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
81
+
82
+ #define SIGNED_INTEGER_TYPE_P(T) (0 > ((T)0)-1)
83
+
84
+ #define SIGNED_INTEGER_MIN(T) \
85
+ ((sizeof(T) == sizeof(int8_t)) ? ((T)INT8_MIN) : \
86
+ ((sizeof(T) == sizeof(int16_t)) ? ((T)INT16_MIN) : \
87
+ ((sizeof(T) == sizeof(int32_t)) ? ((T)INT32_MIN) : \
88
+ ((sizeof(T) == sizeof(int64_t)) ? ((T)INT64_MIN) : \
89
+ 0))))
90
+
91
+ #define SIGNED_INTEGER_MAX(T) ((T)(SIGNED_INTEGER_MIN(T) ^ ((T)~(T)0)))
92
+
93
+ #define UNSIGNED_INTEGER_MAX(T) ((T)~(T)0)
94
+
95
+ #if __has_builtin(__builtin_mul_overflow_p)
96
+ # define MUL_OVERFLOW_P(a, b) \
97
+ __builtin_mul_overflow_p((a), (b), (__typeof__(a * b))0)
98
+ #elif __has_builtin(__builtin_mul_overflow)
99
+ # define MUL_OVERFLOW_P(a, b) \
100
+ __extension__ ({ __typeof__(a) c; __builtin_mul_overflow((a), (b), &c); })
101
+ #endif
102
+
103
+ #define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
104
+ (a) == 0 ? 0 : \
105
+ (a) == -1 ? (b) < -(max) : \
106
+ (a) > 0 ? \
107
+ ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
108
+ ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
109
+
110
+ #if __has_builtin(__builtin_mul_overflow_p)
111
+ /* __builtin_mul_overflow_p can take bitfield */
112
+ /* and GCC permits bitfields for integers other than int */
113
+ # define MUL_OVERFLOW_FIXNUM_P(a, b) \
114
+ __extension__ ({ \
115
+ struct { long fixnum : sizeof(long) * CHAR_BIT - 1; } c = { 0 }; \
116
+ __builtin_mul_overflow_p((a), (b), c.fixnum); \
117
+ })
118
+ #else
119
+ # define MUL_OVERFLOW_FIXNUM_P(a, b) \
120
+ MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
121
+ #endif
122
+
123
+ #ifdef MUL_OVERFLOW_P
124
+ # define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
125
+ # define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
126
+ # define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
127
+ #else
128
+ # define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
129
+ # define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
130
+ # define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
131
+ #endif
132
+
133
+ #ifdef HAVE_UINT128_T
134
+ # define bit_length(x) \
135
+ (unsigned int) \
136
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
137
+ sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \
138
+ 128 - nlz_int128((uint128_t)(x)))
139
+ #else
140
+ # define bit_length(x) \
141
+ (unsigned int) \
142
+ (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \
143
+ 64 - nlz_int64((uint64_t)(x)))
144
+ #endif
145
+
146
+ #ifndef swap16
147
+ # define swap16 ruby_swap16
148
+ #endif
149
+
150
+ #ifndef swap32
151
+ # define swap32 ruby_swap32
152
+ #endif
153
+
154
+ #ifndef swap64
155
+ # define swap64 ruby_swap64
156
+ #endif
157
+
158
+ static inline uint16_t ruby_swap16(uint16_t);
159
+ static inline uint32_t ruby_swap32(uint32_t);
160
+ static inline uint64_t ruby_swap64(uint64_t);
161
+ static inline unsigned nlz_int(unsigned x);
162
+ static inline unsigned nlz_long(unsigned long x);
163
+ static inline unsigned nlz_long_long(unsigned long long x);
164
+ static inline unsigned nlz_intptr(uintptr_t x);
165
+ static inline unsigned nlz_int32(uint32_t x);
166
+ static inline unsigned nlz_int64(uint64_t x);
167
+ #ifdef HAVE_UINT128_T
168
+ static inline unsigned nlz_int128(uint128_t x);
169
+ #endif
170
+ static inline unsigned rb_popcount32(uint32_t x);
171
+ static inline unsigned rb_popcount64(uint64_t x);
172
+ static inline unsigned rb_popcount_intptr(uintptr_t x);
173
+ static inline int ntz_int32(uint32_t x);
174
+ static inline int ntz_int64(uint64_t x);
175
+ static inline int ntz_intptr(uintptr_t x);
176
+ static inline VALUE RUBY_BIT_ROTL(VALUE, int);
177
+ static inline VALUE RUBY_BIT_ROTR(VALUE, int);
178
+
179
+ static inline uint16_t
180
+ ruby_swap16(uint16_t x)
181
+ {
182
+ #if __has_builtin(__builtin_bswap16)
183
+ return __builtin_bswap16(x);
184
+
185
+ #elif MSC_VERSION_SINCE(1310)
186
+ return _byteswap_ushort(x);
187
+
188
+ #else
189
+ return (x << 8) | (x >> 8);
190
+
191
+ #endif
192
+ }
193
+
194
+ static inline uint32_t
195
+ ruby_swap32(uint32_t x)
196
+ {
197
+ #if __has_builtin(__builtin_bswap32)
198
+ return __builtin_bswap32(x);
199
+
200
+ #elif MSC_VERSION_SINCE(1310)
201
+ return _byteswap_ulong(x);
202
+
203
+ #else
204
+ x = ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);
205
+ x = ((x & 0x00FF00FF) << 8) | ((x & 0xFF00FF00) >> 8);
206
+ return x;
207
+
208
+ #endif
209
+ }
210
+
211
+ static inline uint64_t
212
+ ruby_swap64(uint64_t x)
213
+ {
214
+ #if __has_builtin(__builtin_bswap64)
215
+ return __builtin_bswap64(x);
216
+
217
+ #elif MSC_VERSION_SINCE(1310)
218
+ return _byteswap_uint64(x);
219
+
220
+ #else
221
+ x = ((x & 0x00000000FFFFFFFFULL) << 32) | ((x & 0xFFFFFFFF00000000ULL) >> 32);
222
+ x = ((x & 0x0000FFFF0000FFFFULL) << 16) | ((x & 0xFFFF0000FFFF0000ULL) >> 16);
223
+ x = ((x & 0x00FF00FF00FF00FFULL) << 8) | ((x & 0xFF00FF00FF00FF00ULL) >> 8);
224
+ return x;
225
+
226
+ #endif
227
+ }
228
+
229
+ static inline unsigned int
230
+ nlz_int32(uint32_t x)
231
+ {
232
+ #if defined(_MSC_VER) && defined(__AVX2__)
233
+ /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC.
234
+ * AMD CPUs have had this instruction for decades (since K10) but for
235
+ * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum
236
+ * safety. */
237
+ return (unsigned int)__lzcnt(x);
238
+
239
+ #elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
240
+ return (unsigned int)_lzcnt_u32(x);
241
+
242
+ #elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
243
+ unsigned long r;
244
+ return _BitScanReverse(&r, x) ? (31 - (int)r) : 32;
245
+
246
+ #elif __has_builtin(__builtin_clz)
247
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
248
+ return x ? (unsigned int)__builtin_clz(x) : 32;
249
+
250
+ #else
251
+ uint32_t y;
252
+ unsigned n = 32;
253
+ y = x >> 16; if (y) {n -= 16; x = y;}
254
+ y = x >> 8; if (y) {n -= 8; x = y;}
255
+ y = x >> 4; if (y) {n -= 4; x = y;}
256
+ y = x >> 2; if (y) {n -= 2; x = y;}
257
+ y = x >> 1; if (y) {return n - 2;}
258
+ return (unsigned int)(n - x);
259
+ #endif
260
+ }
261
+
262
+ static inline unsigned int
263
+ nlz_int64(uint64_t x)
264
+ {
265
+ #if defined(_MSC_VER) && defined(__AVX2__)
266
+ return (unsigned int)__lzcnt64(x);
267
+
268
+ #elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
269
+ return (unsigned int)_lzcnt_u64(x);
270
+
271
+ #elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
272
+ unsigned long r;
273
+ return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64;
274
+
275
+ #elif __has_builtin(__builtin_clzl)
276
+ if (x == 0) {
277
+ return 64;
278
+ }
279
+ else if (sizeof(long) * CHAR_BIT == 64) {
280
+ return (unsigned int)__builtin_clzl((unsigned long)x);
281
+ }
282
+ else if (sizeof(long long) * CHAR_BIT == 64) {
283
+ return (unsigned int)__builtin_clzll((unsigned long long)x);
284
+ }
285
+ else {
286
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
287
+ __builtin_unreachable();
288
+ }
289
+
290
+ #else
291
+ uint64_t y;
292
+ unsigned int n = 64;
293
+ y = x >> 32; if (y) {n -= 32; x = y;}
294
+ y = x >> 16; if (y) {n -= 16; x = y;}
295
+ y = x >> 8; if (y) {n -= 8; x = y;}
296
+ y = x >> 4; if (y) {n -= 4; x = y;}
297
+ y = x >> 2; if (y) {n -= 2; x = y;}
298
+ y = x >> 1; if (y) {return n - 2;}
299
+ return (unsigned int)(n - x);
300
+
301
+ #endif
302
+ }
303
+
304
+ #ifdef HAVE_UINT128_T
305
+ static inline unsigned int
306
+ nlz_int128(uint128_t x)
307
+ {
308
+ uint64_t y = (uint64_t)(x >> 64);
309
+
310
+ if (x == 0) {
311
+ return 128;
312
+ }
313
+ else if (y == 0) {
314
+ return (unsigned int)nlz_int64(x) + 64;
315
+ }
316
+ else {
317
+ return (unsigned int)nlz_int64(y);
318
+ }
319
+ }
320
+ #endif
321
+
322
+ static inline unsigned int
323
+ nlz_int(unsigned int x)
324
+ {
325
+ if (sizeof(unsigned int) * CHAR_BIT == 32) {
326
+ return nlz_int32((uint32_t)x);
327
+ }
328
+ else if (sizeof(unsigned int) * CHAR_BIT == 64) {
329
+ return nlz_int64((uint64_t)x);
330
+ }
331
+ else {
332
+ UNREACHABLE_RETURN(~0);
333
+ }
334
+ }
335
+
336
+ static inline unsigned int
337
+ nlz_long(unsigned long x)
338
+ {
339
+ if (sizeof(unsigned long) * CHAR_BIT == 32) {
340
+ return nlz_int32((uint32_t)x);
341
+ }
342
+ else if (sizeof(unsigned long) * CHAR_BIT == 64) {
343
+ return nlz_int64((uint64_t)x);
344
+ }
345
+ else {
346
+ UNREACHABLE_RETURN(~0);
347
+ }
348
+ }
349
+
350
+ static inline unsigned int
351
+ nlz_long_long(unsigned long long x)
352
+ {
353
+ if (sizeof(unsigned long long) * CHAR_BIT == 64) {
354
+ return nlz_int64((uint64_t)x);
355
+ }
356
+ #ifdef HAVE_UINT128_T
357
+ else if (sizeof(unsigned long long) * CHAR_BIT == 128) {
358
+ return nlz_int128((uint128_t)x);
359
+ }
360
+ #endif
361
+ else {
362
+ UNREACHABLE_RETURN(~0);
363
+ }
364
+ }
365
+
366
+ static inline unsigned int
367
+ nlz_intptr(uintptr_t x)
368
+ {
369
+ if (sizeof(uintptr_t) == sizeof(unsigned int)) {
370
+ return nlz_int((unsigned int)x);
371
+ }
372
+ if (sizeof(uintptr_t) == sizeof(unsigned long)) {
373
+ return nlz_long((unsigned long)x);
374
+ }
375
+ if (sizeof(uintptr_t) == sizeof(unsigned long long)) {
376
+ return nlz_long_long((unsigned long long)x);
377
+ }
378
+ else {
379
+ UNREACHABLE_RETURN(~0);
380
+ }
381
+ }
382
+
383
+ static inline unsigned int
384
+ rb_popcount32(uint32_t x)
385
+ {
386
+ #if defined(_MSC_VER) && defined(__AVX__)
387
+ /* Note: CPUs since Nehalem and Barcelona have had this instruction so SSE
388
+ * 4.2 should suffice, but it seems there is no such thing like __SSE_4_2__
389
+ * predefined macro in MSVC. They do have __AVX__ so use it instead. */
390
+ return (unsigned int)__popcnt(x);
391
+
392
+ #elif __has_builtin(__builtin_popcount)
393
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT >= 32);
394
+ return (unsigned int)__builtin_popcount(x);
395
+
396
+ #else
397
+ x = (x & 0x55555555) + (x >> 1 & 0x55555555);
398
+ x = (x & 0x33333333) + (x >> 2 & 0x33333333);
399
+ x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
400
+ x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
401
+ x = (x & 0x0000003f) + (x >>16 & 0x0000003f);
402
+ return (unsigned int)x;
403
+
404
+ #endif
405
+ }
406
+
407
+ static inline unsigned int
408
+ rb_popcount64(uint64_t x)
409
+ {
410
+ #if defined(_MSC_VER) && defined(__AVX__)
411
+ return (unsigned int)__popcnt64(x);
412
+
413
+ #elif __has_builtin(__builtin_popcount)
414
+ if (sizeof(long) * CHAR_BIT == 64) {
415
+ return (unsigned int)__builtin_popcountl((unsigned long)x);
416
+ }
417
+ else if (sizeof(long long) * CHAR_BIT == 64) {
418
+ return (unsigned int)__builtin_popcountll((unsigned long long)x);
419
+ }
420
+ else {
421
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
422
+ __builtin_unreachable();
423
+ }
424
+
425
+ #else
426
+ x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
427
+ x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
428
+ x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
429
+ x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
430
+ x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
431
+ x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f);
432
+ return (unsigned int)x;
433
+
434
+ #endif
435
+ }
436
+
437
+ static inline unsigned int
438
+ rb_popcount_intptr(uintptr_t x)
439
+ {
440
+ if (sizeof(uintptr_t) * CHAR_BIT == 64) {
441
+ return rb_popcount64((uint64_t)x);
442
+ }
443
+ else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
444
+ return rb_popcount32((uint32_t)x);
445
+ }
446
+ else {
447
+ UNREACHABLE_RETURN(~0);
448
+ }
449
+ }
450
+
451
+ static inline int
452
+ ntz_int32(uint32_t x)
453
+ {
454
+ #if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
455
+ return (unsigned)_tzcnt_u32(x);
456
+
457
+ #elif MSC_VERSION_SINCE(1400)
458
+ /* :FIXME: Is there any way to issue TZCNT instead of BSF, apart from using
459
+ * assembly? Because issueing LZCNT seems possible (see nlz.h). */
460
+ unsigned long r;
461
+ return _BitScanForward(&r, x) ? (int)r : 32;
462
+
463
+ #elif __has_builtin(__builtin_ctz)
464
+ STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32);
465
+ return x ? (unsigned)__builtin_ctz(x) : 32;
466
+
467
+ #else
468
+ return rb_popcount32((~x) & (x-1));
469
+
470
+ #endif
471
+ }
472
+
473
+ static inline int
474
+ ntz_int64(uint64_t x)
475
+ {
476
+ #if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
477
+ return (unsigned)_tzcnt_u64(x);
478
+
479
+ #elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
480
+ unsigned long r;
481
+ return _BitScanForward64(&r, x) ? (int)r : 64;
482
+
483
+ #elif __has_builtin(__builtin_ctzl)
484
+ if (x == 0) {
485
+ return 64;
486
+ }
487
+ else if (sizeof(long) * CHAR_BIT == 64) {
488
+ return (unsigned)__builtin_ctzl((unsigned long)x);
489
+ }
490
+ else if (sizeof(long long) * CHAR_BIT == 64) {
491
+ return (unsigned)__builtin_ctzll((unsigned long long)x);
492
+ }
493
+ else {
494
+ /* :FIXME: Is there a way to make this branch a compile-time error? */
495
+ __builtin_unreachable();
496
+ }
497
+
498
+ #else
499
+ return rb_popcount64((~x) & (x-1));
500
+
501
+ #endif
502
+ }
503
+
504
+ static inline int
505
+ ntz_intptr(uintptr_t x)
506
+ {
507
+ if (sizeof(uintptr_t) * CHAR_BIT == 64) {
508
+ return ntz_int64((uint64_t)x);
509
+ }
510
+ else if (sizeof(uintptr_t) * CHAR_BIT == 32) {
511
+ return ntz_int32((uint32_t)x);
512
+ }
513
+ else {
514
+ UNREACHABLE_RETURN(~0);
515
+ }
516
+ }
517
+
518
+ static inline VALUE
519
+ RUBY_BIT_ROTL(VALUE v, int n)
520
+ {
521
+ #if __has_builtin(__builtin_rotateleft32) && (SIZEOF_VALUE * CHAR_BIT == 32)
522
+ return __builtin_rotateleft32(v, n);
523
+
524
+ #elif __has_builtin(__builtin_rotateleft64) && (SIZEOF_VALUE * CHAR_BIT == 64)
525
+ return __builtin_rotateleft64(v, n);
526
+
527
+ #elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
528
+ return _rotl(v, n);
529
+
530
+ #elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
531
+ return _rotl64(v, n);
532
+
533
+ #elif defined(_lrotl) && (SIZEOF_VALUE == SIZEOF_LONG)
534
+ return _lrotl(v, n);
535
+
536
+ #else
537
+ const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
538
+ return (v << (n & m)) | (v >> (-n & m));
539
+ #endif
540
+ }
541
+
542
+ static inline VALUE
543
+ RUBY_BIT_ROTR(VALUE v, int n)
544
+ {
545
+ #if __has_builtin(__builtin_rotateright32) && (SIZEOF_VALUE * CHAR_BIT == 32)
546
+ return __builtin_rotateright32(v, n);
547
+
548
+ #elif __has_builtin(__builtin_rotateright64) && (SIZEOF_VALUE * CHAR_BIT == 64)
549
+ return __builtin_rotateright64(v, n);
550
+
551
+ #elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 32)
552
+ return _rotr(v, n);
553
+
554
+ #elif MSC_VERSION_SINCE(1310) && (SIZEOF_VALUE * CHAR_BIT == 64)
555
+ return _rotr64(v, n);
556
+
557
+ #elif defined(_lrotr) && (SIZEOF_VALUE == SIZEOF_LONG)
558
+ return _lrotr(v, n);
559
+
560
+ #else
561
+ const int m = (sizeof(VALUE) * CHAR_BIT) - 1;
562
+ return (v << (-n & m)) | (v >> (n & m));
563
+ #endif
564
+ }
565
+
566
+ #endif /* INTERNAL_BITS_H */