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