* 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
This commit is contained in:
naruse 2016-02-05 04:31:27 +00:00
parent b658249cef
commit 1f57a334da
4 changed files with 72 additions and 8 deletions

View file

@ -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)
{