[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