diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-01 00:57:00 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-09-01 00:57:00 +0000 |
commit | 7bb549d6b597b581a2f95496928612f2059e2df2 (patch) | |
tree | ec199c9556c74423f010c8bf0a32692e122dae0b /internal.h | |
parent | 8bd7af6794007dab448d71b78a13f0c1625858e9 (diff) | |
download | ruby-7bb549d6b597b581a2f95496928612f2059e2df2.tar.gz |
* internal.h (bit_length): Moved from bignum.c.
(nlz_int): Ditto.
(nlz_long): Ditto.
(nlz_long_long): Ditto.
(nlz_int128): Ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42750 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'internal.h')
-rw-r--r-- | internal.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/internal.h b/internal.h index f33059b985..ec5456c13a 100644 --- a/internal.h +++ b/internal.h @@ -106,6 +106,132 @@ extern "C" { # endif #endif +static inline int +nlz_int(unsigned int x) +{ +#if defined(HAVE_BUILTIN___BUILTIN_CLZ) + if (x == 0) return SIZEOF_INT * CHAR_BIT; + return __builtin_clz(x); +#else + 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 inline 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 inline 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;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (int)(n - x); +#endif +} +#endif + +#ifdef HAVE_UINT128_T +static inline int +nlz_int128(uint128_t x) +{ + uint128_t y; + int n = 128; + y = x >> 64; if (y) {n -= 64; x = y;} + y = x >> 32; if (y) {n -= 32; x = y;} + 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_UINT128_T) +# define bit_length(x) \ + (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 bit_length(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 bit_length(x) \ + (sizeof(x) <= SIZEOF_INT ? SIZEOF_INT * CHAR_BIT - nlz_int(x) : \ + SIZEOF_LONG * CHAR_BIT - nlz_long(x)) +#endif + struct rb_deprecated_classext_struct { char conflict[sizeof(VALUE) * 3]; }; |