From 1f57a334daa4cd27decdc756cd709163e00e6a0c Mon Sep 17 00:00:00 2001 From: naruse Date: Fri, 5 Feb 2016 04:31:27 +0000 Subject: * insns.def (opt_mult): Use int128_t for overflow detection. * bignum.c (rb_uint128t2big): added for opt_mult. * bignum.c (rb_uint128t2big): added for rb_uint128t2big.. * configure.in: define int128_t, uint128_t and related MACROs. Initially introduced by r41379 but reverted by r50749. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53741 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- bignum.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'bignum.c') diff --git a/bignum.c b/bignum.c index afd264adec..bc24764b88 100644 --- a/bignum.c +++ b/bignum.c @@ -4367,6 +4367,46 @@ rb_ll2inum(LONG_LONG n) #endif /* HAVE_LONG_LONG */ +#ifdef HAVE_INT128_T +static VALUE +rb_uint128t2big(uint128_t n) +{ + long i; + VALUE big = bignew(bdigit_roomof(SIZEOF_INT128_T), 1); + BDIGIT *digits = BDIGITS(big); + + for (i = 0; i < bdigit_roomof(SIZEOF_INT128_T); i++) { + digits[i] = BIGLO(RSHIFT(n ,BITSPERDIG*i)); + } + + i = bdigit_roomof(SIZEOF_INT128_T); + while (i-- && !digits[i]) ; + BIGNUM_SET_LEN(big, i+1); + return big; +} + +VALUE +rb_int128t2big(int128_t n) +{ + int neg = 0; + uint128_t u; + VALUE big; + + if (n < 0) { + u = 1 + (uint128_t)(-(n + 1)); /* u = -n avoiding overflow */ + neg = 1; + } + else { + u = n; + } + big = rb_uint128t2big(u); + if (neg) { + BIGNUM_SET_SIGN(big, 0); + } + return big; +} +#endif + VALUE rb_cstr2inum(const char *str, int base) { -- cgit v1.2.3