[pypy-svn] r63981 - in pypy/branch/pyjitpl5-simplify/pypy/jit: backend/llgraph backend/test backend/x86 metainterp
arigo at codespeak.net
arigo at codespeak.net
Sat Apr 11 14:24:44 CEST 2009
Author: arigo
Date: Sat Apr 11 14:24:41 2009
New Revision: 63981
Modified:
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/executor.py
pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py
Log:
Systematic tests for all INT_xxx operations.
Add INT_ABS and INT_ABS_OVF.
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/llgraph/llimpl.py Sat Apr 11 14:24:41 2009
@@ -68,6 +68,7 @@
'int_is_true' : (('int',), 'bool'),
'int_neg' : (('int',), 'int'),
'int_invert' : (('int',), 'int'),
+ 'int_abs' : (('int',), 'int'),
'int_add_ovf' : (('int', 'int'), 'int'),
'int_mod_ovf' : (('int', 'int'), 'int'),
'int_sub_ovf' : (('int', 'int'), 'int'),
@@ -75,6 +76,7 @@
'int_floordiv_ovf': (('int', 'int'), 'int'),
'int_neg_ovf' : (('int',), 'int'),
'int_lshift_ovf' : (('int', 'int'), 'int'),
+ 'int_abs_ovf' : (('int',), 'int'),
'bool_not' : (('bool',), 'bool'),
'uint_add' : (('int', 'int'), 'int'),
'uint_sub' : (('int', 'int'), 'int'),
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/test/runner.py Sat Apr 11 14:24:41 2009
@@ -108,6 +108,48 @@
'int')
assert res.value == intmask(r_uint(1) >> r_uint(4))
+ def test_binary_operations(self):
+ minint = -sys.maxint-1
+ for opnum, testcases in [
+ (rop.INT_ADD, [(10, -2, 8)]),
+ (rop.INT_SUB, [(10, -2, 12)]),
+ (rop.INT_MUL, [(-6, -3, 18)]),
+ (rop.INT_FLOORDIV, [(110, 3, 36),
+ (-110, 3, -36),
+ (110, -3, -36),
+ (-110, -3, 36),
+ (-110, -1, 110),
+ (minint, 1, minint)]),
+ (rop.INT_MOD, [(11, 3, 2),
+ (-11, 3, -2),
+ (11, -3, 2),
+ (-11, -3, -2)]),
+ (rop.INT_AND, [(0xFF00, 0x0FF0, 0x0F00)]),
+ (rop.INT_OR, [(0xFF00, 0x0FF0, 0xFFF0)]),
+ (rop.INT_XOR, [(0xFF00, 0x0FF0, 0xF0F0)]),
+ (rop.INT_LSHIFT, [(-5, 2, -20),
+ (-5, 0, -5)]),
+ (rop.INT_RSHIFT, [(-17, 2, -5),
+ (19, 1, 9)]),
+ ]:
+ for x, y, z in testcases:
+ res = self.execute_operation(opnum, [BoxInt(x), BoxInt(y)],
+ 'int')
+ assert res.value == z
+
+ def test_unary_operations(self):
+ minint = -sys.maxint-1
+ for opnum, testcases in [
+ (rop.INT_IS_TRUE, [(0, 0), (1, 1), (2, 1), (-1, 1), (minint, 1)]),
+ (rop.INT_NEG, [(0, 0), (123, -123), (-23127, 23127)]),
+ (rop.INT_INVERT, [(0, ~0), (-1, ~(-1)), (123, ~123)]),
+ (rop.INT_ABS, [(0, 0), (123, 123), (-23127, 23127)]),
+ ]:
+ for x, y in testcases:
+ res = self.execute_operation(opnum, [BoxInt(x)],
+ 'int')
+ assert res.value == y
+
def test_ovf_operations(self):
minint = -sys.maxint-1
boom = 666
@@ -124,6 +166,9 @@
(rop.INT_NEG_OVF, [(-sys.maxint, 0, sys.maxint),
(sys.maxint, 0, -sys.maxint),
(minint, 0, boom)]),
+ (rop.INT_ABS_OVF, [(-sys.maxint, 0, sys.maxint),
+ (sys.maxint, 0, sys.maxint),
+ (minint, 0, boom)]),
(rop.INT_MOD_OVF, [(11, 3, 2),
(-11, 3, -2),
(11, -3, 2),
@@ -150,7 +195,7 @@
ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
ResOperation(rop.FAIL, [v_res], None),
]
- if opnum == rop.INT_NEG_OVF:
+ if opnum in (rop.INT_NEG_OVF, rop.INT_ABS_OVF):
del ops[0].args[1]
ops[1].suboperations = [ResOperation(rop.FAIL, [ConstInt(boom)],
None)]
@@ -175,7 +220,7 @@
## ResOperation(rop.GUARD_EXCEPTION, [ConstInt(ovferror)], v_exc),
## ResOperation(rop.FAIL, [ConstInt(boom)], None),
## ]
-## if opnum == rop.INT_NEG_OVF:
+## if opnum in (rop.INT_NEG_OVF, rop.INT_ABS_OVF):
## del ops[0].args[1]
## ops[1].suboperations = [ResOperation(rop.FAIL, [ConstInt(v_res)],
## None)]
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/assembler.py Sat Apr 11 14:24:41 2009
@@ -393,6 +393,7 @@
assert res is eax
genop_int_neg = _unaryop("NEG")
+ genop_int_invert = _unaryop("NOT")
genop_int_add = _binaryop("ADD", True)
genop_int_sub = _binaryop("SUB")
genop_int_mul = _binaryop("IMUL", True)
@@ -479,6 +480,24 @@
self.mc.MOV(resloc, imm8(0))
self.mc.SETNZ(lower_byte(resloc))
+ def genop_int_abs(self, op, arglocs, resloc):
+ argloc = arglocs[0]
+ tmploc = arglocs[1]
+ assert resloc != argloc and resloc != tmploc
+ self.mc.MOV(resloc, argloc)
+ # ABS-computing code from Psyco, found by exhaustive search
+ # on *all* short sequences of operations :-)
+ self.mc.ADD(resloc, resloc)
+ self.mc.SBB(resloc, argloc)
+ self.mc.SBB(tmploc, tmploc)
+ self.mc.XOR(resloc, tmploc)
+ # in case of overflow, the result is negative again (-sys.maxint-1)
+ # and the L flag is set.
+
+ def genop_guard_int_abs_ovf(self, op, guard_op, addr, arglocs, resloc):
+ self.genop_int_abs(op, arglocs, resloc)
+ self.mc.JL(rel32(addr))
+
def genop_guard_oononnull(self, op, guard_op, addr, arglocs, resloc):
loc = arglocs[0]
self.mc.TEST(loc, loc)
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/backend/x86/regalloc.py Sat Apr 11 14:24:41 2009
@@ -743,6 +743,7 @@
res = self.force_result_in_reg(op.result, op.args[0], [])
self.Perform(op, [res], res)
+ consider_int_invert = consider_int_neg
consider_bool_not = consider_int_neg
def consider_int_neg_ovf(self, op, guard_op):
@@ -1024,6 +1025,28 @@
resloc = self.force_allocate_reg(op.result, [])
self.Perform(op, [argloc], resloc)
+ def consider_int_abs(self, op, ignored):
+ argloc = self.force_allocate_reg(op.args[0], [])
+ tmpvar = TempBox()
+ tmploc = self.force_allocate_reg(tmpvar, [])
+ resloc = self.force_allocate_reg(op.result, [])
+ self.Perform(op, [argloc, tmploc], resloc)
+ self.eventually_free_var(op.args[0])
+ self.eventually_free_var(tmpvar)
+
+ def consider_int_abs_ovf(self, op, guard_op):
+ argloc = self.force_allocate_reg(op.args[0], [])
+ tmpvar = TempBox()
+ tmploc = self.force_allocate_reg(tmpvar, [])
+ resloc = self.force_allocate_reg(op.result, [])
+ self.position += 1
+ regalloc = self.regalloc_for_guard(guard_op)
+ self.perform_with_guard(op, guard_op, regalloc, [argloc, tmploc],
+ resloc, overflow=True)
+ self.eventually_free_vars(guard_op.inputargs)
+ self.eventually_free_var(op.args[0])
+ self.eventually_free_var(tmpvar)
+
def _consider_nullity(self, op, guard_op):
# doesn't need a register in arg
if guard_op is not None:
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/executor.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/executor.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/executor.py Sat Apr 11 14:24:41 2009
@@ -56,6 +56,9 @@
v = r_uint(args[0].getint()) >> r_uint(args[1].getint())
return ConstInt(intmask(v))
+def do_int_abs(cpu, args, descr=None):
+ return ConstInt(abs(args[0].getint()))
+
# ----------
def do_int_lt(cpu, args, descr=None):
@@ -189,6 +192,15 @@
z = 0
return BoxInt(z)
+def do_int_abs_ovf(cpu, args, descr=None):
+ x = args[0].getint()
+ try:
+ z = ovfcheck(abs(x))
+ except OverflowError:
+ cpu.set_overflow_error()
+ z = 0
+ return BoxInt(z)
+
def do_int_mod_ovf(cpu, args, descr=None):
x = args[0].getint()
y = args[1].getint()
Modified: pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/pyjitpl5-simplify/pypy/jit/metainterp/resoperation.py Sat Apr 11 14:24:41 2009
@@ -142,6 +142,7 @@
INT_INVERT = 62
BOOL_NOT = 63
UINT_IS_TRUE = 64
+ INT_ABS = 65
#
OONONNULL = 70
OOISNULL = 71
@@ -192,6 +193,7 @@
INT_MOD_OVF = 156
INT_LSHIFT_OVF = 157
INT_FLOORDIV_OVF = 158
+ INT_ABS_OVF = 159
_OVF_LAST = 160
_CANRAISE_LAST = 160 # ----- end of can_raise operations -----
_LAST = 160 # for the backend to add more internal operations
More information about the Pypy-commit
mailing list