aboutsummaryrefslogtreecommitdiffstats
path: root/insns.def
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-06-27 18:30:12 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-06-27 18:30:12 +0000
commit63dd5353570e111ce9ed0c1a0512b2d91377c601 (patch)
tree21cd5064d87baf768822e01c5e0e3826dc58d81b /insns.def
parent8b6cc970f242c3bea7e97e8b4118453b706b32a8 (diff)
downloadruby-63dd5353570e111ce9ed0c1a0512b2d91377c601.tar.gz
* 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
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def17
1 files changed, 6 insertions, 11 deletions
diff --git a/insns.def b/insns.def
index cdc82872ab..6a3a39cae8 100644
--- a/insns.def
+++ b/insns.def
@@ -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) &&