Author: stian
Branch: improve-rbigint
Changeset: r56331:14ff425f3744
Date: 2012-06-25 06:58 +0200
http://bitbucket.org/pypy/pypy/changeset/14ff425f3744/

Log:    Introduce int128 and int cache.

        Also find a new karatsuba cutoff that is fine with the new settings.
        Some things are slower (especially creating new ints). But
        generally, it's a major speedup. 4 failing tests, mostly due to not
        being able to cast down to int. Hash is also wrong (critical).

        Not JIT support yet I suppose.

diff --git a/pypy/jit/codewriter/jtransform.py 
b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -462,6 +462,11 @@
     rewrite_op_llong_floordiv_zer = _do_builtin_call
     rewrite_op_llong_mod          = _do_builtin_call
     rewrite_op_llong_mod_zer      = _do_builtin_call
+    rewrite_op_lllong_abs          = _do_builtin_call
+    rewrite_op_lllong_floordiv     = _do_builtin_call
+    rewrite_op_lllong_floordiv_zer = _do_builtin_call
+    rewrite_op_lllong_mod          = _do_builtin_call
+    rewrite_op_lllong_mod_zer      = _do_builtin_call
     rewrite_op_ullong_floordiv     = _do_builtin_call
     rewrite_op_ullong_floordiv_zer = _do_builtin_call
     rewrite_op_ullong_mod          = _do_builtin_call
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -250,6 +250,101 @@
 
 _ll_1_ll_math_ll_math_sqrt = ll_math.ll_math_sqrt
 
+# long long long support
+# -----------------
+
+def u_to_longlonglong(x):
+    return rffi.cast(lltype.SignedLongLongLong, x)
+
+def _ll_1_lllong_invert(xll):
+    y = ~r_ulonglonglong(xll)
+    return u_to_longlonglong(y)
+
+def _ll_2_lllong_lt(xll, yll):
+    return xll < yll
+
+def _ll_2_lllong_le(xll, yll):
+    return xll <= yll
+
+def _ll_2_lllong_eq(xll, yll):
+    return xll == yll
+
+def _ll_2_lllong_ne(xll, yll):
+    return xll != yll
+
+def _ll_2_lllong_gt(xll, yll):
+    return xll > yll
+
+def _ll_2_lllong_ge(xll, yll):
+    return xll >= yll
+
+def _ll_2_lllong_add(xull, yull):
+    z = (xull) + (yull)
+    return (z)
+
+def _ll_2_lllong_sub(xull, yull):
+    z = (xull) - (yull)
+    return (z)
+
+def _ll_2_lllong_mul(xull, yull):
+    z = (xull) * (yull)
+    return (z)
+
+def _ll_2_lllong_and(xull, yull):
+    z = (xull) & (yull)
+    return (z)
+
+def _ll_2_lllong_or(xull, yull):
+    z = (xull) | (yull)
+    return (z)
+
+def _ll_2_lllong_xor(xull, yull):
+    z = (xull) ^ (yull)
+    return (z)
+
+def _ll_2_lllong_lshift(xlll, y):
+    return xll << y
+
+def _ll_2_lllong_rshift(xlll, y):
+    return xll >> y
+
+def _ll_1_lllong_from_int(x):
+    return r_longlonglong(intmask(x))
+
+def _ll_1_lllong_from_uint(x):
+    return r_longlonglong(r_uint(x))
+
+def _ll_1_lllong_to_int(xlll):
+    return intmask(xll)
+
+def _ll_1_lllong_from_float(xf):
+    return r_longlonglong(xf)
+
+def _ll_1_llong_to_float(xll):
+    return float(rffi.cast(lltype.SignedLongLongLong, xlll))
+
+def _ll_1_llong_abs(xll):
+    if xll < 0:
+        return -xll
+    else:
+        return xll
+
+def _ll_2_llong_floordiv(xll, yll):
+    return llop.lllong_floordiv(lltype.SignedLongLongLong, xll, yll)
+
+def _ll_2_llong_floordiv_zer(xll, yll):
+    if yll == 0:
+        raise ZeroDivisionError
+    return llop.lllong_floordiv(lltype.SignedLongLongLong, xll, yll)
+
+def _ll_2_llong_mod(xll, yll):
+    return llop.lllong_mod(lltype.SignedLongLongLong, xll, yll)
+
+def _ll_2_llong_mod_zer(xll, yll):
+    if yll == 0:
+        raise ZeroDivisionError
+    return llop.lllong_mod(lltype.SignedLongLongLong, xll, yll)
+
 
 # long long support
 # -----------------
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -87,6 +87,10 @@
     LONG_BIT_SHIFT += 1
     assert LONG_BIT_SHIFT < 99, "LONG_BIT_SHIFT value not found?"
 
+LONGLONGLONG_BIT  = 128
+LONGLONGLONG_MASK = (2**LONGLONGLONG_BIT)-1
+LONGLONGLONG_TEST = 2**(LONGLONGLONG_BIT-1)
+
 """
 int is no longer necessarily the same size as the target int.
 We therefore can no longer use the int type as it is, but need
@@ -122,6 +126,17 @@
         n -= 2*LONGLONG_TEST
     return r_longlong(n)
 
+def longlonglongmask(n):
+    """
+    NOT_RPYTHON
+    """
+    assert isinstance(n, (int, long))
+    n = long(n)
+    n &= LONGLONGLONG_MASK
+    if n >= LONGLONGLONG_TEST:
+        n -= 2*LONGLONGLONG_TEST
+    return r_longlonglong(n)
+
 def widen(n):
     from pypy.rpython.lltypesystem import lltype
     if _should_widen_type(lltype.typeOf(n)):
@@ -475,6 +490,7 @@
 r_longlong = build_int('r_longlong', True, 64)
 r_ulonglong = build_int('r_ulonglong', False, 64)
 
+r_longlonglong = build_int('r_longlonglong', True, 128)
 longlongmax = r_longlong(LONGLONG_TEST - 1)
 
 if r_longlong is not r_int:
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -1,4 +1,4 @@
-from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
+from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, 
r_ulonglong, r_longlonglong
 from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int
 from pypy.rlib.rarithmetic import most_neg_value_of_same_type
 from pypy.rlib.rfloat import isfinite
@@ -15,11 +15,12 @@
 # a sign bit plus two digits plus 1 overflow bit.
 
 #SHIFT = (LONG_BIT // 2) - 1
-SHIFT = 31
+SHIFT = 63
 
 MASK = int((1 << SHIFT) - 1)
 FLOAT_MULTIPLIER = float(1 << LONG_BIT) # Because it works.
 
+CACHE_INTS = 1024 # CPython do 256
 
 # Debugging digit array access.
 #
@@ -33,7 +34,7 @@
 
 # Karatsuba is O(N**1.585)
 USE_KARATSUBA = True # set to False for comparison
-KARATSUBA_CUTOFF = 38
+KARATSUBA_CUTOFF = 19 #38
 KARATSUBA_SQUARE_CUTOFF = 2 * KARATSUBA_CUTOFF
 
 USE_TOOMCOCK = False # WIP
@@ -48,30 +49,36 @@
 
 
 def _mask_digit(x):
-    return intmask(x & MASK)
+    return longlongmask(x & MASK) #intmask(x & MASK)
 _mask_digit._annspecialcase_ = 'specialize:argtype(0)'
 
 def _widen_digit(x):
-    if not we_are_translated():
-        assert is_valid_int(x), "widen_digit() takes an int, got a %r" % 
type(x)
-    if LONG_BIT < 64:
+    """if not we_are_translated():
+        assert is_valid_int(x), "widen_digit() takes an int, got a %r" % 
type(x)"""
+    return r_longlonglong(x)
+    """if LONG_BIT < 64:
         return r_longlong(x)
-    return x
+    return x"""
 
 def _store_digit(x):
-    if not we_are_translated():
-        assert is_valid_int(x), "store_digit() takes an int, got a %r" % 
type(x)
+    """if not we_are_translated():
+        assert is_valid_int(x), "store_digit() takes an int, got a %r" % 
type(x)"""
     if SHIFT <= 15:
         return rffi.cast(rffi.SHORT, x)
     elif SHIFT <= 31:
         return rffi.cast(rffi.INT, x)
+    elif SHIFT <= 63:
+        return int(x)
+        #return rffi.cast(rffi.LONGLONG, x)
     else:
         raise ValueError("SHIFT too large!")
 
 def _load_digit(x):
-    return rffi.cast(lltype.Signed, x)
+    return x
+    #return rffi.cast(lltype.Signed, x)
 
 def _load_unsigned_digit(x):
+    #return r_ulonglong(x)
     return rffi.cast(lltype.Unsigned, x)
 
 NULLDIGIT = _store_digit(0)
@@ -80,7 +87,9 @@
 def _check_digits(l):
     for x in l:
         assert type(x) is type(NULLDIGIT)
-        assert intmask(x) & MASK == intmask(x)
+        # XXX: Fix for int128
+        # assert intmask(x) & MASK == intmask(x)
+            
 class Entry(extregistry.ExtRegistryEntry):
     _about_ = _check_digits
     def compute_result_annotation(self, s_list):
@@ -91,7 +100,6 @@
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
 
-
 class rbigint(object):
     """This is a reimplementation of longs using a list of digits."""
 
@@ -129,6 +137,12 @@
         # This function is marked as pure, so you must not call it and
         # then modify the result.
         check_regular_int(intval)
+        
+        cache = False
+        
+        if intval != 0 and intval < CACHE_INTS and intval > -CACHE_INTS:
+            return INTCACHE[intval]
+            
         if intval < 0:
             sign = -1
             ival = r_uint(-intval)
@@ -141,6 +155,14 @@
         # We used to pick 5 ("big enough for anything"), but that's a
         # waste of time and space given that 5*15 = 75 bits are rarely
         # needed.
+        # XXX: Even better!
+        if SHIFT >= 63:
+            carry = ival >> SHIFT
+            if carry:
+                return rbigint([intmask((ival)), intmask(carry)], sign)
+            else:
+                return rbigint([intmask(ival)], sign)
+            
         t = ival
         ndigits = 0
         while t:
@@ -153,6 +175,7 @@
             v.setdigit(p, t)
             t >>= SHIFT
             p += 1
+
         return v
 
     @staticmethod
@@ -250,7 +273,7 @@
             x = (x << SHIFT) + self.udigit(i)
             if (x >> SHIFT) != prev:
                 raise OverflowError(
-                        "long int too large to convert to unsigned int")
+                        "long int too large to convert to unsigned int (%d, 
%d)" % (x >> SHIFT, prev))
             i -= 1
         return x
 
@@ -379,13 +402,22 @@
         if a.sign == 0 or b.sign == 0:
             return rbigint()
         
+        
         if asize == 1:
-            digit = a.digit(0)
+            digit = a.widedigit(0)
             if digit == 0:
                 return rbigint()
             elif digit == 1:
                 return rbigint(b._digits[:], a.sign * b.sign)
-            
+            elif bsize == 1:
+                result = rbigint([NULLDIGIT] * 2, a.sign * b.sign)
+                carry = b.widedigit(0) * digit
+                result.setdigit(0, carry)
+                carry >>= SHIFT
+                if carry:
+                    result.setdigit(1, carry)
+                return result
+                
             result =  _x_mul(a, b, digit)
         elif USE_TOOMCOCK and asize >= TOOMCOOK_CUTOFF:
             result = _tc_mul(a, b)
@@ -494,8 +526,7 @@
             #     base = base % modulus
             # Having the base positive just makes things easier.
             if a.sign < 0:
-                a, temp = a.divmod(c)
-                a = temp
+                a = a.mod(c)
                 
             
         elif size_b == 1 and a.sign == 1:
@@ -518,7 +549,7 @@
         
         # python adaptation: moved macros REDUCE(X) and MULT(X, Y, result)
         # into helper function result = _help_mult(x, y, c)
-        if not c or size_b <= FIVEARY_CUTOFF:
+        if True: #not c or size_b <= FIVEARY_CUTOFF:
             # Left-to-right binary exponentiation (HAC Algorithm 14.79)
             # http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
             size_b -= 1
@@ -533,6 +564,7 @@
                 size_b -= 1
                 
         else:
+            # XXX: Not working with int128!
             # Left-to-right 5-ary exponentiation (HAC Algorithm 14.82)
             # This is only useful in the case where c != None.
             # z still holds 1L
@@ -605,8 +637,11 @@
 
         oldsize = self.numdigits()
         newsize = oldsize + wordshift
-        if remshift:
-            newsize += 1
+        if not remshift:
+            return rbigint([NULLDIGIT] * wordshift + self._digits, self.sign)
+            
+        newsize += 1
+        
         z = rbigint([NULLDIGIT] * newsize, self.sign)
         accum = _widen_digit(0)
         i = wordshift
@@ -748,6 +783,12 @@
         return "<rbigint digits=%s, sign=%s, %s>" % (self._digits,
                                                      self.sign, self.str())
 
+INTCACHE = {}
+for x in range(1, CACHE_INTS):
+    numList = [_store_digit(x)]
+    INTCACHE[x] = rbigint(numList, 1)
+    INTCACHE[-x] = rbigint(numList, -1)
+    
 ONERBIGINT = rbigint([ONEDIGIT], 1)
 NULLRBIGINT = rbigint()
 
@@ -765,7 +806,7 @@
     # Perform a modular reduction, X = X % c, but leave X alone if c
     # is NULL.
     if c is not None:
-        temp, res = res.divmod(c)
+        res = res.mod(c)
         
     return res
 
@@ -835,7 +876,7 @@
         size_a, size_b = size_b, size_a
     z = rbigint([NULLDIGIT] * (size_a + 1), 1)
     i = 0
-    carry = r_uint(0)
+    carry = r_ulonglong(0)
     while i < size_b:
         carry += a.udigit(i) + b.udigit(i)
         z.setdigit(i, carry)
@@ -879,7 +920,7 @@
         size_a = size_b = i+1
         
     z = rbigint([NULLDIGIT] * size_a, sign)
-    borrow = r_uint(0)
+    borrow = r_ulonglong(0)
     i = 0
     while i < size_b:
         # The following assumes unsigned arithmetic
@@ -901,9 +942,9 @@
 
 # A neat little table of power of twos.
 ptwotable = {}
-for x in range(SHIFT):
-    ptwotable[2 << x] = x+1
-    ptwotable[-2 << x] = x+1
+for x in range(SHIFT-1):
+    ptwotable[r_longlong(2 << x)] = x+1
+    ptwotable[r_longlong(-2 << x)] = x+1
     
 def _x_mul(a, b, digit=0):
     """
@@ -943,7 +984,7 @@
                 z.setdigit(pz, carry)
                 pz += 1
                 carry >>= SHIFT
-                assert carry <= (_widen_digit(MASK) << 1)
+                #assert carry <= (_widen_digit(MASK) << 1)
             if carry:
                 carry += z.widedigit(pz)
                 z.setdigit(pz, carry)
@@ -1365,10 +1406,6 @@
 def _muladd1(a, n, extra=0):
     """Multiply by a single digit and add a single digit, ignoring the sign.
     """
-    
-    # Special case this one. 
-    if n == 1 and not extra:
-        return a
 
     size_a = a.numdigits()
     z = rbigint([NULLDIGIT] * (size_a+1), 1)
@@ -1387,9 +1424,10 @@
 def _x_divrem(v1, w1):
     """ Unsigned bigint division with remainder -- the algorithm """
     size_w = w1.numdigits()
-    d = (r_uint(MASK)+1) // (w1.udigit(size_w-1) + 1)
+    d = (r_ulonglong(MASK)+1) // (w1.udigit(size_w-1) + 1)
     assert d <= MASK    # because the first digit of w1 is not zero
-    d = intmask(d)
+    d = longlongmask(d)
+    assert d != 0
     v = _muladd1(v1, d)
     w = _muladd1(w1, d)
     size_v = v.numdigits()
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
@@ -140,19 +140,20 @@
 #            rbigint.digits_for_most_neg_long(-sys.maxint-1), -1)
 
     def test_args_from_int(self):
-        BASE = 1 << SHIFT
+        BASE = 1 << 31 # Can't can't shift here. Shift might be from 
longlonglong
         MAX = int(BASE-1)
         assert rbigint.fromrarith_int(0).eq(bigint([0], 0))
         assert rbigint.fromrarith_int(17).eq(bigint([17], 1))
         assert rbigint.fromrarith_int(MAX).eq(bigint([MAX], 1))
-        assert rbigint.fromrarith_int(r_longlong(BASE)).eq(bigint([0, 1], 1))
+        # No longer true.
+        """assert rbigint.fromrarith_int(r_longlong(BASE)).eq(bigint([0, 1], 
1))
         assert rbigint.fromrarith_int(r_longlong(BASE**2)).eq(
-            bigint([0, 0, 1], 1))
+            bigint([0, 0, 1], 1))"""
         assert rbigint.fromrarith_int(-17).eq(bigint([17], -1))
         assert rbigint.fromrarith_int(-MAX).eq(bigint([MAX], -1))
-        assert rbigint.fromrarith_int(-MAX-1).eq(bigint([0, 1], -1))
+        """assert rbigint.fromrarith_int(-MAX-1).eq(bigint([0, 1], -1))
         assert rbigint.fromrarith_int(r_longlong(-(BASE**2))).eq(
-            bigint([0, 0, 1], -1))
+            bigint([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/rpython/lltypesystem/lloperation.py 
b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -329,6 +329,30 @@
     'ullong_rshift':        LLOp(canfold=True),  # args (r_ulonglong, int)
     'ullong_xor':           LLOp(canfold=True),
 
+    'lllong_is_true':        LLOp(canfold=True),
+    'lllong_neg':            LLOp(canfold=True),
+    'lllong_abs':            LLOp(canfold=True),
+    'lllong_invert':         LLOp(canfold=True),
+
+    'lllong_add':            LLOp(canfold=True),
+    'lllong_sub':            LLOp(canfold=True),
+    'lllong_mul':            LLOp(canfold=True),
+    'lllong_floordiv':       LLOp(canfold=True),
+    'lllong_floordiv_zer':   LLOp(canraise=(ZeroDivisionError,), tryfold=True),
+    'lllong_mod':            LLOp(canfold=True),
+    'lllong_mod_zer':        LLOp(canraise=(ZeroDivisionError,), tryfold=True),
+    'lllong_lt':             LLOp(canfold=True),
+    'lllong_le':             LLOp(canfold=True),
+    'lllong_eq':             LLOp(canfold=True),
+    'lllong_ne':             LLOp(canfold=True),
+    'lllong_gt':             LLOp(canfold=True),
+    'lllong_ge':             LLOp(canfold=True),
+    'lllong_and':            LLOp(canfold=True),
+    'lllong_or':             LLOp(canfold=True),
+    'lllong_lshift':         LLOp(canfold=True),  # args (r_longlonglong, int)
+    'lllong_rshift':         LLOp(canfold=True),  # args (r_longlonglong, int)
+    'lllong_xor':            LLOp(canfold=True),
+    
     'cast_primitive':       LLOp(canfold=True),
     'cast_bool_to_int':     LLOp(canfold=True),
     'cast_bool_to_uint':    LLOp(canfold=True),
diff --git a/pypy/rpython/lltypesystem/lltype.py 
b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -1,7 +1,7 @@
 import py
 from pypy.rlib.rarithmetic import (r_int, r_uint, intmask, r_singlefloat,
-                                   r_ulonglong, r_longlong, r_longfloat,
-                                   base_int, normalizedinttype, longlongmask)
+                                   r_ulonglong, r_longlong, r_longfloat, 
r_longlonglong,
+                                   base_int, normalizedinttype, longlongmask, 
longlonglongmask)
 from pypy.rlib.objectmodel import Symbolic
 from pypy.tool.uid import Hashable
 from pypy.tool.identity_dict import identity_dict
@@ -667,6 +667,7 @@
 
 _numbertypes = {int: Number("Signed", int, intmask)}
 _numbertypes[r_int] = _numbertypes[int]
+_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong, 
longlonglongmask)
 if r_longlong is not r_int:
     _numbertypes[r_longlong] = Number("SignedLongLong", r_longlong,
                                       longlongmask)
@@ -689,6 +690,7 @@
 Signed   = build_number("Signed", int)
 Unsigned = build_number("Unsigned", r_uint)
 SignedLongLong = build_number("SignedLongLong", r_longlong)
+SignedLongLongLong = build_number("SignedLongLongLong", r_longlonglong)
 UnsignedLongLong = build_number("UnsignedLongLong", r_ulonglong)
 
 Float       = Primitive("Float",       0.0)                  # C type 'double'
diff --git a/pypy/rpython/lltypesystem/opimpl.py 
b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -20,7 +20,7 @@
 
 # global synonyms for some types
 from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong
+from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong, 
r_longlonglong
 from pypy.rpython.lltypesystem.llmemory import AddressAsInt
 
 if r_longlong is r_int:
@@ -29,13 +29,18 @@
 else:
     r_longlong_arg = r_longlong
     r_longlong_result = r_longlong
+    
+    
+r_longlonglong_arg = r_longlonglong
+r_longlonglong_result = r_longlonglong
 
 argtype_by_name = {
     'int': (int, long),
     'float': float,
     'uint': r_uint,
     'llong': r_longlong_arg,
-    'ullong': r_ulonglong,
+    'llong': r_longlong_arg,
+    'lllong': r_longlonglong,
     }
 
 def no_op(x):
@@ -283,6 +288,22 @@
         r -= y
     return r
 
+def op_lllong_floordiv(x, y):
+    assert isinstance(x, r_longlonglong_arg)
+    assert isinstance(y, r_longlonglong_arg)
+    r = x//y
+    if x^y < 0 and x%y != 0:
+        r += 1
+    return r
+
+def op_lllong_mod(x, y):
+    assert isinstance(x, r_longlonglong_arg)
+    assert isinstance(y, r_longlonglong_arg)
+    r = x%y
+    if x^y < 0 and x%y != 0:
+        r -= y
+    return r
+
 def op_uint_lshift(x, y):
     assert isinstance(x, r_uint)
     assert is_valid_int(y)
@@ -303,6 +324,16 @@
     assert is_valid_int(y)
     return r_longlong_result(x >> y)
 
+def op_lllong_lshift(x, y):
+    assert isinstance(x, r_longlonglong_arg)
+    assert is_valid_int(y)
+    return r_longlonglong_result(x << y)
+
+def op_lllong_rshift(x, y):
+    assert isinstance(x, r_longlonglong_arg)
+    assert is_valid_int(y)
+    return r_longlonglong_result(x >> y)
+
 def op_ullong_lshift(x, y):
     assert isinstance(x, r_ulonglong)
     assert isinstance(y, int)
diff --git a/pypy/rpython/lltypesystem/rffi.py 
b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -434,6 +434,7 @@
         TYPES.append(name)
 TYPES += ['signed char', 'unsigned char',
           'long long', 'unsigned long long',
+          '__int128',
           'size_t', 'time_t', 'wchar_t',
           'uintptr_t', 'intptr_t',
           'void*']    # generic pointer type
diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -4,7 +4,7 @@
 from pypy.objspace.flow.operation import op_appendices
 from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \
      Void, Char, UniChar, malloc, pyobjectptr, UnsignedLongLong, \
-     SignedLongLong, build_number, Number, cast_primitive, typeOf
+     SignedLongLong, build_number, Number, cast_primitive, typeOf, 
SignedLongLongLong
 from pypy.rpython.rmodel import IntegerRepr, inputconst
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
 from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \
@@ -32,6 +32,7 @@
 
 signed_repr = getintegerrepr(Signed, 'int_')
 signedlonglong_repr = getintegerrepr(SignedLongLong, 'llong_')
+unsigned_repr = getintegerrepr(SignedLongLongLong, 'lllong_')
 unsigned_repr = getintegerrepr(Unsigned, 'uint_')
 unsignedlonglong_repr = getintegerrepr(UnsignedLongLong, 'ullong_')
 
diff --git a/pypy/translator/c/primitive.py b/pypy/translator/c/primitive.py
--- a/pypy/translator/c/primitive.py
+++ b/pypy/translator/c/primitive.py
@@ -247,3 +247,4 @@
 define_c_primitive(rffi.ULONG, 'unsigned long', 'UL')
 define_c_primitive(rffi.LONGLONG, 'long long', 'LL')
 define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL')
+define_c_primitive(rffi.__INT128, '__int128', 'LL') # Unless it's a 128bit 
platform, LL is the biggest
\ No newline at end of file
diff --git a/pypy/translator/c/src/int.h b/pypy/translator/c/src/int.h
--- a/pypy/translator/c/src/int.h
+++ b/pypy/translator/c/src/int.h
@@ -98,7 +98,8 @@
                                                r = 
Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG,x, (y))
 #define OP_ULLONG_RSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
                                                r = (x) >> (y)
-
+#define OP_LLLONG_RSHIFT(x,y,r)  CHECK_SHIFT_RANGE(y, PYPY_LONGLONGLONG_BIT); \
+                                                r = 
Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG_LONG,x, (y))
 
 #define OP_INT_LSHIFT(x,y,r)    CHECK_SHIFT_RANGE(y, PYPY_LONG_BIT); \
                                                        r = (x) << (y)
@@ -106,6 +107,8 @@
                                                        r = (x) << (y)
 #define OP_LLONG_LSHIFT(x,y,r)  CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
                                                        r = (x) << (y)
+#define OP_LLLONG_LSHIFT(x,y,r)  CHECK_SHIFT_RANGE(y, PYPY_LONGLONGLONG_BIT); \
+                                                        r = (x) << (y)
 #define OP_ULLONG_LSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
                                                        r = (x) << (y)
 
@@ -120,6 +123,7 @@
 #define OP_UINT_FLOORDIV(x,y,r)   r = (x) / (y)
 #define OP_LLONG_FLOORDIV(x,y,r)  r = (x) / (y)
 #define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
+#define OP_LLLONG_FLOORDIV(x,y,r)  r = (x) / (y)
 
 #define OP_INT_FLOORDIV_OVF(x,y,r)                      \
        if ((y) == -1 && (x) == SIGNED_MIN)               \
@@ -142,12 +146,19 @@
            { FAIL_ZER("integer division"); r=0; }      \
        else                                            \
            r = (x) / (y)
+
 #define OP_ULLONG_FLOORDIV_ZER(x,y,r)                           \
        if ((y) == 0)                                           \
            { FAIL_ZER("unsigned integer division"); r=0; }     \
        else                                                    \
            r = (x) / (y)
-
+           
+#define OP_LLLONG_FLOORDIV_ZER(x,y,r)                    \
+        if ((y) == 0)                                   \
+            { FAIL_ZER("integer division"); r=0; }      \
+        else                                            \
+            r = (x) / (y)
+            
 #define OP_INT_FLOORDIV_OVF_ZER(x,y,r)                  \
        if ((y) == 0)                                   \
            { FAIL_ZER("integer division"); r=0; }      \
@@ -160,6 +171,7 @@
 #define OP_UINT_MOD(x,y,r)    r = (x) % (y)
 #define OP_LLONG_MOD(x,y,r)   r = (x) % (y)
 #define OP_ULLONG_MOD(x,y,r)  r = (x) % (y)
+#define OP_LLLONG_MOD(x,y,r)   r = (x) % (y)
 
 #define OP_INT_MOD_OVF(x,y,r)                           \
        if ((y) == -1 && (x) == SIGNED_MIN)               \
@@ -187,6 +199,12 @@
        else                                                    \
            r = (x) % (y)
 
+#define OP_LLLONG_MOD_ZER(x,y,r)                         \
+        if ((y) == 0)                                   \
+            { FAIL_ZER("integer modulo"); r=0; }        \
+        else                                            \
+            r = (x) % (y)
+            
 #define OP_INT_MOD_OVF_ZER(x,y,r)                       \
        if ((y) == 0)                                   \
            { FAIL_ZER("integer modulo"); r=0; }        \
@@ -206,11 +224,13 @@
 #define OP_CAST_UINT_TO_INT(x,r)    r = (Signed)(x)
 #define OP_CAST_INT_TO_UINT(x,r)    r = (Unsigned)(x)
 #define OP_CAST_INT_TO_LONGLONG(x,r) r = (long long)(x)
+#define OP_CAST_INT_TO_LONGLONGLONG(x,r) r = (__int128)(x)
 #define OP_CAST_CHAR_TO_INT(x,r)    r = (Signed)((unsigned char)(x))
 #define OP_CAST_INT_TO_CHAR(x,r)    r = (char)(x)
 #define OP_CAST_PTR_TO_INT(x,r)     r = (Signed)(x)    /* XXX */
 
 #define OP_TRUNCATE_LONGLONG_TO_INT(x,r) r = (Signed)(x)
+#define OP_TRUNCATE_LONGLONGLONG_TO_INT(x,r) r = (Signed)(x)
 
 #define OP_CAST_UNICHAR_TO_INT(x,r)    r = (Signed)((Unsigned)(x)) /*?*/
 #define OP_CAST_INT_TO_UNICHAR(x,r)    r = (unsigned int)(x)
@@ -290,6 +310,11 @@
 #define OP_LLONG_ABS     OP_INT_ABS
 #define OP_LLONG_INVERT  OP_INT_INVERT
 
+#define OP_LLLONG_IS_TRUE OP_INT_IS_TRUE
+#define OP_LLLONG_NEG     OP_INT_NEG
+#define OP_LLLONG_ABS     OP_INT_ABS
+#define OP_LLLONG_INVERT  OP_INT_INVERT
+
 #define OP_LLONG_ADD OP_INT_ADD
 #define OP_LLONG_SUB OP_INT_SUB
 #define OP_LLONG_MUL OP_INT_MUL
@@ -303,6 +328,19 @@
 #define OP_LLONG_OR     OP_INT_OR
 #define OP_LLONG_XOR    OP_INT_XOR
 
+#define OP_LLLONG_ADD OP_INT_ADD
+#define OP_LLLONG_SUB OP_INT_SUB
+#define OP_LLLONG_MUL OP_INT_MUL
+#define OP_LLLONG_LT  OP_INT_LT
+#define OP_LLLONG_LE  OP_INT_LE
+#define OP_LLLONG_EQ  OP_INT_EQ
+#define OP_LLLONG_NE  OP_INT_NE
+#define OP_LLLONG_GT  OP_INT_GT
+#define OP_LLLONG_GE  OP_INT_GE
+#define OP_LLLONG_AND    OP_INT_AND
+#define OP_LLLONG_OR     OP_INT_OR
+#define OP_LLLONG_XOR    OP_INT_XOR
+
 #define OP_ULLONG_IS_TRUE OP_LLONG_IS_TRUE
 #define OP_ULLONG_INVERT  OP_LLONG_INVERT
 #define OP_ULLONG_ADD OP_LLONG_ADD
diff --git a/pypy/translator/goal/targetbigintbenchmark.py 
b/pypy/translator/goal/targetbigintbenchmark.py
--- a/pypy/translator/goal/targetbigintbenchmark.py
+++ b/pypy/translator/goal/targetbigintbenchmark.py
@@ -23,17 +23,17 @@
         6.647562
 
         Pypy with improvements:
-        2.291724
-        4.616600
-        9.538857
-        1.102726
-        4.820049
-        9.899771
-        14.733251
-        0.016657
-        11.992919
-        14.144412
-        6.404446
+        2.085952
+        4.318238
+        9.753659
+        1.641015
+        3.983455
+        5.787758
+        7.573468
+        0.042393
+        4.436702
+        9.103529
+        5.036710
 
     """
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to