Author: stian
Branch: improve-rbigint
Changeset: r56336:e8c1863ac3e4
Date: 2012-06-26 02:45 +0200
http://bitbucket.org/pypy/pypy/changeset/e8c1863ac3e4/

Log:    Some not working code for checking for int128 support. Also add
        support for non-int128 platforms as soon as we can detect them.

diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -7,17 +7,35 @@
 from pypy.rlib import jit
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rpython import extregistry
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
 import math, sys
 
+# Check for int128 support. Is this right? It sure doesn't work.
+"""class CConfig:
+    _compilation_info_ = ExternalCompilationInfo()
+    
+    __INT128 = rffi_platform.SimpleType("__int128", rffi.__INT128)
+
+cConfig = rffi_platform.configure(CConfig)"""
+
+SUPPORT_INT128 = True
+
 # note about digit sizes:
 # In division, the native integer type must be able to hold
 # a sign bit plus two digits plus 1 overflow bit.
 
 #SHIFT = (LONG_BIT // 2) - 1
-SHIFT = 63
-
-MASK = long((1 << SHIFT) - 1)
+if SUPPORT_INT128:
+    SHIFT = 63
+    MASK = long((1 << SHIFT) - 1)
+    UDIGIT_TYPE = r_ulonglong
+else:
+    SHIFT = 31
+    MASK = int((1 << SHIFT) - 1)
+    UDIGIT_TYPE = r_uint
+    
 FLOAT_MULTIPLIER = float(1 << LONG_BIT) # Because it works.
 
 CACHE_INTS = 1024 # CPython do 256
@@ -34,7 +52,12 @@
 
 # Karatsuba is O(N**1.585)
 USE_KARATSUBA = True # set to False for comparison
-KARATSUBA_CUTOFF = 19 #38
+
+if SHIFT > 31:
+    KARATSUBA_CUTOFF = 19
+else:
+    KARATSUBA_CUTOFF = 38
+    
 KARATSUBA_SQUARE_CUTOFF = 2 * KARATSUBA_CUTOFF
 
 USE_TOOMCOCK = False # WIP
@@ -48,8 +71,13 @@
 FIVEARY_CUTOFF = 8
 
 
-def _mask_digit(x):
-    return longlongmask(x & MASK) #intmask(x & MASK)
+if SHIFT <= 31:
+    def _mask_digit(x):
+        return intmask(x & MASK)
+else:
+    def _mask_digit(x):
+        return longlongmask(x & MASK)
+        
 _mask_digit._annspecialcase_ = 'specialize:argtype(0)'
 
 def _widen_digit(x):
@@ -95,7 +123,10 @@
 def _check_digits(l):
     for x in l:
         assert type(x) is type(NULLDIGIT)
-        assert longlongmask(x) & MASK == longlongmask(x)
+        if SHIFT <= 31:
+            assert intmask(x) & MASK == intmask(x)
+        else:
+            assert longlongmask(x) & MASK == longlongmask(x)
             
 class Entry(extregistry.ExtRegistryEntry):
     _about_ = _check_digits
@@ -882,7 +913,7 @@
         size_a, size_b = size_b, size_a
     z = rbigint([NULLDIGIT] * (size_a + 1), 1)
     i = 0
-    carry = r_ulonglong(0)
+    carry = UDIGIT_TYPE(0)
     while i < size_b:
         carry += a.udigit(i) + b.udigit(i)
         z.setdigit(i, carry)
@@ -926,7 +957,7 @@
         size_a = size_b = i+1
         
     z = rbigint([NULLDIGIT] * size_a, sign)
-    borrow = r_ulonglong(0)
+    borrow = UDIGIT_TYPE(0)
     i = 0
     while i < size_b:
         # The following assumes unsigned arithmetic
@@ -1430,7 +1461,7 @@
 def _x_divrem(v1, w1):
     """ Unsigned bigint division with remainder -- the algorithm """
     size_w = w1.numdigits()
-    d = (r_ulonglong(MASK)+1) // (w1.udigit(size_w-1) + 1)
+    d = (UDIGIT_TYPE(MASK)+1) // (w1.udigit(size_w-1) + 1)
     assert d <= MASK    # because the first digit of w1 is not zero
     d = longlongmask(d)
     v = _muladd1(v1, d)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to