]>
Commit | Line | Data |
---|---|---|
09017a04 | 1 | /* HOST_WIDE_INT definitions for the GNU compiler. |
f1717362 | 2 | Copyright (C) 1998-2016 Free Software Foundation, Inc. |
09017a04 | 3 | |
f12b58b3 | 4 | This file is part of GCC. |
09017a04 | 5 | |
6 | Provide definitions for macros which depend on HOST_BITS_PER_INT | |
ab6d34f7 | 7 | and HOST_BITS_PER_LONG. */ |
09017a04 | 8 | |
2a281353 | 9 | #ifndef GCC_HWINT_H |
10 | #define GCC_HWINT_H | |
09017a04 | 11 | |
02be28b3 | 12 | /* This describes the machine the compiler is hosted on. */ |
13 | #define HOST_BITS_PER_CHAR CHAR_BIT | |
14 | #define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT) | |
15 | #define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT) | |
16 | #define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG) | |
17 | ||
038ca0d1 | 18 | /* The string that should be inserted into a printf style format to |
19 | indicate a "long" operand. */ | |
48e1416a | 20 | #ifndef HOST_LONG_FORMAT |
038ca0d1 | 21 | #define HOST_LONG_FORMAT "l" |
22 | #endif | |
23 | ||
92ebe7d3 | 24 | /* The string that should be inserted into a printf style format to |
25 | indicate a "long long" operand. */ | |
48e1416a | 26 | #ifndef HOST_LONG_LONG_FORMAT |
92ebe7d3 | 27 | #define HOST_LONG_LONG_FORMAT "ll" |
28 | #endif | |
29 | ||
805e22b2 | 30 | /* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but |
31 | GCC_VERSION >= 3000, assume this is the second or later stage of a | |
32 | bootstrap, we do have long long, and it's 64 bits. (This is | |
33 | required by C99; we do have some ports that violate that assumption | |
34 | but they're all cross-compile-only.) Just in case, force a | |
35 | constraint violation if that assumption is incorrect. */ | |
36 | #if !defined HAVE_LONG_LONG | |
37 | # if GCC_VERSION >= 3000 | |
38 | # define HAVE_LONG_LONG 1 | |
39 | # define SIZEOF_LONG_LONG 8 | |
9af5ce0c | 40 | extern char sizeof_long_long_must_be_8[sizeof (long long) == 8 ? 1 : -1]; |
805e22b2 | 41 | # endif |
42 | #endif | |
43 | ||
02be28b3 | 44 | #ifdef HAVE_LONG_LONG |
45 | # define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG) | |
805e22b2 | 46 | #endif |
09017a04 | 47 | |
1c8ad86a | 48 | /* Set HOST_WIDE_INT, this should be always 64 bits. |
d515e136 | 49 | The underlying type is matched to that of int64_t and assumed |
50 | to be either long or long long. */ | |
31ee5761 | 51 | |
1c8ad86a | 52 | #define HOST_BITS_PER_WIDE_INT 64 |
d515e136 | 53 | #if INT64_T_IS_LONG |
805e22b2 | 54 | # define HOST_WIDE_INT long |
1fa4dd5c | 55 | # define HOST_WIDE_INT_C(X) X ## L |
805e22b2 | 56 | #else |
1c8ad86a | 57 | # if HOST_BITS_PER_LONGLONG == 64 |
31ee5761 | 58 | # define HOST_WIDE_INT long long |
1fa4dd5c | 59 | # define HOST_WIDE_INT_C(X) X ## LL |
09017a04 | 60 | # else |
1c8ad86a | 61 | #error "Unable to find a suitable type for HOST_WIDE_INT" |
09017a04 | 62 | # endif |
805e22b2 | 63 | #endif |
09017a04 | 64 | |
9af5ce0c | 65 | #define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C (X ## U) |
66 | #define HOST_WIDE_INT_1 HOST_WIDE_INT_C (1) | |
67 | #define HOST_WIDE_INT_1U HOST_WIDE_INT_UC (1) | |
68 | #define HOST_WIDE_INT_M1 HOST_WIDE_INT_C (-1) | |
69 | #define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC (-1) | |
1fa4dd5c | 70 | |
b5369b7d | 71 | /* This is a magic identifier which allows GCC to figure out the type |
72 | of HOST_WIDE_INT for %wd specifier checks. You must issue this | |
73 | typedef before using the __asm_fprintf__ format attribute. */ | |
74 | typedef HOST_WIDE_INT __gcc_host_wide_int__; | |
75 | ||
3a4303e7 | 76 | /* Provide C99 <inttypes.h> style format definitions for 64bits. */ |
77 | #ifndef HAVE_INTTYPES_H | |
d515e136 | 78 | #if INT64_T_IS_LONG |
79 | # define GCC_PRI64 HOST_LONG_FORMAT | |
80 | #else | |
81 | # define GCC_PRI64 HOST_LONG_LONG_FORMAT | |
82 | #endif | |
3a4303e7 | 83 | #undef PRId64 |
d515e136 | 84 | #define PRId64 GCC_PRI64 "d" |
3a4303e7 | 85 | #undef PRIi64 |
d515e136 | 86 | #define PRIi64 GCC_PRI64 "i" |
3a4303e7 | 87 | #undef PRIo64 |
d515e136 | 88 | #define PRIo64 GCC_PRI64 "o" |
3a4303e7 | 89 | #undef PRIu64 |
d515e136 | 90 | #define PRIu64 GCC_PRI64 "u" |
3a4303e7 | 91 | #undef PRIx64 |
d515e136 | 92 | #define PRIx64 GCC_PRI64 "x" |
3a4303e7 | 93 | #undef PRIX64 |
d515e136 | 94 | #define PRIX64 GCC_PRI64 "X" |
3a4303e7 | 95 | #endif |
02be28b3 | 96 | |
d515e136 | 97 | /* Various printf format strings for HOST_WIDE_INT. */ |
98 | ||
99 | #if INT64_T_IS_LONG | |
100 | # define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT | |
101 | # define HOST_WIDE_INT_PRINT_C "L" | |
102 | #else | |
103 | # define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT | |
104 | # define HOST_WIDE_INT_PRINT_C "LL" | |
105 | #endif | |
106 | ||
107 | #define HOST_WIDE_INT_PRINT_DEC "%" PRId64 | |
108 | #define HOST_WIDE_INT_PRINT_DEC_C "%" PRId64 HOST_WIDE_INT_PRINT_C | |
109 | #define HOST_WIDE_INT_PRINT_UNSIGNED "%" PRIu64 | |
110 | #define HOST_WIDE_INT_PRINT_HEX "%#" PRIx64 | |
111 | #define HOST_WIDE_INT_PRINT_HEX_PURE "%" PRIx64 | |
112 | #define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%" PRIx64 "%016" PRIx64 | |
113 | #define HOST_WIDE_INT_PRINT_PADDED_HEX "%016" PRIx64 | |
114 | ||
3f28a032 | 115 | /* Define HOST_WIDEST_FAST_INT to the widest integer type supported |
116 | efficiently in hardware. (That is, the widest integer type that fits | |
117 | in a hardware register.) Normally this is "long" but on some hosts it | |
118 | should be "long long" or "__int64". This is no convenient way to | |
f2b32076 | 119 | autodetect this, so such systems must set a flag in config.host; see there |
3f28a032 | 120 | for details. */ |
121 | ||
122 | #ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT | |
123 | # ifdef HAVE_LONG_LONG | |
124 | # define HOST_WIDEST_FAST_INT long long | |
125 | # define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG | |
3f28a032 | 126 | # else |
1c8ad86a | 127 | # error "Your host said it wanted to use long long but that does not exist" |
3f28a032 | 128 | # endif |
129 | #else | |
130 | # define HOST_WIDEST_FAST_INT long | |
131 | # define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG | |
132 | #endif | |
133 | ||
b96c136c | 134 | /* Inline functions operating on HOST_WIDE_INT. */ |
135 | #if GCC_VERSION < 3004 | |
136 | ||
137 | extern int clz_hwi (unsigned HOST_WIDE_INT x); | |
138 | extern int ctz_hwi (unsigned HOST_WIDE_INT x); | |
139 | extern int ffs_hwi (unsigned HOST_WIDE_INT x); | |
140 | ||
45105ae2 | 141 | /* Return the number of set bits in X. */ |
142 | extern int popcount_hwi (unsigned HOST_WIDE_INT x); | |
143 | ||
b96c136c | 144 | /* Return log2, or -1 if not exact. */ |
145 | extern int exact_log2 (unsigned HOST_WIDE_INT); | |
146 | ||
147 | /* Return floor of log2, with -1 for zero. */ | |
148 | extern int floor_log2 (unsigned HOST_WIDE_INT); | |
149 | ||
f80de6c2 | 150 | /* Return the smallest n such that 2**n >= X. */ |
151 | extern int ceil_log2 (unsigned HOST_WIDE_INT); | |
152 | ||
b96c136c | 153 | #else /* GCC_VERSION >= 3004 */ |
154 | ||
155 | /* For convenience, define 0 -> word_size. */ | |
156 | static inline int | |
157 | clz_hwi (unsigned HOST_WIDE_INT x) | |
158 | { | |
159 | if (x == 0) | |
160 | return HOST_BITS_PER_WIDE_INT; | |
161 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
162 | return __builtin_clzl (x); | |
163 | # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG | |
164 | return __builtin_clzll (x); | |
165 | # else | |
166 | return __builtin_clz (x); | |
167 | # endif | |
168 | } | |
169 | ||
170 | static inline int | |
171 | ctz_hwi (unsigned HOST_WIDE_INT x) | |
172 | { | |
173 | if (x == 0) | |
174 | return HOST_BITS_PER_WIDE_INT; | |
175 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
176 | return __builtin_ctzl (x); | |
177 | # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG | |
178 | return __builtin_ctzll (x); | |
179 | # else | |
180 | return __builtin_ctz (x); | |
181 | # endif | |
182 | } | |
183 | ||
184 | static inline int | |
185 | ffs_hwi (unsigned HOST_WIDE_INT x) | |
186 | { | |
187 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
188 | return __builtin_ffsl (x); | |
189 | # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG | |
190 | return __builtin_ffsll (x); | |
191 | # else | |
192 | return __builtin_ffs (x); | |
193 | # endif | |
194 | } | |
195 | ||
45105ae2 | 196 | static inline int |
197 | popcount_hwi (unsigned HOST_WIDE_INT x) | |
198 | { | |
199 | # if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
200 | return __builtin_popcountl (x); | |
201 | # elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG | |
202 | return __builtin_popcountll (x); | |
203 | # else | |
204 | return __builtin_popcount (x); | |
205 | # endif | |
206 | } | |
207 | ||
b96c136c | 208 | static inline int |
209 | floor_log2 (unsigned HOST_WIDE_INT x) | |
210 | { | |
211 | return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); | |
212 | } | |
213 | ||
f80de6c2 | 214 | static inline int |
215 | ceil_log2 (unsigned HOST_WIDE_INT x) | |
216 | { | |
217 | return floor_log2 (x - 1) + 1; | |
218 | } | |
219 | ||
b96c136c | 220 | static inline int |
221 | exact_log2 (unsigned HOST_WIDE_INT x) | |
222 | { | |
223 | return x == (x & -x) && x ? ctz_hwi (x) : -1; | |
224 | } | |
225 | ||
226 | #endif /* GCC_VERSION >= 3004 */ | |
227 | ||
2fa63533 | 228 | #define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \ |
229 | ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)) | |
230 | #define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN)) | |
231 | ||
232 | extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT); | |
b1757d46 | 233 | extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT); |
2fa63533 | 234 | extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT); |
235 | extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); | |
236 | extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); | |
237 | extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT); | |
e01f9f1f | 238 | |
687a1ea1 | 239 | /* Sign extend SRC starting from PREC. */ |
240 | ||
687a1ea1 | 241 | static inline HOST_WIDE_INT |
242 | sext_hwi (HOST_WIDE_INT src, unsigned int prec) | |
243 | { | |
244 | if (prec == HOST_BITS_PER_WIDE_INT) | |
245 | return src; | |
246 | else | |
39946840 | 247 | #if defined (__GNUC__) |
687a1ea1 | 248 | { |
39946840 | 249 | /* Take the faster path if the implementation-defined bits it's relying |
250 | on are implemented the way we expect them to be. Namely, conversion | |
251 | from unsigned to signed preserves bit pattern, and right shift of | |
252 | a signed value propagates the sign bit. | |
253 | We have to convert from signed to unsigned and back, because when left | |
254 | shifting signed values, any overflow is undefined behaviour. */ | |
473bcb8e | 255 | gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); |
687a1ea1 | 256 | int shift = HOST_BITS_PER_WIDE_INT - prec; |
39946840 | 257 | return ((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) src << shift)) >> shift; |
687a1ea1 | 258 | } |
39946840 | 259 | #else |
260 | { | |
261 | /* Fall back to the slower, well defined path otherwise. */ | |
262 | gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); | |
263 | HOST_WIDE_INT sign_mask = HOST_WIDE_INT_1 << (prec - 1); | |
264 | HOST_WIDE_INT value_mask = (HOST_WIDE_INT_1U << prec) - HOST_WIDE_INT_1U; | |
265 | return (((src & value_mask) ^ sign_mask) - sign_mask); | |
266 | } | |
267 | #endif | |
687a1ea1 | 268 | } |
687a1ea1 | 269 | |
270 | /* Zero extend SRC starting from PREC. */ | |
687a1ea1 | 271 | static inline unsigned HOST_WIDE_INT |
272 | zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec) | |
273 | { | |
274 | if (prec == HOST_BITS_PER_WIDE_INT) | |
275 | return src; | |
276 | else | |
473bcb8e | 277 | { |
278 | gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); | |
2f40fa7e | 279 | return src & (((unsigned HOST_WIDE_INT) 1 << prec) - 1); |
473bcb8e | 280 | } |
687a1ea1 | 281 | } |
687a1ea1 | 282 | |
a2b340f2 | 283 | /* Compute the absolute value of X. */ |
284 | ||
285 | inline HOST_WIDE_INT | |
286 | abs_hwi (HOST_WIDE_INT x) | |
287 | { | |
288 | gcc_checking_assert (x != HOST_WIDE_INT_MIN); | |
289 | return x >= 0 ? x : -x; | |
290 | } | |
291 | ||
292 | /* Compute the absolute value of X as an unsigned type. */ | |
293 | ||
294 | inline unsigned HOST_WIDE_INT | |
295 | absu_hwi (HOST_WIDE_INT x) | |
296 | { | |
297 | return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x; | |
298 | } | |
299 | ||
2a281353 | 300 | #endif /* ! GCC_HWINT_H */ |