Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit