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