Author: Armin Rigo <ar...@tunes.org>
Branch: jitypes2
Changeset: r44184:42c0606d02bf
Date: 2011-05-15 18:23 +0200
http://bitbucket.org/pypy/pypy/changeset/42c0606d02bf/

Log:    Fixes:

        * implement saving and restoring registers like %eax around the
        initial call to close the stack.

        * fix a bug in saving/restoring %eax around the final call to
        reopen the stack: cannot save it on [ESP], because that's going to
        be overwritten by the call.

diff --git a/pypy/jit/backend/x86/assembler.py 
b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -2044,8 +2044,7 @@
             # like %eax that would be destroyed by this call, *and* they are
             # used by arglocs for the *next* call, then trouble; for now we
             # will just push/pop them.
-            XXXXXXX
-            self.call_close_stack()
+            self.call_close_stack(arglocs)
         # do the call
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -2058,7 +2057,7 @@
         self.mc.CMP_bi(FORCE_INDEX_OFS, 0)
         self.implement_guard(guard_token, 'L')
 
-    def call_close_stack(self):
+    def call_close_stack(self, save_registers):
         from pypy.rpython.memory.gctransform import asmgcroot
         css = self._regalloc.close_stack_struct
         if css == 0:
@@ -2067,6 +2066,17 @@
             pos = self._regalloc.fm.reserve_location_in_frame(use_words)
             css = get_ebp_ofs(pos + use_words - 1)
             self._regalloc.close_stack_struct = css
+        # First, we need to save away the registers listed in
+        # 'save_registers' that are not callee-save.  XXX We assume that
+        # the XMM registers won't be modified.  We store them in
+        # [ESP+4], [ESP+8], etc., leaving enough room in [ESP] for the
+        # single argument to closestack_addr below.
+        p = WORD
+        for reg in self._regalloc.rm.save_around_call_regs:
+            if reg in save_registers:
+                self.mc.MOV_sr(p, reg.value)
+                p += WORD
+        self._regalloc.reserve_param(p//WORD)
         # The location where the future CALL will put its return address
         # will be [ESP-WORD], so save that as the next frame's top address
         self.mc.LEA_rs(eax.value, -WORD)        # LEA EAX, [ESP-4]
@@ -2082,15 +2092,20 @@
             reg = edi
         self.mc.LEA_rb(reg.value, css)
         self._emit_call(-1, imm(self.closestack_addr), [reg])
+        # Finally, restore the registers saved above.
+        p = WORD
+        for reg in self._regalloc.rm.save_around_call_regs:
+            if reg in save_registers:
+                self.mc.MOV_rs(reg.value, p)
+                p += WORD
 
     def call_reopen_stack(self, save_loc):
-        # save the previous result (eax/xmm0) into the stack temporarily
-        if isinstance(save_loc, RegLoc):
-            self._regalloc.reserve_param(save_loc.width//WORD)
-            if save_loc.is_xmm:
-                self.mc.MOVSD_sx(0, save_loc.value)
-            else:
-                self.mc.MOV_sr(0, save_loc.value)
+        # save the previous result (eax/xmm0) into the stack temporarily.
+        # XXX like with call_close_stack(), we assume that we don't need
+        # to save xmm0 in this case.
+        if isinstance(save_loc, RegLoc) and not save_loc.is_xmm:
+            self.mc.MOV_sr(WORD, save_loc.value)
+            self._regalloc.reserve_param(2)
         # call the reopenstack() function (also reacquiring the GIL)
         css = self._regalloc.close_stack_struct
         assert css != 0
@@ -2101,11 +2116,8 @@
         self.mc.LEA_rb(reg.value, css)
         self._emit_call(-1, imm(self.reopenstack_addr), [reg])
         # restore the result from the stack
-        if isinstance(save_loc, RegLoc):
-            if save_loc.is_xmm:
-                self.mc.MOVSD_xs(save_loc.value, 0)
-            else:
-                self.mc.MOV_rs(save_loc.value, 0)
+        if isinstance(save_loc, RegLoc) and not save_loc.is_xmm:
+            self.mc.MOV_rs(save_loc.value, WORD)
 
     def genop_guard_call_assembler(self, op, guard_op, guard_token,
                                    arglocs, result_loc):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to