summaryrefslogtreecommitdiff
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-06 22:43:01 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-06 22:43:01 +0000
commitd35596c61da633f539c02ecb78b5c6a9e923ddfc (patch)
tree667b73eb3c69cc438b041780711673b96bfb0beb /bignum.c
parent0650ecc3951090fc711915a98f1b6b0ffb0aeeda (diff)
* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42413 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c125
1 files changed, 75 insertions, 50 deletions
diff --git a/bignum.c b/bignum.c
index 1f295506d9..cfd8a0a820 100644
--- a/bignum.c
+++ b/bignum.c
@@ -149,14 +149,27 @@ 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;
+ 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;}
@@ -166,17 +179,26 @@ nlz16(uint16_t x)
}
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;
+nlz_long(unsigned long x)
+{
+#if defined(HAVE_BUILTIN___BUILTIN_CLZL)
+ if (x == 0) return SIZEOF_LONG * CHAR_BIT;
+ return __builtin_clzl(x);
#else
- uint32_t y;
+ 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;}
@@ -186,20 +208,28 @@ nlz32(uint32_t x)
#endif
}
-#if defined(HAVE_UINT64_T)
+#ifdef HAVE_LONG_LONG
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;
+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
- uint64_t y;
+ 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))