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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit