hwint.h 12.4 KB
Newer Older
1
/* HOST_WIDE_INT definitions for the GNU compiler.
2
   Copyright (C) 1998-2013 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 10
#ifndef GCC_HWINT_H
#define GCC_HWINT_H
11

12 13 14 15 16 17
/* This describes the machine the compiler is hosted on.  */
#define HOST_BITS_PER_CHAR  CHAR_BIT
#define HOST_BITS_PER_SHORT (CHAR_BIT * SIZEOF_SHORT)
#define HOST_BITS_PER_INT   (CHAR_BIT * SIZEOF_INT)
#define HOST_BITS_PER_LONG  (CHAR_BIT * SIZEOF_LONG)

18
/* The string that should be inserted into a printf style format to
19
   indicate a "long" operand.  */
H.J. Lu committed
20
#ifndef HOST_LONG_FORMAT
21 22 23 24
#define HOST_LONG_FORMAT "l"
#endif

/* The string that should be inserted into a printf style format to
25
   indicate a "long long" operand.  */
H.J. Lu committed
26
#ifndef HOST_LONG_LONG_FORMAT
27 28 29
#define HOST_LONG_LONG_FORMAT "ll"
#endif

30 31 32 33 34 35 36 37 38 39
/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but
   GCC_VERSION >= 3000, assume this is the second or later stage of a
   bootstrap, we do have long long, and it's 64 bits.  (This is
   required by C99; we do have some ports that violate that assumption
   but they're all cross-compile-only.)  Just in case, force a
   constraint violation if that assumption is incorrect.  */
#if !defined HAVE_LONG_LONG
# if GCC_VERSION >= 3000
#  define HAVE_LONG_LONG 1
#  define SIZEOF_LONG_LONG 8
40
extern char sizeof_long_long_must_be_8[sizeof (long long) == 8 ? 1 : -1];
41 42 43
# endif
#endif

44 45
#ifdef HAVE_LONG_LONG
# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
46
#endif
47
#ifdef HAVE___INT64
48
# define HOST_BITS_PER___INT64 (CHAR_BIT * SIZEOF___INT64)
49
#endif
50

51 52 53
/* Set HOST_WIDE_INT.  This should be the widest efficient host
   integer type.  It can be 32 or 64 bits, except that if we are
   targeting a machine with 64-bit size_t then it has to be 64 bits.
54

55 56 57
   With a sane ABI, 'long' is the largest efficient host integer type.
   Thus, we use that unless we have to use 'long long' or '__int64'
   because we're targeting a 64-bit machine from a 32-bit host.  */
58

59 60 61
#if HOST_BITS_PER_LONG >= 64 || !defined NEED_64BIT_HOST_WIDE_INT
#   define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
#   define HOST_WIDE_INT long
62
#   define HOST_WIDE_INT_C(X) X ## L
63 64
#else
# if HOST_BITS_PER_LONGLONG >= 64
65 66
#   define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
#   define HOST_WIDE_INT long long
67
#   define HOST_WIDE_INT_C(X) X ## LL
68
# else
69 70 71
#  if HOST_BITS_PER___INT64 >= 64
#   define HOST_BITS_PER_WIDE_INT HOST_BITS_PER___INT64
#   define HOST_WIDE_INT __int64
72
#   define HOST_WIDE_INT_C(X) X ## i64
73
#  else
74
    #error "Unable to find a suitable type for HOST_WIDE_INT"
75 76
#  endif
# endif
77
#endif
78

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
/* Print support for half a host wide int.  */
#define HOST_BITS_PER_HALF_WIDE_INT (HOST_BITS_PER_WIDE_INT / 2)
#if HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_LONG
# define HOST_HALF_WIDE_INT long
# define HOST_HALF_WIDE_INT_PRINT HOST_LONG_FORMAT
# define HOST_HALF_WIDE_INT_PRINT_C "L"
# define HOST_HALF_WIDE_INT_PRINT_DEC "%" HOST_HALF_WIDE_INT_PRINT "d"
# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED "%" HOST_HALF_WIDE_INT_PRINT "u"
# define HOST_HALF_WIDE_INT_PRINT_HEX "%#" HOST_HALF_WIDE_INT_PRINT "x"
# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE "%" HOST_HALF_WIDE_INT_PRINT "x"
#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_INT
# define HOST_HALF_WIDE_INT int
# define HOST_HALF_WIDE_INT_PRINT ""
# define HOST_HALF_WIDE_INT_PRINT_C ""
# define HOST_HALF_WIDE_INT_PRINT_DEC "%" HOST_HALF_WIDE_INT_PRINT "d"
# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED "%" HOST_HALF_WIDE_INT_PRINT "u"
# define HOST_HALF_WIDE_INT_PRINT_HEX "%#" HOST_HALF_WIDE_INT_PRINT "x"
# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE "%" HOST_HALF_WIDE_INT_PRINT "x"
#elif HOST_BITS_PER_HALF_WIDE_INT == HOST_BITS_PER_SHORT
# define HOST_HALF_WIDE_INT short
# define HOST_HALF_WIDE_INT_PRINT ""
# define HOST_HALF_WIDE_INT_PRINT_C ""
# define HOST_HALF_WIDE_INT_PRINT_DEC "%" HOST_HALF_WIDE_INT_PRINT "d"
# define HOST_HALF_WIDE_INT_PRINT_DEC_C HOST_HALF_WIDE_INT_PRINT_DEC HOST_HALF_WIDE_INT_PRINT_C
# define HOST_HALF_WIDE_INT_PRINT_UNSIGNED "%" HOST_HALF_WIDE_INT_PRINT "u"
# define HOST_HALF_WIDE_INT_PRINT_HEX "%#" HOST_HALF_WIDE_INT_PRINT "x"
# define HOST_HALF_WIDE_INT_PRINT_HEX_PURE "%" HOST_HALF_WIDE_INT_PRINT "x"
#else
#error Please add support for HOST_HALF_WIDE_INT
#endif


113 114 115 116 117
#define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C (X ## U)
#define HOST_WIDE_INT_1 HOST_WIDE_INT_C (1)
#define HOST_WIDE_INT_1U HOST_WIDE_INT_UC (1)
#define HOST_WIDE_INT_M1 HOST_WIDE_INT_C (-1)
#define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC (-1)
118

119 120 121 122 123
/* This is a magic identifier which allows GCC to figure out the type
   of HOST_WIDE_INT for %wd specifier checks.  You must issue this
   typedef before using the __asm_fprintf__ format attribute.  */
typedef HOST_WIDE_INT __gcc_host_wide_int__;

124 125 126
/* Various printf format strings for HOST_WIDE_INT.  */

#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
127
# define HOST_WIDE_INT_PRINT HOST_LONG_FORMAT
128
# define HOST_WIDE_INT_PRINT_C "L"
129 130 131
  /* 'long' might be 32 or 64 bits, and the number of leading zeroes
     must be tweaked accordingly.  */
# if HOST_BITS_PER_WIDE_INT == 64
132
#  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
133
     "0x%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x"
134 135
#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
     "%016" HOST_LONG_FORMAT "x"
136
# else
137
#  define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
138
     "0x%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x"
139 140
#  define HOST_WIDE_INT_PRINT_PADDED_HEX \
     "%08" HOST_LONG_FORMAT "x"
141
# endif
142
#else
143
# define HOST_WIDE_INT_PRINT HOST_LONG_LONG_FORMAT
144
# define HOST_WIDE_INT_PRINT_C "LL"
145
  /* We can assume that 'long long' is at least 64 bits.  */
146
# define HOST_WIDE_INT_PRINT_DOUBLE_HEX \
147
    "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
148 149
# define HOST_WIDE_INT_PRINT_PADDED_HEX \
    "%016" HOST_LONG_LONG_FORMAT "x"
150 151 152 153 154
#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */

#define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d"
#define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C
#define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u"
155
#define HOST_WIDE_INT_PRINT_HEX "%#" HOST_WIDE_INT_PRINT "x"
156
#define HOST_WIDE_INT_PRINT_HEX_PURE "%" HOST_WIDE_INT_PRINT "x"
157

158 159
/* Set HOST_WIDEST_INT.  This is a 64-bit type unless the compiler
   in use has no 64-bit type at all; in that case it's 32 bits.  */
160

161 162
#if HOST_BITS_PER_WIDE_INT >= 64 \
    || (HOST_BITS_PER_LONGLONG < 64 && HOST_BITS_PER___INT64 < 64)
163 164
# define HOST_WIDEST_INT		      HOST_WIDE_INT
# define HOST_BITS_PER_WIDEST_INT	      HOST_BITS_PER_WIDE_INT
165
# define HOST_WIDEST_INT_PRINT                HOST_WIDE_INT_PRINT
166 167 168 169 170
# define HOST_WIDEST_INT_PRINT_DEC	      HOST_WIDE_INT_PRINT_DEC
# define HOST_WIDEST_INT_PRINT_DEC_C	      HOST_WIDE_INT_PRINT_DEC_C
# define HOST_WIDEST_INT_PRINT_UNSIGNED	      HOST_WIDE_INT_PRINT_UNSIGNED
# define HOST_WIDEST_INT_PRINT_HEX	      HOST_WIDE_INT_PRINT_HEX
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX     HOST_WIDE_INT_PRINT_DOUBLE_HEX
171
# define HOST_WIDEST_INT_C(X)		      HOST_WIDE_INT (X)
172 173 174 175
#else
# if HOST_BITS_PER_LONGLONG >= 64
#  define HOST_BITS_PER_WIDEST_INT	      HOST_BITS_PER_LONGLONG
#  define HOST_WIDEST_INT		      long long
176
#  define HOST_WIDEST_INT_C(X)		      X ## LL
177
# else
178 179 180
#  if HOST_BITS_PER___INT64 >= 64
#   define HOST_BITS_PER_WIDEST_INT	      HOST_BITS_PER___INT64
#   define HOST_WIDEST_INT		      __int64
181
#   define HOST_WIDEST_INT_C(X)		      X ## i64
182
#  else
183
    #error "This line should be impossible to reach"
184 185
#  endif
# endif
186
# define HOST_WIDEST_INT_PRINT                HOST_LONG_LONG_FORMAT
187 188 189
# define HOST_WIDEST_INT_PRINT_DEC	      "%" HOST_LONG_LONG_FORMAT "d"
# define HOST_WIDEST_INT_PRINT_DEC_C	      "%" HOST_LONG_LONG_FORMAT "dLL"
# define HOST_WIDEST_INT_PRINT_UNSIGNED	      "%" HOST_LONG_LONG_FORMAT "u"
190
# define HOST_WIDEST_INT_PRINT_HEX	      "%#" HOST_LONG_LONG_FORMAT "x"
191
# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX     \
192
    "0x%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x"
193
#endif
194

195 196 197 198
/* Define HOST_WIDEST_FAST_INT to the widest integer type supported
   efficiently in hardware.  (That is, the widest integer type that fits
   in a hardware register.)  Normally this is "long" but on some hosts it
   should be "long long" or "__int64".  This is no convenient way to
199
   autodetect this, so such systems must set a flag in config.host; see there
200 201 202 203 204 205 206 207 208 209
   for details.  */

#ifdef USE_LONG_LONG_FOR_WIDEST_FAST_INT
#  ifdef HAVE_LONG_LONG
#    define HOST_WIDEST_FAST_INT long long
#    define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONGLONG
#  elif defined (HAVE___INT64)
#    define HOST_WIDEST_FAST_INT __int64
#    define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER___INT64
#  else
210
#    error "Your host said it wanted to use long long or __int64 but neither"
211 212 213 214 215 216 217
#    error "exist"
#  endif
#else
#  define HOST_WIDEST_FAST_INT long
#  define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG
#endif

Joseph Myers committed
218 219 220 221 222 223 224
/* Inline functions operating on HOST_WIDE_INT.  */
#if GCC_VERSION < 3004

extern int clz_hwi (unsigned HOST_WIDE_INT x);
extern int ctz_hwi (unsigned HOST_WIDE_INT x);
extern int ffs_hwi (unsigned HOST_WIDE_INT x);

225 226 227
/* Return the number of set bits in X.  */
extern int popcount_hwi (unsigned HOST_WIDE_INT x);

Joseph Myers committed
228 229 230 231 232 233
/* Return log2, or -1 if not exact.  */
extern int exact_log2                  (unsigned HOST_WIDE_INT);

/* Return floor of log2, with -1 for zero.  */
extern int floor_log2                  (unsigned HOST_WIDE_INT);

234 235 236
/* Return the smallest n such that 2**n >= X.  */
extern int ceil_log2			(unsigned HOST_WIDE_INT);

Joseph Myers committed
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
#else /* GCC_VERSION >= 3004 */

/* For convenience, define 0 -> word_size.  */
static inline int
clz_hwi (unsigned HOST_WIDE_INT x)
{
  if (x == 0)
    return HOST_BITS_PER_WIDE_INT;
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  return __builtin_clzl (x);
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
  return __builtin_clzll (x);
# else
  return __builtin_clz (x);
# endif
}

static inline int
ctz_hwi (unsigned HOST_WIDE_INT x)
{
  if (x == 0)
    return HOST_BITS_PER_WIDE_INT;
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  return __builtin_ctzl (x);
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
  return __builtin_ctzll (x);
# else
  return __builtin_ctz (x);
# endif
}

static inline int
ffs_hwi (unsigned HOST_WIDE_INT x)
{
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  return __builtin_ffsl (x);
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
  return __builtin_ffsll (x);
# else
  return __builtin_ffs (x);
# endif
}

static inline int
281 282 283 284 285 286 287 288 289 290 291 292
popcount_hwi (unsigned HOST_WIDE_INT x)
{
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
  return __builtin_popcountl (x);
# elif HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONGLONG
  return __builtin_popcountll (x);
# else
  return __builtin_popcount (x);
# endif
}

static inline int
Joseph Myers committed
293 294 295 296 297 298
floor_log2 (unsigned HOST_WIDE_INT x)
{
  return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x);
}

static inline int
299 300 301 302 303 304
ceil_log2 (unsigned HOST_WIDE_INT x)
{
  return floor_log2 (x - 1) + 1;
}

static inline int
Joseph Myers committed
305 306 307 308 309 310 311
exact_log2 (unsigned HOST_WIDE_INT x)
{
  return x == (x & -x) && x ? ctz_hwi (x) : -1;
}

#endif /* GCC_VERSION >= 3004 */

312 313 314 315 316
#define HOST_WIDE_INT_MIN (HOST_WIDE_INT) \
  ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
#define HOST_WIDE_INT_MAX (~(HOST_WIDE_INT_MIN))

extern HOST_WIDE_INT abs_hwi (HOST_WIDE_INT);
317
extern unsigned HOST_WIDE_INT absu_hwi (HOST_WIDE_INT);
318 319 320 321
extern HOST_WIDE_INT gcd (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT pos_mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT, HOST_WIDE_INT);
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
322

323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
/* Sign extend SRC starting from PREC.  */

#ifdef ENABLE_CHECKING
extern HOST_WIDE_INT sext_hwi (HOST_WIDE_INT, unsigned int);
#else
static inline HOST_WIDE_INT
sext_hwi (HOST_WIDE_INT src, unsigned int prec)
{
  if (prec == HOST_BITS_PER_WIDE_INT)
    return src;
  else
    {
      int shift = HOST_BITS_PER_WIDE_INT - prec;
      return (src << shift) >> shift;
    }
}
#endif

/* Zero extend SRC starting from PREC.  */
#ifdef ENABLE_CHECKING
extern unsigned HOST_WIDE_INT zext_hwi (unsigned HOST_WIDE_INT, unsigned int);
#else
static inline unsigned HOST_WIDE_INT
zext_hwi (unsigned HOST_WIDE_INT src, unsigned int prec)
{
  if (prec == HOST_BITS_PER_WIDE_INT)
    return src;
  else
    return src & (((HOST_WIDE_INT)1 << prec) - 1);
}
#endif

355
#endif /* ! GCC_HWINT_H */