Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r65781:caa2340430f2
Date: 2013-07-29 14:59 +0200
http://bitbucket.org/pypy/pypy/changeset/caa2340430f2/

Log:    Fix the test and generate more efficient code.

diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -14,7 +14,7 @@
 from rpython.rlib.jit import AsmInfo
 from rpython.jit.backend.model import CompiledLoopToken
 from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs,
-    gpr_reg_mgr_cls, xmm_reg_mgr_cls, _register_arguments)
+    gpr_reg_mgr_cls, xmm_reg_mgr_cls)
 from rpython.jit.backend.llsupport.regalloc import (get_scale, 
valid_addressing_size)
 from rpython.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD, IS_X86_64,
                                        JITFRAME_FIXED_SIZE, IS_X86_32,
@@ -154,7 +154,11 @@
         come.
         """
         mc = codebuf.MachineCodeBlockWrapper()
-        self._push_all_regs_to_frame(mc, [], supports_floats, callee_only)
+        # copy registers to the frame, with the exception of the
+        # 'cond_call_register_arguments' and eax, because these have already
+        # been saved by the caller
+        self._push_all_regs_to_frame(mc, cond_call_register_arguments + [eax],
+                                     supports_floats, callee_only)
         if IS_X86_64:
             mc.SUB(esp, imm(WORD))
             self.set_extra_stack_depth(mc, 2 * WORD)
@@ -164,7 +168,7 @@
             mc.SUB(esp, imm(WORD * 7))
             self.set_extra_stack_depth(mc, 8 * WORD)
             for i in range(4):
-                mc.MOV_sr(i * WORD, _register_arguments[i].value)
+                mc.MOV_sr(i * WORD, cond_call_register_arguments[i].value)
         mc.CALL(eax)
         if IS_X86_64:
             mc.ADD(esp, imm(WORD))
@@ -172,8 +176,7 @@
             mc.ADD(esp, imm(WORD * 7))
         self.set_extra_stack_depth(mc, 0)
         self._reload_frame_if_necessary(mc, align_stack=True)
-        self._pop_all_regs_from_frame(mc, [], supports_floats,
-                                      callee_only)
+        self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only)
         mc.RET()
         return mc.materialize(self.cpu.asmmemmgr, [])
 
@@ -1755,7 +1758,7 @@
             regs = gpr_reg_mgr_cls.save_around_call_regs
         else:
             regs = gpr_reg_mgr_cls.all_regs
-        for i, gpr in enumerate(regs):
+        for gpr in regs:
             if gpr not in ignored_regs:
                 v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
                 mc.MOV_br(v * WORD + base_ofs, gpr.value)
@@ -1777,7 +1780,7 @@
             regs = gpr_reg_mgr_cls.save_around_call_regs
         else:
             regs = gpr_reg_mgr_cls.all_regs
-        for i, gpr in enumerate(regs):
+        for gpr in regs:
             if gpr not in ignored_regs:
                 v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
                 mc.MOV_rb(gpr.value, v * WORD + base_ofs)
@@ -2161,11 +2164,29 @@
     def label(self):
         self._check_frame_depth_debug(self.mc)
 
-    def cond_call(self, op, gcmap, cond_loc, call_loc):
-        self.mc.TEST(cond_loc, cond_loc)
+    def cond_call(self, op, gcmap, loc_cond, imm_func, arglocs):
+        self.mc.TEST(loc_cond, loc_cond)
         self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
         jmp_adr = self.mc.get_relative_pos()
+        #
         self.push_gcmap(self.mc, gcmap, store=True)
+        #
+        # first save away the 4 registers from 'cond_call_register_arguments'
+        # plus the register 'eax'
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        for gpr in cond_call_register_arguments + [eax]:
+            v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
+            self.mc.MOV_br(v * WORD + base_ofs, gpr.value)
+        #
+        # load the 0-to-4 arguments into these registers
+        from rpython.jit.backend.x86.jump import remap_frame_layout
+        remap_frame_layout(self, arglocs,
+                           cond_call_register_arguments[:len(arglocs)], eax)
+        #
+        # load the constant address of the function to call into eax
+        self.mc.MOV(eax, imm_func)
+        #
+        # figure out which variant of cond_call_slowpath to call, and call it
         callee_only = False
         floats = False
         if self._regalloc is not None:
@@ -2348,5 +2369,7 @@
     os.write(2, '[x86/asm] %s\n' % msg)
     raise NotImplementedError(msg)
 
+cond_call_register_arguments = [edi, esi, edx, ecx]
+
 class BridgeAlreadyCompiled(Exception):
     pass
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -119,8 +119,6 @@
 for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs):
     gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i
 
-_register_arguments = [edi, esi, edx, ecx]
-
 
 class RegAlloc(BaseRegalloc):
 
@@ -803,21 +801,15 @@
     def consider_cond_call(self, op):
         assert op.result is None
         args = op.getarglist()
-        assert 2 <= len(args) <= 4 + 2
-        tmpbox = TempBox()
-        self.rm.force_allocate_reg(tmpbox, selected_reg=eax)
+        assert 2 <= len(args) <= 4 + 2     # maximum 4 arguments
+        loc_cond = self.make_sure_var_in_reg(args[0], args)
         v = args[1]
         assert isinstance(v, Const)
-        imm = self.rm.convert_to_imm(v)
-        self.assembler.regalloc_mov(imm, eax)
-        args_so_far = [tmpbox]
-        for i in range(2, len(args)):
-            reg = _register_arguments[i - 2]
-            self.make_sure_var_in_reg(args[i], args_so_far, selected_reg=reg)
-            args_so_far.append(args[i])
-        loc_cond = self.make_sure_var_in_reg(args[0], args)
-        self.assembler.cond_call(op, self.get_gcmap([eax]), loc_cond, eax)
-        self.rm.possibly_free_var(tmpbox)
+        imm_func = self.rm.convert_to_imm(v)
+        arglocs = [self.loc(args[i]) for i in range(2, len(args))]
+        gcmap = self.get_gcmap()
+        self.rm.possibly_free_var(args[0])
+        self.assembler.cond_call(op, gcmap, loc_cond, imm_func, arglocs)
 
     def consider_call_malloc_nursery(self, op):
         size_box = op.getarg(0)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to