diff --git a/ChangeLog b/ChangeLog index c23170a2c7..9e5ac108cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Wed Aug 7 07:38:39 2013 Tanaka Akira + + * bignum.c (nlz16): Removed. + (nlz32): Ditto. + (nlz64): Ditto. + (nlz128): Ditto. + (nlz_int): New function. + (nlz_long): New function. + (nlz_long_long): New function. + (nlz_int128): New function. + (nlz): Follow above changes. + (bitsize): Follow above changes. + Tue Aug 6 22:38:15 2013 Zachary Scott * time.c: [DOC] Typo in Time overview by @sparr [Fixes GH-374] diff --git a/bignum.c b/bignum.c index 1f295506d9..cfd8a0a820 100644 --- a/bignum.c +++ b/bignum.c @@ -149,57 +149,87 @@ static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *mo static inline VALUE power_cache_get_power(int base, int power_level, size_t *numdigits_ret); static int -nlz16(uint16_t x) +nlz_int(unsigned int x) { -#if defined(HAVE_BUILTIN___BUILTIN_CLZ) && 2 <= SIZEOF_INT - if (x == 0) return 16; - return __builtin_clz(x) - (SIZEOF_INT-2)*CHAR_BIT; +#if defined(HAVE_BUILTIN___BUILTIN_CLZ) + if (x == 0) return SIZEOF_INT * CHAR_BIT; + return __builtin_clz(x); #else - uint16_t y; - int n = 16; - y = x >> 8; if (y) {n -= 8; x = y;} - y = x >> 4; if (y) {n -= 4; x = y;} - y = x >> 2; if (y) {n -= 2; x = y;} - y = x >> 1; if (y) {return n - 2;} - return (int)(n - x); -#endif -} - -static int -nlz32(uint32_t x) -{ -#if defined(HAVE_BUILTIN___BUILTIN_CLZ) && 4 <= SIZEOF_INT - if (x == 0) return 32; - return __builtin_clz(x) - (SIZEOF_INT-4)*CHAR_BIT; -#elif defined(HAVE_BUILTIN___BUILTIN_CLZL) && 4 <= SIZEOF_LONG - if (x == 0) return 32; - return __builtin_clzl(x) - (SIZEOF_LONG-4)*CHAR_BIT; -#else - uint32_t y; - int n = 32; - y = x >> 16; if (y) {n -= 16; x = y;} - y = x >> 8; if (y) {n -= 8; x = y;} - y = x >> 4; if (y) {n -= 4; x = y;} - y = x >> 2; if (y) {n -= 2; x = y;} - y = x >> 1; if (y) {return n - 2;} - return (int)(n - x); -#endif -} - -#if defined(HAVE_UINT64_T) -static int -nlz64(uint64_t x) -{ -#if defined(HAVE_BUILTIN___BUILTIN_CLZL) && 8 <= SIZEOF_LONG - if (x == 0) return 64; - return __builtin_clzl(x) - (SIZEOF_LONG-8)*CHAR_BIT; -#elif defined(HAVE_BUILTIN___BUILTIN_CLZLL) && 8 <= SIZEOF_LONG_LONG - if (x == 0) return 64; - return __builtin_clzll(x) - (SIZEOF_LONG_LONG-8)*CHAR_BIT; -#else - uint64_t y; + unsigned int y; +# if 64 < SIZEOF_INT * CHAR_BIT + int n = 128; +# elif 32 < SIZEOF_INT * CHAR_BIT int n = 64; +# else + int n = 32; +# endif +# if 64 < SIZEOF_INT * CHAR_BIT + y = x >> 64; if (y) {n -= 64; x = y;} +# endif +# if 32 < SIZEOF_INT * CHAR_BIT y = x >> 32; if (y) {n -= 32; x = y;} +# endif + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +#endif +} + +static int +nlz_long(unsigned long x) +{ +#if defined(HAVE_BUILTIN___BUILTIN_CLZL) + if (x == 0) return SIZEOF_LONG * CHAR_BIT; + return __builtin_clzl(x); +#else + unsigned long y; +# if 64 < SIZEOF_LONG * CHAR_BIT + int n = 128; +# elif 32 < SIZEOF_LONG * CHAR_BIT + int n = 64; +# else + int n = 32; +# endif +# if 64 < SIZEOF_LONG * CHAR_BIT + y = x >> 64; if (y) {n -= 64; x = y;} +# endif +# if 32 < SIZEOF_LONG * CHAR_BIT + y = x >> 32; if (y) {n -= 32; x = y;} +# endif + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +#endif +} + +#ifdef HAVE_LONG_LONG +static int +nlz_long_long(unsigned LONG_LONG x) +{ +#if defined(HAVE_BUILTIN___BUILTIN_CLZLL) + if (x == 0) return SIZEOF_LONG_LONG * CHAR_BIT; + return __builtin_clzll(x); +#else + unsigned LONG_LONG y; +# if 64 < SIZEOF_LONG_LONG * CHAR_BIT + int n = 128; +# elif 32 < SIZEOF_LONG_LONG * CHAR_BIT + int n = 64; +# else + int n = 32; +# endif +# if 64 < SIZEOF_LONG_LONG * CHAR_BIT + y = x >> 64; if (y) {n -= 64; x = y;} +# endif +# if 32 < SIZEOF_LONG_LONG * CHAR_BIT + y = x >> 32; if (y) {n -= 32; x = y;} +# endif y = x >> 16; if (y) {n -= 16; x = y;} y = x >> 8; if (y) {n -= 8; x = y;} y = x >> 4; if (y) {n -= 4; x = y;} @@ -210,14 +240,10 @@ nlz64(uint64_t x) } #endif -#if defined(HAVE_UINT128_T) +#ifdef HAVE_UINT128_T static int -nlz128(uint128_t x) +nlz_int128(uint128_t x) { -#if defined(HAVE_BUILTIN___BUILTIN_CLZLL) && 16 <= SIZEOF_LONG_LONG - if (x == 0) return 128; - return __builtin_clzll(x) - (SIZEOF_LONG_LONG-16)*CHAR_BIT; -#else uint128_t y; int n = 128; y = x >> 64; if (y) {n -= 64; x = y;} @@ -228,35 +254,34 @@ nlz128(uint128_t x) y = x >> 2; if (y) {n -= 2; x = y;} y = x >> 1; if (y) {return n - 2;} return (int)(n - x); -#endif } #endif -#if SIZEOF_BDIGITS == 2 -static int nlz(BDIGIT x) { return nlz16((uint16_t)x); } -#elif SIZEOF_BDIGITS == 4 -static int nlz(BDIGIT x) { return nlz32((uint32_t)x); } -#elif SIZEOF_BDIGITS == 8 -static int nlz(BDIGIT x) { return nlz64((uint64_t)x); } -#elif SIZEOF_BDIGITS == 16 -static int nlz(BDIGIT x) { return nlz128((uint128_t)x); } +#if SIZEOF_BDIGITS <= SIZEOF_INT +static int nlz(BDIGIT x) { return nlz_int((unsigned int)x) - (SIZEOF_INT-SIZEOF_BDIGITS) * CHAR_BIT; } +#elif SIZEOF_BDIGITS <= SIZEOF_LONG +static int nlz(BDIGIT x) { return nlz_long((unsigned long)x) - (SIZEOF_LONG-SIZEOF_BDIGITS) * CHAR_BIT; } +#elif SIZEOF_BDIGITS <= SIZEOF_LONG_LONG +static int nlz(BDIGIT x) { return nlz_long_long((unsigned LONG_LONG)x) - (SIZEOF_LONG_LONG-SIZEOF_BDIGITS) * CHAR_BIT; } +#elif SIZEOF_BDIGITS <= SIZEOF_INT128_T +static int nlz(BDIGIT x) { return nlz_int128((uint128_t)x) - (SIZEOF_INT128_T-SIZEOF_BDIGITS) * CHAR_BIT; } #endif #if defined(HAVE_UINT128_T) # define bitsize(x) \ - (sizeof(x) <= 2 ? 16 - nlz16(x) : \ - sizeof(x) <= 4 ? 32 - nlz32(x) : \ - sizeof(x) <= 8 ? 64 - nlz64(x) : \ - 128 - nlz128(x)) -#elif defined(HAVE_UINT64_T) + (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int(x) : \ + sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long(x) : \ + sizeof(x) <= SIZEOF_LONG_LONG ? SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long(x) : \ + SIZEOF_INT128_T * CHAR_BIT - nlz_int128(x)) +#elif defined(HAVE_LONG_LONG) # define bitsize(x) \ - (sizeof(x) <= 2 ? 16 - nlz16(x) : \ - sizeof(x) <= 4 ? 32 - nlz32(x) : \ - 64 - nlz64(x)) + (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int(x) : \ + sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long(x) : \ + SIZEOF_LONG_LONG * CHAR_BIT - nlz_long_long(x)) #else # define bitsize(x) \ - (sizeof(x) <= 2 ? 16 - nlz16(x) : \ - 32 - nlz32(x)) + (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int(x) : \ + sizeof(x) <= SIZEOF_LONG ? SIZEOF_LONG * CHAR_BIT - nlz_long(x)) #endif #define U16(a) ((uint16_t)(a))