[pypy-svn] pypy jit-longlong: Rewrite this without relying on llong_neg_ovf, a deprecated operation
arigo
commits-noreply at bitbucket.org
Fri Jan 7 22:07:17 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: jit-longlong
Changeset: r40473:7437ed40d6f9
Date: 2011-01-07 22:06 +0100
http://bitbucket.org/pypy/pypy/changeset/7437ed40d6f9/
Log: Rewrite this without relying on llong_neg_ovf, a deprecated
operation now removed.
diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py
--- a/pypy/rlib/test/test_rbigint.py
+++ b/pypy/rlib/test/test_rbigint.py
@@ -86,15 +86,18 @@
def test_args_from_int(self):
BASE = 1 << SHIFT
+ MAX = int(BASE-1)
assert rbigint.fromrarith_int(0).eq(rbigint([0], 0))
assert rbigint.fromrarith_int(17).eq(rbigint([17], 1))
- assert rbigint.fromrarith_int(BASE-1).eq(rbigint([intmask(BASE-1)], 1))
- assert rbigint.fromrarith_int(BASE).eq(rbigint([0, 1], 1))
- assert rbigint.fromrarith_int(BASE**2).eq(rbigint([0, 0, 1], 1))
+ assert rbigint.fromrarith_int(MAX).eq(rbigint([MAX], 1))
+ assert rbigint.fromrarith_int(r_longlong(BASE)).eq(rbigint([0, 1], 1))
+ assert rbigint.fromrarith_int(r_longlong(BASE**2)).eq(
+ rbigint([0, 0, 1], 1))
assert rbigint.fromrarith_int(-17).eq(rbigint([17], -1))
- assert rbigint.fromrarith_int(-(BASE-1)).eq(rbigint([intmask(BASE-1)], -1))
- assert rbigint.fromrarith_int(-BASE).eq(rbigint([0, 1], -1))
- assert rbigint.fromrarith_int(-(BASE**2)).eq(rbigint([0, 0, 1], -1))
+ assert rbigint.fromrarith_int(-MAX).eq(rbigint([MAX], -1))
+ assert rbigint.fromrarith_int(-MAX-1).eq(rbigint([0, 1], -1))
+ assert rbigint.fromrarith_int(r_longlong(-(BASE**2))).eq(
+ rbigint([0, 0, 1], -1))
# assert rbigint.fromrarith_int(-sys.maxint-1).eq((
# rbigint.digits_for_most_neg_long(-sys.maxint-1), -1)
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -165,6 +165,24 @@
assert t.BITS <= r_longlong.BITS
return build_int(None, t.SIGNED, r_longlong.BITS)
+def most_neg_value_of_same_type(x):
+ from pypy.rpython.lltypesystem import lltype
+ return most_neg_value_of(lltype.typeOf(x))
+most_neg_value_of_same_type._annspecialcase_ = 'specialize:argtype(0)'
+
+def most_neg_value_of(tp):
+ from pypy.rpython.lltypesystem import lltype, rffi
+ if tp is lltype.Signed:
+ return -sys.maxint-1
+ r_class = rffi.platform.numbertype_to_rclass[tp]
+ assert issubclass(r_class, base_int)
+ if r_class.SIGNED:
+ return r_class(-(r_class.MASK >> 1) - 1)
+ else:
+ return r_class(0)
+most_neg_value_of._annspecialcase_ = 'specialize:memo'
+
+
class base_int(long):
""" fake unsigned integer implementation """
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -1,5 +1,6 @@
from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen
+from pypy.rlib.rarithmetic import most_neg_value_of_same_type
from pypy.rlib.debug import make_sure_not_resized
import math, sys
@@ -612,19 +613,12 @@
return digits_from_nonneg_long(x), 1
elif x == 0:
return [0], 0
+ elif x != most_neg_value_of_same_type(x):
+ # normal case
+ return digits_from_nonneg_long(-x), -1
else:
- try:
- y = ovfcheck(-x)
- except OverflowError:
- y = -1
- # be conservative and check again if the result is >= 0, even
- # if no OverflowError was raised (e.g. broken CPython/GCC4.2)
- if y >= 0:
- # normal case
- return digits_from_nonneg_long(y), -1
- else:
- # the most negative integer! hacks needed...
- return digits_for_most_neg_long(x), -1
+ # the most negative integer! hacks needed...
+ return digits_for_most_neg_long(x), -1
args_from_rarith_int1._annspecialcase_ = "specialize:argtype(0)"
def args_from_rarith_int(x):
diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py
--- a/pypy/rlib/test/test_rarithmetic.py
+++ b/pypy/rlib/test/test_rarithmetic.py
@@ -394,3 +394,10 @@
def test_int_real_union():
from pypy.rpython.lltypesystem.rffi import r_int_real
assert compute_restype(r_int_real, r_int_real) is r_int_real
+
+def test_most_neg_value_of():
+ assert most_neg_value_of_same_type(123) == -sys.maxint-1
+ assert most_neg_value_of_same_type(r_uint(123)) == 0
+ llmin = -(2**(r_longlong.BITS-1))
+ assert most_neg_value_of_same_type(r_longlong(123)) == llmin
+ assert most_neg_value_of_same_type(r_ulonglong(123)) == 0
More information about the Pypy-commit
mailing list