ruby-changes:42129
From: naruse <ko1@a...>
Date: Sun, 20 Mar 2016 20:10:49 +0900 (JST)
Subject: [ruby-changes:42129] naruse:r54203 (trunk): * internal.h (DLONG): defined if long is 32bit (and LONG_LONG is 64bit;
naruse 2016-03-20 20:10:43 +0900 (Sun, 20 Mar 2016) New Revision: 54203 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54203 Log: * internal.h (DLONG): defined if long is 32bit (and LONG_LONG is 64bit; but LONG_LONG is always defined as 64bit), or there's int128_t. * internal.h (DL2NUM): defined if DLONG is defined. * internal.h (rb_fix_mul_fix): defined for `Fixnum * Fixnum`. * insns.def (opt_mul): use rb_fix_mul_fix(). * numeric.c (fix_mul): ditto. * time.c (mul): ditto. Modified files: trunk/ChangeLog trunk/insns.def trunk/internal.h trunk/numeric.c trunk/time.c Index: insns.def =================================================================== --- insns.def (revision 54202) +++ insns.def (revision 54203) @@ -1487,25 +1487,7 @@ opt_mult https://github.com/ruby/ruby/blob/trunk/insns.def#L1487 { if (FIXNUM_2_P(recv, obj) && BASIC_OP_UNREDEFINED_P(BOP_MULT, FIXNUM_REDEFINED_OP_FLAG)) { - long a = FIX2LONG(recv); -#ifdef HAVE_INT128_T - VALUE rb_int128t2big(int128_t n); - int128_t r = (int128_t)a * (int128_t)FIX2LONG(obj); - if (RB_FIXABLE(r)) { - val = LONG2FIX((long)r); - } - else { - val = rb_int128t2big(r); - } -#else - long b = FIX2LONG(obj); - if (MUL_OVERFLOW_FIXNUM_P(a, b)) { - val = rb_big_mul(rb_int2big(a), rb_int2big(b)); - } - else { - val = LONG2FIX(a * b); - } -#endif + val = rb_fix_mul_fix(recv, obj); } else if (FLONUM_2_P(recv, obj) && BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) { Index: ChangeLog =================================================================== --- ChangeLog (revision 54202) +++ ChangeLog (revision 54203) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sun Mar 20 20:10:14 2016 NARUSE, Yui <naruse@r...> + + * internal.h (DLONG): defined if long is 32bit (and LONG_LONG is 64bit; + but LONG_LONG is always defined as 64bit), or there's int128_t. + + * internal.h (DL2NUM): defined if DLONG is defined. + + * internal.h (rb_fix_mul_fix): defined for `Fixnum * Fixnum`. + + * insns.def (opt_mul): use rb_fix_mul_fix(). + + * numeric.c (fix_mul): ditto. + + * time.c (mul): ditto. + Sun Mar 20 18:53:49 2016 Nobuyoshi Nakada <nobu@r...> * numeric.c (fix_gt, fix_ge, fix_lt, fix_le): optimize comparisons Index: internal.h =================================================================== --- internal.h (revision 54202) +++ internal.h (revision 54203) @@ -266,6 +266,34 @@ nlz_int128(uint128_t x) https://github.com/ruby/ruby/blob/trunk/internal.h#L266 } #endif +#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG +# define DLONG LONG_LONG +# define DL2NUM(x) LL2NUM(x) +#elif defined(HAVE_INT128_T) +# define DLONG int128_t +# define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x)) +#endif + +VALUE rb_int128t2big(int128_t n); + +/* arguments must be Fixnum */ +static inline VALUE +rb_fix_mul_fix(VALUE x, VALUE y) +{ + long lx = FIX2LONG(x); + long ly = FIX2LONG(y); +#ifdef DLONG + return DL2NUM((DLONG)lx * (DLONG)ly); +#else + if (MUL_OVERFLOW_FIXNUM_P(a, b)) { + return rb_big_mul(rb_int2big(a), rb_int2big(b)); + } + else { + return LONG2FIX(a * b); + } +#endif +} + /* * This behaves different from C99 for negative arguments. * Note that div may overflow fixnum. Index: time.c =================================================================== --- time.c (revision 54202) +++ time.c (revision 54203) @@ -91,61 +91,11 @@ sub(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/time.c#L91 return rb_funcall(x, '-', 1, y); } -#if !(HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG) -static int -long_mul(long x, long y, long *z) -{ - unsigned long a, b, c; - int s; - if (x == 0 || y == 0) { - *z = 0; - return 1; - } - if (x < 0) { - s = -1; - a = (unsigned long)-x; - } - else { - s = 1; - a = (unsigned long)x; - } - if (y < 0) { - s = -s; - b = (unsigned long)-y; - } - else { - b = (unsigned long)y; - } - if (a <= ULONG_MAX / b) { - c = a * b; - if (s < 0) { - if (c <= (unsigned long)LONG_MAX + 1) { - *z = -(long)c; - return 1; - } - } - else { - if (c <= (unsigned long)LONG_MAX) { - *z = (long)c; - return 1; - } - } - } - return 0; -} -#endif - static VALUE mul(VALUE x, VALUE y) { if (FIXNUM_P(x) && FIXNUM_P(y)) { -#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG - return LL2NUM((LONG_LONG)FIX2LONG(x) * FIX2LONG(y)); -#else - long z; - if (long_mul(FIX2LONG(x), FIX2LONG(y), &z)) - return LONG2NUM(z); -#endif + rb_fix_mul_fix(x, y); } if (RB_TYPE_P(x, T_BIGNUM)) return rb_big_mul(x, y); Index: numeric.c =================================================================== --- numeric.c (revision 54202) +++ numeric.c (revision 54203) @@ -3085,32 +3085,7 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/numeric.c#L3085 fix_mul(VALUE x, VALUE y) { if (FIXNUM_P(y)) { -#ifdef __HP_cc -/* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */ - volatile -#endif - long a, b; -#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG - LONG_LONG d; -#else - VALUE r; -#endif - - a = FIX2LONG(x); - b = FIX2LONG(y); - -#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG - d = (LONG_LONG)a * b; - if (FIXABLE(d)) return LONG2FIX(d); - return rb_ll2inum(d); -#else - if (a == 0) return x; - if (MUL_OVERFLOW_FIXNUM_P(a, b)) - r = rb_big_mul(rb_int2big(a), rb_int2big(b)); - else - r = LONG2FIX(a * b); - return r; -#endif + return rb_fix_mul_fix(x, y); } else if (RB_TYPE_P(y, T_BIGNUM)) { return rb_big_mul(y, x); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/