[pypy-svn] r63980 - in pypy/branch/pyjitpl5-simplify/pypy/jit/backend: test x86

arigo at codespeak.net arigo at codespeak.net
Sat Apr 11 13:27:28 CEST 2009


Author: arigo
Date: Sat Apr 11 13:27:26 2009
New Revision: 63980

Modified:
   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
Log:
Finish the implement the _OVF operations.
Add a test, commented out for now.


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 13:27:26 2009
@@ -138,15 +138,17 @@
                                     (-110, 3, -36),
                                     (110, -3, -36),
                                     (-110, -3, 36),
+                                    (-110, -1, 110),
+                                    (minint, 1, minint),
                                     (minint, -1, boom)]),
             ]:
             v1 = BoxInt(testcases[0][0])
             v2 = BoxInt(testcases[0][1])
-            res_v = BoxInt()
+            v_res = BoxInt()
             ops = [
-                ResOperation(opnum, [v1, v2], res_v),
+                ResOperation(opnum, [v1, v2], v_res),
                 ResOperation(rop.GUARD_NO_EXCEPTION, [], None),
-                ResOperation(rop.FAIL, [res_v], None),
+                ResOperation(rop.FAIL, [v_res], None),
                 ]
             if opnum == rop.INT_NEG_OVF:
                 del ops[0].args[1]
@@ -159,6 +161,31 @@
             for x, y, z in testcases:
                 op = self.cpu.execute_operations(loop, [BoxInt(x), BoxInt(y)])
                 assert op.args[0].value == z
+            # ----------
+            # the same thing but with the exception path reversed
+##            v1 = BoxInt(testcases[0][0])
+##            v2 = BoxInt(testcases[0][1])
+##            v_res = BoxInt()
+##            v_exc = BoxPtr()
+##            self.cpu.set_overflow_error()
+##            ovferror = self.cpu.get_exception()
+##            self.cpu.clear_exception()
+##            ops = [
+##                ResOperation(opnum, [v1, v2], v_res),
+##                ResOperation(rop.GUARD_EXCEPTION, [ConstInt(ovferror)], v_exc),
+##                ResOperation(rop.FAIL, [ConstInt(boom)], None),
+##                ]
+##            if opnum == rop.INT_NEG_OVF:
+##                del ops[0].args[1]
+##            ops[1].suboperations = [ResOperation(rop.FAIL, [ConstInt(v_res)],
+##                                                 None)]
+##            loop = TreeLoop('inverted')
+##            loop.operations = ops
+##            loop.inputargs = [v1, v2]
+##            self.cpu.compile_operations(loop)
+##            for x, y, z in testcases:
+##                op = self.cpu.execute_operations(loop, [BoxInt(x), BoxInt(y)])
+##                assert op.args[0].value == z
 
     def test_uint_xor(self):
         x = execute(self.cpu, rop.UINT_XOR, [BoxInt(100), ConstInt(4)])

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 13:27:26 2009
@@ -451,42 +451,27 @@
         loc = arglocs[0]
         assert arglocs[1] is ecx
         self.mc.SHL(loc, cl)
-        #self.mc.CMP(ecx, imm8(32)) XXX <- what's that???
-        #self.mc.SBB(ecx, ecx)
-        #self.mc.AND(loc, ecx)
-
-    def genop_guard_int_lshift_ovf(self, op, guard_op, addr, arglocs, resloc):
-        loc = arglocs[0]
-        self.mc.CMP(ecx, imm(31))
-        self.mc.JG(rel32(addr))
-        self.mc.SHL(loc, cl)
-        self.mc.JO(rel32(addr))
-
-    # TODO: measure which way is faster actually - with tmp in ecx or with
-    #       arg in ecx. I don't expect it to be performance critical, but
-    #       who knows
 
     def genop_int_rshift(self, op, arglocs, resloc):
-        (x, y, tmp) = arglocs
-        assert tmp is ecx
-        yv = op.args[1]
-        if isinstance(yv, ConstInt):
-            intval = yv.value
-            if intval < 0 or intval > 31:
-                intval = 31
-            self.mc.MOV(tmp, imm8(intval))
-        else:
-            self.mc.MOV(tmp, imm8(31)) 
-            self.mc.CMP(y, tmp)
-            self.mc.CMOVBE(tmp, y)
-        self.mc.SAR(resloc, cl)
+        loc = arglocs[0]
+        assert arglocs[1] is ecx
+        self.mc.SAR(loc, cl)
 
     def genop_uint_rshift(self, op, arglocs, resloc):
         loc = arglocs[0]
+        assert arglocs[1] is ecx
         self.mc.SHR(loc, cl)
-        #self.mc.CMP(ecx, imm8(32)) <--- XXX what's that?
-        #self.mc.SBB(ecx, ecx)
-        #self.mc.AND(eax, ecx)
+
+    def genop_guard_int_lshift_ovf(self, op, guard_op, addr, arglocs, resloc):
+        loc = arglocs[0]
+        tmploc = arglocs[2]
+        # xxx a bit inefficient
+        self.mc.MOV(tmploc, loc)
+        self.mc.SHL(tmploc, cl)
+        self.mc.SAR(tmploc, cl)
+        self.mc.CMP(tmploc, loc)
+        self.mc.JNE(rel32(addr))
+        self.mc.SHL(loc, cl)
 
     def genop_int_is_true(self, op, arglocs, resloc):
         argloc = arglocs[0]
@@ -525,9 +510,10 @@
         self.mc.IDIV(ecx)
 
     def genop_guard_int_mod_ovf(self, op, guard_op, addr, arglocs, result_loc):
-        self.mc.CMP(eax, imm(-sys.maxint-1))
-        self.mc.JE(rel32(addr))
-        self.mc.CMP(ecx, imm(-1))
+        # detect the combination "eax=-sys.maxint-1, ecx=-1"
+        self.mc.LEA(edx, mem(eax, sys.maxint))  # edx=-1 if eax=-sys.maxint-1
+        self.mc.AND(edx, ecx)                   # edx=-1 only in the case above
+        self.mc.CMP(edx, imm(-1))
         self.mc.JE(rel32(addr))
         self.mc.CDQ()
         self.mc.IDIV(ecx)

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 13:27:26 2009
@@ -754,51 +754,45 @@
         self.eventually_free_vars(guard_op.inputargs)
         self.eventually_free_var(guard_op.result)
 
-    def consider_int_rshift(self, op, ignored):
-        tmpvar = TempBox()
-        reg = self.force_allocate_reg(tmpvar, [], ecx)
-        y = self.loc(op.args[1])
-        x = self.force_result_in_reg(op.result, op.args[0],
-                                     op.args + [tmpvar])
-        self.eventually_free_vars(op.args + [tmpvar])
-        self.Perform(op, [x, y, reg], x)
-
     def consider_int_lshift(self, op, ignored):
         loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
         loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
         self.Perform(op, [loc1, loc2], loc1)
         self.eventually_free_vars(op.args)
 
+    consider_int_rshift  = consider_int_lshift
     consider_uint_rshift = consider_int_lshift
 
     def consider_int_lshift_ovf(self, op, guard_op):
         loc2 = self.make_sure_var_in_reg(op.args[1], [], ecx)
         loc1 = self.force_result_in_reg(op.result, op.args[0], op.args)
+        tmpvar = TempBox()
+        tmploc = self.force_allocate_reg(tmpvar, [])
         self.eventually_free_vars(op.args)
         self.position += 1
         regalloc = self.regalloc_for_guard(guard_op)
-        self.perform_with_guard(op, guard_op, regalloc, [loc1, loc2], loc1,
-                                overflow=True)
+        self.perform_with_guard(op, guard_op, regalloc, [loc1, loc2, tmploc],
+                                loc1, overflow=True)
         self.eventually_free_vars(guard_op.inputargs)
-        self.eventually_free_var(guard_op.result)
+        self.eventually_free_var(tmpvar)
 
-    def _consider_int_div_or_mod(self, op, trashreg):
+    def _consider_int_div_or_mod(self, op, resultreg, trashreg):
         l0 = self.make_sure_var_in_reg(op.args[0], [], eax)
         l1 = self.make_sure_var_in_reg(op.args[1], [], ecx)
-        l2 = self.force_allocate_reg(op.result, [], edx)
+        l2 = self.force_allocate_reg(op.result, [], resultreg)
         # the register (eax or edx) not holding what we are looking for
         # will be just trash after that operation
         tmpvar = TempBox()
         self.force_allocate_reg(tmpvar, [], trashreg)
-        assert (l0, l1, l2) == (eax, ecx, edx)
+        assert (l0, l1, l2) == (eax, ecx, resultreg)
         self.eventually_free_vars(op.args + [tmpvar])
 
     def consider_int_mod(self, op, ignored):
-        self._consider_int_div_or_mod(op, eax)
+        self._consider_int_div_or_mod(op, edx, eax)
         self.Perform(op, [eax, ecx], edx)
 
     def consider_int_mod_ovf(self, op, guard_op):
-        self._consider_int_div_or_mod(op, eax)
+        self._consider_int_div_or_mod(op, edx, eax)
         self.position += 1
         regalloc = self.regalloc_for_guard(guard_op)
         self.perform_with_guard(op, guard_op, regalloc, [eax, ecx], edx,
@@ -806,11 +800,11 @@
         self.eventually_free_vars(guard_op.inputargs)
 
     def consider_int_floordiv(self, op, ignored):
-        self._consider_int_div_or_mod(op, edx)
+        self._consider_int_div_or_mod(op, eax, edx)
         self.Perform(op, [eax, ecx], eax)
 
     def consider_int_floordiv_ovf(self, op, guard_op):
-        self._consider_int_div_or_mod(op, edx)
+        self._consider_int_div_or_mod(op, eax, edx)
         self.position += 1
         regalloc = self.regalloc_for_guard(guard_op)
         self.perform_with_guard(op, guard_op, regalloc, [eax, ecx], eax,



More information about the Pypy-commit mailing list