Commits

Armin Rigo committed 208b812

A complete test for genop_guard_float_{comparison}.
Fixes.

Comments (0)

Files changed (2)

pypy/jit/backend/test/runner_test.py

         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

pypy/jit/backend/x86/assembler.py

             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
                     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):
     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')