def int_floordiv_zer(x, y): '''#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ if ((y)) { OP_INT_FLOORDIV(x,y,r,err); } \ else FAIL_ZER(err, "integer division") ''' if y: return llop.int_floordiv(Signed, x, y) else: raise ZeroDivisionError("integer division")
def test_int_floordiv_mod(): from rpython.rtyper.lltypesystem.lloperation import llop from rpython.jit.codewriter.support import _ll_2_int_floordiv, _ll_2_int_mod for x in range(-6, 7): for y in range(-3, 4): if y != 0: assert (_ll_2_int_floordiv(x, y) == llop.int_floordiv(lltype.Signed, x, y)) assert (_ll_2_int_mod(x, y) == llop.int_mod(lltype.Signed, x, y))
def test_int_floordiv_mod(): from rpython.rtyper.lltypesystem.lloperation import llop from rpython.jit.codewriter.support import _ll_2_int_floordiv, _ll_2_int_mod for x in range(-6, 7): for y in range(-3, 4): if y != 0: assert (_ll_2_int_floordiv(x, y) == llop.int_floordiv( lltype.Signed, x, y)) assert (_ll_2_int_mod(x, y) == llop.int_mod(lltype.Signed, x, y))
def int_floordiv_ovf(x, y): '''#define OP_INT_FLOORDIV_OVF(x,y,r,err) \ if ((y) == -1 && (x) < 0 && ((unsigned long)(x) << 1) == 0) \ FAIL_OVF(err, "integer division"); \ OP_INT_FLOORDIV(x,y,r,err) ''' if y == -1 and x < 0 and (r_uint(x) << 1) == 0: raise OverflowError("integer division") else: return llop.int_floordiv(Signed, x, y)
def ll_int_py_div(x, y): # Python, and RPython, assume that integer division truncates # towards -infinity. However, in C, integer division truncates # towards 0. So assuming that, we need to apply a correction # in the right cases. r = llop.int_floordiv(Signed, x, y) # <= truncates like in C p = r * y if y < 0: u = p - x else: u = x - p return r + (u >> INT_BITS_1)
def int_c_div(x, y): """Return the result of the C-style 'x / y'. This differs from the Python-style division if (x < 0 xor y < 0). The JIT implements it with a Python-style division followed by correction code. This is not that bad, because the JIT removes the correction code if x and y are both nonnegative, and if y is any nonnegative constant then the division turns into a rshift or a mul. """ from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lloperation import llop return llop.int_floordiv(lltype.Signed, x, y)
def _ll_2_int_floordiv_ovf(x, y): if x == -sys.maxint - 1 and y == -1: raise OverflowError return llop.int_floordiv(lltype.Signed, x, y)
def ll_int_py_div_nonnegargs(x, y): from rpython.rlib.debug import ll_assert r = llop.int_floordiv(Signed, x, y) # <= truncates like in C ll_assert(r >= 0, "int_py_div_nonnegargs(): one arg is negative") return r
def int_floordiv(space, n, m): return space.wrap(llop.int_floordiv(lltype.Signed, n, m))
def _ll_2_int_floordiv_zer(x, y): if y == 0: raise ZeroDivisionError return llop.int_floordiv(lltype.Signed, x, y)
def unsafe_fxquotient(a, b): return values.W_Fixnum.make(llop.int_floordiv(Signed, a.value, b.value))
def _ll_2_int_floordiv_ovf(x, y): # intentionally not short-circuited to produce only one guard # and to remove the check fully if one of the arguments is known if (x == -sys.maxint - 1) & (y == -1): raise OverflowError return llop.int_floordiv(lltype.Signed, x, y)
def _ll_2_int_floordiv_ovf_zer(x, y): if y == 0: raise ZeroDivisionError if x == -sys.maxint - 1 and y == -1: raise OverflowError return llop.int_floordiv(lltype.Signed, x, y)