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