* 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>
|
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
|
* 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) &&
|
if (FIXNUM_2_P(recv, obj) &&
|
||||||
BASIC_OP_UNREDEFINED_P(BOP_MULT, FIXNUM_REDEFINED_OP_FLAG)) {
|
BASIC_OP_UNREDEFINED_P(BOP_MULT, FIXNUM_REDEFINED_OP_FLAG)) {
|
||||||
long a = FIX2LONG(recv);
|
val = rb_fix_mul_fix(recv, obj);
|
||||||
#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
|
|
||||||
}
|
}
|
||||||
else if (FLONUM_2_P(recv, obj) &&
|
else if (FLONUM_2_P(recv, obj) &&
|
||||||
BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
|
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
|
#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.
|
* This behaves different from C99 for negative arguments.
|
||||||
* Note that div may overflow fixnum.
|
* Note that div may overflow fixnum.
|
||||||
|
27
numeric.c
27
numeric.c
@ -3085,32 +3085,7 @@ static VALUE
|
|||||||
fix_mul(VALUE x, VALUE y)
|
fix_mul(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
if (FIXNUM_P(y)) {
|
if (FIXNUM_P(y)) {
|
||||||
#ifdef __HP_cc
|
return rb_fix_mul_fix(x, y);
|
||||||
/* 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
|
|
||||||
}
|
}
|
||||||
else if (RB_TYPE_P(y, T_BIGNUM)) {
|
else if (RB_TYPE_P(y, T_BIGNUM)) {
|
||||||
return rb_big_mul(y, x);
|
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);
|
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
|
static VALUE
|
||||||
mul(VALUE x, VALUE y)
|
mul(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
if (FIXNUM_P(x) && FIXNUM_P(y)) {
|
if (FIXNUM_P(x) && FIXNUM_P(y)) {
|
||||||
#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
|
rb_fix_mul_fix(x, y);
|
||||||
return LL2NUM((LONG_LONG)FIX2LONG(x) * FIX2LONG(y));
|
|
||||||
#else
|
|
||||||
long z;
|
|
||||||
if (long_mul(FIX2LONG(x), FIX2LONG(y), &z))
|
|
||||||
return LONG2NUM(z);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (RB_TYPE_P(x, T_BIGNUM))
|
if (RB_TYPE_P(x, T_BIGNUM))
|
||||||
return rb_big_mul(x, y);
|
return rb_big_mul(x, y);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user