diff options
Diffstat (limited to 'gcc/toplev.c')
| -rw-r--r-- | gcc/toplev.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c index afc43f8..4ce593a 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -537,20 +537,23 @@ read_integral_parameter (const char *p, const char *pname, const int defval) } /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. - If X is 0, return -1. - - This should be used via the floor_log2 macro. */ + If X is 0, return -1. */ int -floor_log2_wide (unsigned HOST_WIDE_INT x) +floor_log2 (unsigned HOST_WIDE_INT x) { - int t=0; + int t = 0; + if (x == 0) return -1; - if (sizeof (HOST_WIDE_INT) * 8 > 64) + +#ifdef CLZ_HWI + t = HOST_BITS_PER_WIDE_INT - 1 - (int) CLZ_HWI (x); +#else + if (HOST_BITS_PER_WIDE_INT > 64) if (x >= (unsigned HOST_WIDE_INT) 1 << (t + 64)) t += 64; - if (sizeof (HOST_WIDE_INT) * 8 > 32) + if (HOST_BITS_PER_WIDE_INT > 32) if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 32)) t += 32; if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 16)) @@ -563,21 +566,24 @@ floor_log2_wide (unsigned HOST_WIDE_INT x) t += 2; if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 1)) t += 1; +#endif + return t; } /* Return the logarithm of X, base 2, considering X unsigned, - if X is a power of 2. Otherwise, returns -1. - - This should be used via the `exact_log2' macro. */ + if X is a power of 2. Otherwise, returns -1. */ int -exact_log2_wide (unsigned HOST_WIDE_INT x) +exact_log2 (unsigned HOST_WIDE_INT x) { - /* Test for 0 or a power of 2. */ - if (x == 0 || x != (x & -x)) + if (x != (x & -x)) return -1; - return floor_log2_wide (x); +#ifdef CTZ_HWI + return x ? CTZ_HWI (x) : -1; +#else + return floor_log2 (x); +#endif } /* Handler for fatal signals, such as SIGSEGV. These are transformed |
