[pypy-svn] pypy default: A complete test for genop_guard_float_{comparison}.
arigo
commits-noreply at bitbucket.org
Fri Jan 14 18:27:39 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r40693:208b81273595
Date: 2011-01-14 18:15 +0100
http://bitbucket.org/pypy/pypy/changeset/208b81273595/
Log: A complete test for genop_guard_float_{comparison}. Fixes.
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
@@ -408,8 +408,10 @@
tok.faildescr._x86_adr_jump_offset = addr
relative_target = tok.pos_recovery_stub - (tok.pos_jump_offset + 4)
assert rx86.fits_in_32bits(relative_target)
- p = rffi.cast(rffi.INTP, addr)
- p[0] = rffi.cast(rffi.INT, relative_target)
+ #
+ mc = codebuf.MachineCodeBlockWrapper()
+ mc.writeimm32(relative_target)
+ mc.copy_to_raw_memory(addr)
def get_asmmemmgr_blocks(self, looptoken):
clt = looptoken.compiled_loop_token
@@ -859,22 +861,33 @@
self.implement_guard(guard_token, false_cond)
return genop_cmp_guard
- def _cmpop_guard_float(cond, false_cond, need_jp):
+ def _cmpop_guard_float(cond, rev_cond, false_cond, false_rev_cond):
+ need_direct_jp = 'A' not in cond
+ need_rev_jp = 'A' not in rev_cond
def genop_cmp_guard_float(self, op, guard_op, guard_token, arglocs,
result_loc):
guard_opnum = guard_op.getopnum()
- self.mc.UCOMISD(arglocs[0], arglocs[1])
+ if isinstance(arglocs[0], RegLoc):
+ self.mc.UCOMISD(arglocs[0], arglocs[1])
+ checkcond = cond
+ checkfalsecond = false_cond
+ need_jp = need_direct_jp
+ else:
+ self.mc.UCOMISD(arglocs[1], arglocs[0])
+ checkcond = rev_cond
+ checkfalsecond = false_rev_cond
+ need_jp = need_rev_jp
if guard_opnum == rop.GUARD_FALSE:
if need_jp:
self.mc.J_il8(rx86.Conditions['P'], 6)
- self.implement_guard(guard_token, cond)
+ self.implement_guard(guard_token, checkcond)
else:
if need_jp:
self.mc.J_il8(rx86.Conditions['P'], 2)
- self.mc.J_il8(rx86.Conditions[cond], 5)
+ self.mc.J_il8(rx86.Conditions[checkcond], 5)
self.implement_guard(guard_token)
else:
- self.implement_guard(guard_token, false_cond)
+ self.implement_guard(guard_token, checkfalsecond)
return genop_cmp_guard_float
def _emit_call(self, x, arglocs, start=0, tmp=eax):
@@ -1022,15 +1035,18 @@
genop_guard_uint_le = _cmpop_guard("BE", "AE", "A", "B")
genop_guard_uint_ge = _cmpop_guard("AE", "BE", "B", "A")
- genop_guard_float_lt = _cmpop_guard_float("B", "AE", True)
- genop_guard_float_le = _cmpop_guard_float("BE", "A", True)
- genop_guard_float_eq = _cmpop_guard_float("E", "NE", True)
- genop_guard_float_gt = _cmpop_guard_float("A", "BE", False)
- genop_guard_float_ge = _cmpop_guard_float("AE", "B", False)
+ genop_guard_float_lt = _cmpop_guard_float("B", "A", "AE","BE")
+ genop_guard_float_le = _cmpop_guard_float("BE","AE", "A", "B")
+ genop_guard_float_eq = _cmpop_guard_float("E", "E", "NE","NE")
+ genop_guard_float_gt = _cmpop_guard_float("A", "B", "BE","AE")
+ genop_guard_float_ge = _cmpop_guard_float("AE","BE", "B", "A")
def genop_guard_float_ne(self, op, guard_op, guard_token, arglocs, result_loc):
guard_opnum = guard_op.getopnum()
- self.mc.UCOMISD(arglocs[0], arglocs[1])
+ if isinstance(arglocs[0], RegLoc):
+ self.mc.UCOMISD(arglocs[0], arglocs[1])
+ else:
+ self.mc.UCOMISD(arglocs[1], arglocs[0])
if guard_opnum == rop.GUARD_TRUE:
self.mc.J_il8(rx86.Conditions['P'], 6)
self.implement_guard(guard_token, 'E')
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -1067,6 +1067,64 @@
for i in range(1, len(fboxes)):
assert self.cpu.get_latest_value_float(i) == 13.5 + 6.73 * i
+ def test_floats_and_guards(self):
+ for opname, compare in [
+ (rop.FLOAT_LT, lambda x, y: x < y),
+ (rop.FLOAT_LE, lambda x, y: x <= y),
+ (rop.FLOAT_EQ, lambda x, y: x == y),
+ (rop.FLOAT_NE, lambda x, y: x != y),
+ (rop.FLOAT_GT, lambda x, y: x > y),
+ (rop.FLOAT_GE, lambda x, y: x >= y),
+ ]:
+ for opguard, guard_case in [
+ (rop.GUARD_FALSE, False),
+ (rop.GUARD_TRUE, True),
+ ]:
+ for combinaison in ["bb", "bc", "cb"]:
+ #
+ if combinaison[0] == 'b':
+ fbox1 = BoxFloat()
+ else:
+ fbox1 = ConstFloat(-4.5)
+ if combinaison[1] == 'b':
+ fbox2 = BoxFloat()
+ else:
+ fbox2 = ConstFloat(-4.5)
+ b1 = BoxInt()
+ faildescr1 = BasicFailDescr(1)
+ faildescr2 = BasicFailDescr(2)
+ inputargs = [fb for fb in [fbox1, fbox2]
+ if isinstance(fb, BoxFloat)]
+ operations = [
+ ResOperation(opname, [fbox1, fbox2], b1),
+ ResOperation(opguard, [b1], None, descr=faildescr1),
+ ResOperation(rop.FINISH, [], None, descr=faildescr2),
+ ]
+ operations[-2].setfailargs([])
+ looptoken = LoopToken()
+ self.cpu.compile_loop(inputargs, operations, looptoken)
+ #
+ cpu = self.cpu
+ nan = 1e200 * 1e200
+ nan /= nan
+ for test1 in [-6.5, -4.5, -2.5, nan]:
+ if test1 == -4.5 or combinaison[0] == 'b':
+ for test2 in [-6.5, -4.5, -2.5, nan]:
+ if test2 == -4.5 or combinaison[1] == 'b':
+ n = 0
+ if combinaison[0] == 'b':
+ cpu.set_future_value_float(n, test1)
+ n += 1
+ if combinaison[1] == 'b':
+ cpu.set_future_value_float(n, test2)
+ n += 1
+ cpu.set_future_value_float(1, test2)
+ fail = cpu.execute_token(looptoken)
+ #
+ expected = compare(test1, test2)
+ expected ^= guard_case
+ assert fail.identifier == 2 - expected
+
def test_unused_result_int(self):
# test pure operations on integers whose result is not used
from pypy.jit.metainterp.test.test_executor import get_int_tests
More information about the Pypy-commit
mailing list