[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