hwint.h revision 1.4
1/* HOST_WIDE_INT definitions for the GNU compiler. 2 Copyright (C) 1998-2015 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 18/* The string that should be inserted into a printf style format to 19 indicate a "long" operand. */ 20#ifndef HOST_LONG_FORMAT 21#define HOST_LONG_FORMAT "l" 22#endif 23 24/* The string that should be inserted into a printf style format to 25 indicate a "long long" operand. */ 26#ifndef HOST_LONG_LONG_FORMAT 27#define HOST_LONG_LONG_FORMAT "ll" 28#endif 29 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 40extern char sizeof_long_long_must_be_8[sizeof (long long) == 8 ? 1 : -1]; 41# endif 42#endif 43 44#ifdef HAVE_LONG_LONG 45# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG) 46#endif 47 48/* Set HOST_WIDE_INT, this should be always 64 bits. 49 The underlying type is matched to that of int64_t and assumed 50 to be either long or long long. */ 51 52#define HOST_BITS_PER_WIDE_INT 64 53#if INT64_T_IS_LONG 54# define HOST_WIDE_INT long 55# define HOST_WIDE_INT_C(X) X ## L 56#else 57# if HOST_BITS_PER_LONGLONG == 64 58# define HOST_WIDE_INT long long 59# define HOST_WIDE_INT_C(X) X ## LL 60# else 61 #error "Unable to find a suitable type for HOST_WIDE_INT" 62# endif 63#endif 64 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) 70 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. */ 74typedef HOST_WIDE_INT __gcc_host_wide_int__; 75 76/* Provide C99 <inttypes.h> style format definitions for 64bits. */ 77#ifndef HAVE_INTTYPES_H 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 83#undef PRId64 84#define PRId64 GCC_PRI64 "d" 85#undef PRIi64 86#define PRIi64 GCC_PRI64 "i" 87#undef PRIo64 88#define PRIo64 GCC_PRI64 "o" 89#undef PRIu64 90#define PRIu64 GCC_PRI64 "u" 91#undef PRIx64 92#define PRIx64 GCC_PRI64 "x" 93#undef PRIX64 94#define PRIX64 GCC_PRI64 "X" 95#endif 96 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# define HOST_WIDE_INT_CONSTANT(x) x ## L 103#else 104# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT 105# define HOST_WIDE_INT_PRINT_C "LL" 106# define HOST_WIDE_INT_CONSTANT(x) x ## LL 107#endif 108 109#define HOST_WIDE_INT_PRINT_DEC "%" PRId64 110#define HOST_WIDE_INT_PRINT_DEC_C "%" PRId64 HOST_WIDE_INT_PRINT_C 111#define HOST_WIDE_INT_PRINT_UNSIGNED "%" PRIu64 112#define HOST_WIDE_INT_PRINT_HEX "%#" PRIx64 113#define HOST_WIDE_INT_PRINT_HEX_PURE "%" PRIx64 114#define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%" PRIx64 "%016" PRIx64 115#define HOST_WIDE_INT_PRINT_PADDED_HEX "%016" PRIx64 116 117/* Define HOST_WIDEST_FAST_INT to the widest integer type supported 118 efficiently in hardware. (That is, the widest integer type that fits 119 in a hardware register.) Normally this is "long" but on some hosts it 120 should be "long long" or "__int64". This is no convenient way to 121 autodetect this, so such systems must set a flag in config.host; see there 122 for details. */ 123 124#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT 125# ifdef HAVE_LONG_LONG 126# define HOST_WIDEST_FAST_INT long long 127# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG 128# else 129# error "Your host said it wanted to use long long but that does not exist" 130# endif 131#else 132# define HOST_WIDEST_FAST_INT long 133# define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG 134#endif 135 136/* Inline functions operating on HOST_WIDE_INT. */ 137#if GCC_VERSION < 3004 138 139extern int clz_hwi (unsigned HOST_WIDE_INT x); 140extern int ctz_hwi (unsigned HOST_WIDE_INT x); 141extern int ffs_hwi (unsigned HOST_WIDE_INT x); 142 143/* Return the number of set bits in X. */ 144extern int popcount_hwi (unsigned HOST_WIDE_INT x); 145 146/* Return log2, or -1 if not exact. */ 147extern int exact_log2 (unsigned HOST_WIDE_INT); 148 149/* Return floor of log2, with -1 for zero. */ 150extern int floor_log2 (unsigned HOST_WIDE_INT); 151 152/* Return the smallest n such that 2**n >= X. */ 153extern int ceil_log2 (unsigned HOST_WIDE_INT); 154 155#else /* GCC_VERSION >= 3004 */ 156 157/* For convenience, define 0 -> word_size. */ 158static inline int 159clz_hwi (unsigned HOST_WIDE_INT x) 160{ 161 if (x == 0) 162 return HOST_BITS_PER_WIDE_INT; 163# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG 164 return __builtin_clzl (x); 165# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG 166 return __builtin_clzll (x); 167# else 168 return __builtin_clz (x); 169# endif 170} 171 172static inline int 173ctz_hwi (unsigned HOST_WIDE_INT x) 174{ 175 if (x == 0) 176 return HOST_BITS_PER_WIDE_INT; 177# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG 178 return __builtin_ctzl (x); 179# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG 180 return __builtin_ctzll (x); 181# else 182 return __builtin_ctz (x); 183# endif 184} 185 186static inline int 187ffs_hwi (unsigned HOST_WIDE_INT x) 188{ 189# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG 190 return __builtin_ffsl (x); 191# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG 192 return __builtin_ffsll (x); 193# else 194 return __builtin_ffs (x); 195# endif 196} 197 198static inline int 199popcount_hwi (unsigned HOST_WIDE_INT x) 200{ 201# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG 202 return __builtin_popcountl (x); 203# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG 204 return __builtin_popcountll (x); 205# else 206 return __builtin_popcount (x); 207# endif 208} 209 210static inline int 211floor_log2 (unsigned HOST_WIDE_INT x) 212{ 213 return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); 214} 215 216static inline int 217ceil_log2 (unsigned HOST_WIDE_INT x) 218{ 219 return floor_log2 (x - 1) + 1; 220} 221 222static inline int 223exact_log2 (unsigned HOST_WIDE_INT x) 224{ 225 return x == (x & -x) && x ? ctz_hwi (x) : -1; 226} 227 228#endif /* GCC_VERSION >= 3004 */ 229 230#define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \ 231 ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)) 232#define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN)) 233 234extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT); 235extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT); 236extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT); 237extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); 238extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT); 239extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT); 240 241/* Sign extend SRC starting from PREC. */ 242 243static inline HOST_WIDE_INT 244sext_hwi (HOST_WIDE_INT src, unsigned int prec) 245{ 246 if (prec == HOST_BITS_PER_WIDE_INT) 247 return src; 248 else 249 { 250 gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); 251 int shift = HOST_BITS_PER_WIDE_INT - prec; 252 return (src << shift) >> shift; 253 } 254} 255 256/* Zero extend SRC starting from PREC. */ 257static inline unsigned HOST_WIDE_INT 258zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec) 259{ 260 if (prec == HOST_BITS_PER_WIDE_INT) 261 return src; 262 else 263 { 264 gcc_checking_assert (prec < HOST_BITS_PER_WIDE_INT); 265 return src & (((unsigned HOST_WIDE_INT) 1 << prec) - 1); 266 } 267} 268 269/* Compute the absolute value of X. */ 270 271inline HOST_WIDE_INT 272abs_hwi (HOST_WIDE_INT x) 273{ 274 gcc_checking_assert (x != HOST_WIDE_INT_MIN); 275 return x >= 0 ? x : -x; 276} 277 278/* Compute the absolute value of X as an unsigned type. */ 279 280inline unsigned HOST_WIDE_INT 281absu_hwi (HOST_WIDE_INT x) 282{ 283 return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x; 284} 285 286#endif /* ! GCC_HWINT_H */ 287