Author: Alexander Schremmer <alex AT alexanderweb DOT de>
Branch: math-improvements
Changeset: r95849:9c346098e834
Date: 2019-02-05 18:38 +0100
http://bitbucket.org/pypy/pypy/changeset/9c346098e834/

Log:    (xoraxax, arigo) Implement correct ULLL and LLL constants for
        {,u}int128_t.

diff --git a/rpython/translator/c/primitive.py 
b/rpython/translator/c/primitive.py
--- a/rpython/translator/c/primitive.py
+++ b/rpython/translator/c/primitive.py
@@ -247,6 +247,22 @@
         PrimitiveName[ll_type] = lambda value, db: name_str % value
     PrimitiveType[ll_type] = '%s @' % c_name
 
+def define_shifted_primitive(ll_type, signed):
+    suffix = "LL" if signed else "ULL"
+    c_name = "__int128_t" if signed else "__uint128_t"
+    def convert(value, db):
+        left_part = value >> 64
+        right_part = value - (left_part << 64)
+        if signed:
+            assert -2**63 <= left_part < 2**63
+        else:
+            assert 0 <= left_part < 2**64
+        assert 0 <= right_part < 2**64
+        name_str = '((((%s) %d%s) << 64) | ((%s) %dULL))' % (c_name, 
left_part, suffix, c_name, right_part)
+        return name_str
+    PrimitiveName[ll_type] = convert
+    PrimitiveType[ll_type] = '%s @' % c_name
+
 define_c_primitive(rffi.SIGNEDCHAR, 'signed char')
 define_c_primitive(rffi.UCHAR, 'unsigned char')
 define_c_primitive(rffi.SHORT, 'short')
@@ -259,5 +275,5 @@
 define_c_primitive(rffi.LONGLONG, 'long long', 'LL')
 define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL')
 if SUPPORT_INT128:
-    define_c_primitive(rffi.__INT128_T, '__int128_t', 'LL') # Unless it's a 
128bit platform, LL is the biggest
-    define_c_primitive(rffi.__UINT128_T, '__uint128_t', 'ULL')
+    define_shifted_primitive(rffi.__INT128_T, signed=True)
+    define_shifted_primitive(rffi.__UINT128_T, signed=False)
diff --git a/rpython/translator/c/test/test_typed.py 
b/rpython/translator/c/test/test_typed.py
--- a/rpython/translator/c/test/test_typed.py
+++ b/rpython/translator/c/test/test_typed.py
@@ -6,6 +6,7 @@
 
 from rpython.rlib.rstackovf import StackOverflow
 from rpython.rlib.objectmodel import compute_hash, current_object_addr_as_int
+from rpython.rlib.nonconst import NonConstant
 from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong, intmask, 
longlongmask
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.translator.test import snippet
@@ -969,6 +970,35 @@
         res = f(217)
         assert res == 305123851
 
+    def test_uint128_constant(self):
+        if not hasattr(rffi, '__UINT128_T'):
+            py.test.skip("no '__uint128_t'")
+        x = rffi.cast(getattr(rffi, '__UINT128_T'), 41)
+        x <<= 60
+        x *= 7
+        def func(n):
+            y = NonConstant(x)
+            y >>= 50
+            return intmask(y)
+        f = self.getcompiled(func, [int])
+        res = f(1)
+        assert res == ((41 << 60) * 7) >> 50
+
+    def test_int128_constant(self):
+        if not hasattr(rffi, '__INT128_T'):
+            py.test.skip("no '__int128_t'")
+        x = rffi.cast(getattr(rffi, '__INT128_T'), -41)
+        x <<= 60
+        x *= 7
+        x |= 2**63
+        def func(n):
+            y = NonConstant(x)
+            y >>= 50
+            return intmask(y)
+        f = self.getcompiled(func, [int])
+        res = f(1)
+        assert res == (((-41 << 60) * 7) | 2**63) >> 50
+
     def test_bool_2(self):
         def func(n):
             x = rffi.cast(lltype.Bool, n)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to