[pypy-svn] r69713 - in pypy/branch/virtual-forcing/pypy/jit/backend: llsupport test x86

arigo at codespeak.net arigo at codespeak.net
Fri Nov 27 22:23:13 CET 2009


Author: arigo
Date: Fri Nov 27 22:23:13 2009
New Revision: 69713

Modified:
   pypy/branch/virtual-forcing/pypy/jit/backend/llsupport/regalloc.py
   pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py
   pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py
   pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py
Log:
(pedronis, arigo)
Fix CALL_MAY_FORCE for returning floats,
by sanitizing the interface a bit.


Modified: pypy/branch/virtual-forcing/pypy/jit/backend/llsupport/regalloc.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/llsupport/regalloc.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/llsupport/regalloc.py	Fri Nov 27 22:23:13 2009
@@ -327,12 +327,12 @@
         """ Adjust registers according to the result of the call,
         which is in variable v.
         """
-        if v is not None:
-            self._check_type(v)
-            r = self.call_result_location(v)
-            self.reg_bindings[v] = r
-            self.free_regs = [fr for fr in self.free_regs if fr is not r]
-    
+        self._check_type(v)
+        r = self.call_result_location(v)
+        self.reg_bindings[v] = r
+        self.free_regs = [fr for fr in self.free_regs if fr is not r]
+        return r
+
     # abstract methods, override
 
     def convert_to_imm(self, c):

Modified: pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/test/runner_test.py	Fri Nov 27 22:23:13 2009
@@ -1308,6 +1308,51 @@
         assert self.cpu.get_latest_value_int(2) == 10
         assert values == [1, 10]
 
+    def test_force_operations_returning_float(self):
+        values = []
+        def maybe_force(token, flag):
+            if flag:
+               self.cpu.force(token)
+               values.append(self.cpu.get_latest_value_int(0))
+               values.append(self.cpu.get_latest_value_int(2))
+            return 42.5
+
+        FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Float)
+        func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
+        funcbox = self.get_funcbox(self.cpu, func_ptr).constbox()
+        calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+        cpu = self.cpu
+        i0 = BoxInt()
+        i1 = BoxInt()
+        f2 = BoxFloat()
+        tok = BoxInt()
+        faildescr = BasicFailDescr(1)
+        ops = [
+        ResOperation(rop.FORCE_TOKEN, [], tok),
+        ResOperation(rop.CALL_MAY_FORCE, [funcbox, tok, i1], f2,
+                     descr=calldescr),
+        ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
+        ResOperation(rop.FINISH, [f2], None, descr=BasicFailDescr(0))
+        ]
+        ops[2].fail_args = [i1, f2, i0]
+        looptoken = LoopToken()
+        self.cpu.compile_loop([i0, i1], ops, looptoken)
+        self.cpu.set_future_value_int(0, 20)
+        self.cpu.set_future_value_int(1, 0)
+        fail = self.cpu.execute_token(looptoken)
+        assert fail.identifier == 0
+        assert self.cpu.get_latest_value_float(0) == 42.5
+        assert values == []
+
+        self.cpu.set_future_value_int(0, 10)
+        self.cpu.set_future_value_int(1, 1)
+        fail = self.cpu.execute_token(looptoken)
+        assert fail.identifier == 1
+        assert self.cpu.get_latest_value_int(0) == 1
+        assert self.cpu.get_latest_value_float(1) == 42.5
+        assert self.cpu.get_latest_value_int(2) == 10
+        assert values == [1, 10]
+
     # pure do_ / descr features
 
     def test_do_operations(self):

Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/assembler.py	Fri Nov 27 22:23:13 2009
@@ -269,9 +269,6 @@
 
     regalloc_mov = mov # legacy interface
 
-    def regalloc_fstp(self, loc):
-        self.mc.FSTP(loc)
-
     def regalloc_push(self, loc):
         if isinstance(loc, XMMREG):
             self.mc.SUB(esp, imm(2*WORD))
@@ -1104,7 +1101,9 @@
         self.mc.CALL(x)
         self.mark_gc_roots()
         self.mc.ADD(esp, imm(extra_on_stack))
-        if size == 1:
+        if isinstance(resloc, MODRM64):
+            self.mc.FSTP(resloc)
+        elif size == 1:
             self.mc.AND(eax, imm(0xff))
         elif size == 2:
             self.mc.AND(eax, imm(0xffff))

Modified: pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/backend/x86/regalloc.py	Fri Nov 27 22:23:13 2009
@@ -100,10 +100,9 @@
         
     def after_call(self, v):
         # the result is stored in st0, but we don't have this around,
-        # so we move it to some stack location
-        if v is not None:
-            loc = self.stack_manager.loc(v, 2)
-            self.assembler.regalloc_fstp(loc)
+        # so genop_call will move it to some stack location immediately
+        # after the call
+        return self.stack_manager.loc(v, 2)
 
 class X86StackManager(StackManager):
 
@@ -290,7 +289,7 @@
                                                    arglocs, result_loc,
                                                    self.sm.stack_depth)
         if op.result is not None:
-            self.rm.possibly_free_var(op.result)
+            self.possibly_free_var(op.result)
         self.possibly_free_vars(guard_op.fail_args)
 
     def perform_guard(self, guard_op, arglocs, result_loc):
@@ -614,17 +613,17 @@
         save_all_regs = guard_not_forced_op is not None
         self.rm.before_call(force_store, save_all_regs=save_all_regs)
         self.xrm.before_call(force_store, save_all_regs=save_all_regs)
-        if guard_not_forced_op is not None:
-            if op.result is not None:
-                self.force_allocate_reg(op.result, selected_reg=eax)  # XXX!!!
-            self.perform_with_guard(op, guard_not_forced_op, arglocs, eax)
-        else:
-            self.Perform(op, arglocs, eax)
         if op.result is not None:
             if op.result.type == FLOAT:
-                self.xrm.after_call(op.result)
+                resloc = self.xrm.after_call(op.result)
             else:
-                self.rm.after_call(op.result)
+                resloc = self.rm.after_call(op.result)
+        else:
+            resloc = None
+        if guard_not_forced_op is not None:
+            self.perform_with_guard(op, guard_not_forced_op, arglocs, resloc)
+        else:
+            self.Perform(op, arglocs, resloc)
 
     def _consider_call(self, op, guard_not_forced_op=None):
         calldescr = op.descr



More information about the Pypy-commit mailing list