X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fhwint.h;h=1eadd45da73ace7e9ef1745cb4efe664dff23b11;hb=b622b5f5872f072c0625b5223713ea8a20e1864a;hp=c7fcd345bec84cc132cf33b9a00f67c81b1a8d2b;hpb=9c5b6e15021ce28bae0ea7a2afed31fdea871af0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/hwint.h b/gcc/hwint.h index c7fcd345bec..1eadd45da73 100644 --- a/gcc/hwint.h +++ b/gcc/hwint.h @@ -1,5 +1,6 @@ /* HOST_WIDE_INT definitions for the GNU compiler. - Copyright (C) 1998, 2002, 2004, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1998, 2002, 2004, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of GCC. @@ -157,4 +158,103 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1]; # define HOST_BITS_PER_WIDEST_FAST_INT HOST_BITS_PER_LONG #endif +/* 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); + +/* 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); + +#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 +floor_log2 (unsigned HOST_WIDE_INT x) +{ + return HOST_BITS_PER_WIDE_INT - 1 - clz_hwi (x); +} + +static inline int +exact_log2 (unsigned HOST_WIDE_INT x) +{ + return x == (x & -x) && x ? ctz_hwi (x) : -1; +} + +#endif /* GCC_VERSION >= 3004 */ + +/* Compute the greatest common divisor of two numbers using + Euclid's algorithm. */ + +static inline int +gcd (int a, int b) +{ + int x, y, z; + + x = abs (a); + y = abs (b); + + while (x > 0) + { + z = y % x; + y = x; + x = z; + } + + return y; +} + +/* Compute the least common multiple of two numbers A and B . */ + +static inline int +least_common_multiple (int a, int b) +{ + return (abs (a) * abs (b) / gcd (a, b)); +} + #endif /* ! GCC_HWINT_H */