* insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow

compilers to use x86 LEA instruction (3 operand).
  Even if 3 operand LEA's latency is 3 cycle after SandyBridge,
  it reduces code size and can be faster because of super scalar.

* insns.def (opt_plus): calculate and use rb_int2big.
  On positive Fixnum overflow, `recv - 1 + obj` doesn't carry
  because recv's msb and obj's msb are 0, and resulted msb is 1.
  Therefore simply rshift and cast as signed long works fine.
  On negative Fixnum overflow, it will carry because both arguments'
  msb are 1, and resulted msb is also 1.
  In this case it needs to restore carried sign bit after rshift.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55515 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2016-06-27 18:30:12 +00:00
Родитель 4b31485ad8
Коммит 1e791f438b
2 изменённых файлов: 21 добавлений и 11 удалений

Просмотреть файл

@ -1,3 +1,18 @@
Tue Jun 28 02:41:32 2016 NARUSE, Yui <naruse@ruby-lang.org>
* insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow
compilers to use x86 LEA instruction (3 operand).
Even if 3 operand LEA's latency is 3 cycle after SandyBridge,
it reduces code size and can be faster because of super scalar.
* insns.def (opt_plus): calculate and use rb_int2big.
On positive Fixnum overflow, `recv - 1 + obj` doesn't carry
because recv's msb and obj's msb are 0, and resulted msb is 1.
Therefore simply rshift and cast as signed long works fine.
On negative Fixnum overflow, it will carry because both arguments'
msb are 1, and resulted msb is also 1.
In this case it needs to restore carried sign bit after rshift.
Mon Jun 27 16:58:32 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/fileutils.rb (FileUtils#install): accecpt symbolic mode, as

Просмотреть файл

@ -1381,18 +1381,13 @@ opt_plus
BASIC_OP_UNREDEFINED_P(BOP_PLUS,INTEGER_REDEFINED_OP_FLAG)) {
/* fixnum + fixnum */
#ifndef LONG_LONG_VALUE
val = (recv + (obj & (~1)));
if ((~(recv ^ obj) & (recv ^ val)) &
((VALUE)0x01 << ((sizeof(VALUE) * CHAR_BIT) - 1))) {
val = rb_big_plus(rb_int2big(FIX2LONG(recv)),
rb_int2big(FIX2LONG(obj)));
}
VALUE msb = (VALUE)1 << ((sizeof(VALUE) * CHAR_BIT) - 1);
val = recv - 1 + obj;
if ((~(recv ^ obj) & (recv ^ val)) & msb) {
val = rb_int2big((SIGNED_VALUE)((val>>1) | (recv & msb)));
}
#else
long a, b, c;
a = FIX2LONG(recv);
b = FIX2LONG(obj);
c = a + b;
val = LONG2NUM(c);
val = LONG2NUM(FIX2LONG(recv) + FIX2LONG(obj));
#endif
}
else if (FLONUM_2_P(recv, obj) &&