* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54203 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
57638377cc
commit
148f1b9d57
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
Sun Mar 20 20:10:14 2016 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* numeric.c (fix_gt, fix_ge, fix_lt, fix_le): optimize comparisons
|
||||
|
20
insns.def
20
insns.def
@ -1487,25 +1487,7 @@ opt_mult
|
||||
{
|
||||
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)) {
|
||||
|
28
internal.h
28
internal.h
@ -266,6 +266,34 @@ nlz_int128(uint128_t x)
|
||||
}
|
||||
#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.
|
||||
|
27
numeric.c
27
numeric.c
@ -3085,32 +3085,7 @@ static VALUE
|
||||
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);
|
||||
|
52
time.c
52
time.c
@ -91,61 +91,11 @@ sub(VALUE x, VALUE y)
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user