[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