[pypy-commit] pypy s390x-backend: passing floating point guard instructions! nan handling was a little bit delicate for equal. stores information on an extra bit for float comparison

plan_rich noreply at buildbot.pypy.org
Mon Nov 23 08:34:01 EST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: s390x-backend
Changeset: r80854:bf6e032b454c
Date: 2015-11-23 14:34 +0100
http://bitbucket.org/pypy/pypy/changeset/bf6e032b454c/

Log:	passing floating point guard instructions! nan handling was a little
	bit delicate for equal. stores information on an extra bit for float
	comparison

diff --git a/rpython/jit/backend/zarch/conditions.py b/rpython/jit/backend/zarch/conditions.py
--- a/rpython/jit/backend/zarch/conditions.py
+++ b/rpython/jit/backend/zarch/conditions.py
@@ -1,37 +1,60 @@
 from rpython.jit.backend.zarch import locations as loc
 from rpython.rlib.objectmodel import specialize
 
+class ConditionLocation(loc.ImmLocation):
+    def __repr__(self):
+        s = ""
+        if self.value & 0x10 != 0:
+            s += "!FLOAT! "
+        if self.value & 0x1 != 0:
+            s += "OF"
+        if self.value & 0x2 != 0:
+            s += " GT"
+        if self.value & 0x4 != 0:
+            s += " LT"
+        if self.value & 0x8 != 0:
+            s += " EQ"
+        return "cond(%s)" % s
+
 # normal branch instructions
-EQ = loc.imm(0x8)
-LT = loc.imm(0x4)
-GT = loc.imm(0x2)
-OF = loc.imm(0x1) # overflow
-LE = loc.imm(EQ.value | LT.value)
-GE = loc.imm(EQ.value | GT.value)
-NE = loc.imm(LT.value | GT.value)
-NO = loc.imm(0xe) # NO overflow
-ANY = loc.imm(0xf)
+FLOAT = ConditionLocation(0x10)
+EQ = ConditionLocation(0x8)
+LT = ConditionLocation(0x4)
+GT = ConditionLocation(0x2)
+OF = ConditionLocation(0x1) # overflow
+LE = ConditionLocation(EQ.value | LT.value)
+GE = ConditionLocation(EQ.value | GT.value)
+NE = ConditionLocation(LT.value | GT.value | OF.value)
+NO = ConditionLocation(0xe) # NO overflow
+ANY = ConditionLocation(0xf)
 
 FP_ROUND_DEFAULT = loc.imm(0x0)
 FP_TOWARDS_ZERO = loc.imm(0x5)
 
 cond_none = loc.imm(0x0)
 
- at specialize.arg(1)
-def negate(cond, inv_overflow=False):
-    if cond is OF:
-        return NO
-    if cond is NO:
-        return OF
-    overflow = cond.value & 0x1
-    value = (~cond.value) & 0xe
-    return loc.imm(value | overflow)
+def negate(cond):
+    isfloat = (cond.value & 0x10) != 0
+    if isfloat:
+        # inverting is handeled differently for floats
+        # overflow is never inverted
+        value = (~cond.value) & 0xf
+        return ConditionLocation(value | FLOAT.value)
+    value = (~cond.value) & 0xf
+    return ConditionLocation(value)
 
-assert negate(EQ).value == NE.value
-assert negate(NE).value == EQ.value
-assert negate(LT).value == GE.value
-assert negate(LE).value == GT.value
-assert negate(GT).value == LE.value
-assert negate(GE).value == LT.value
+def prepare_float_condition(cond):
+    newcond = ConditionLocation(cond.value | FLOAT.value)
+    return newcond
+
+def _assert_invert(v1, v2):
+    assert (v1.value & 0xe) == (v2.value & 0xe)
+_assert_invert(negate(EQ), NE)
+_assert_invert(negate(NE), EQ)
+_assert_invert(negate(LT), GE)
+_assert_invert(negate(LE), GT)
+_assert_invert(negate(GT), LE)
+_assert_invert(negate(GE), LT)
+assert negate(NO).value == OF.value
 assert negate(OF).value == NO.value
-assert negate(NO).value == OF.value
+del _assert_invert
diff --git a/rpython/jit/backend/zarch/helper/assembler.py b/rpython/jit/backend/zarch/helper/assembler.py
--- a/rpython/jit/backend/zarch/helper/assembler.py
+++ b/rpython/jit/backend/zarch/helper/assembler.py
@@ -14,20 +14,10 @@
     self.mc.cmp_op(l0, l1, pool=l1.is_in_pool(), imm=l1.is_imm(), signed=signed, fp=fp)
 
     if fp:
-        # Support for NaNs: with LE or GE, if one of the operands is a
-        # NaN, we get CR=1,0,0,0 (unordered bit only).  We're about to
-        # check "not GT" or "not LT", but in case of NaN we want to
-        # get the answer False.
-        if condition == c.LE:
-            pass
-            # TODO xxx
-            #self.mc.crnor(1, 1, 3)
-            #condition = c.GT
-        elif condition == c.GE:
-            pass
-            #xxx
-            #self.mc.crnor(0, 0, 3)
-            #condition = c.LT
+        # Support for NaNs: S390X sets condition register to 0x3 (unordered)
+        # as soon as any of the operands is NaN
+        condition = c.prepare_float_condition(condition)
+        print("condition is:", condition)
     self.flush_cc(condition, arglocs[2])
 
 
diff --git a/rpython/jit/backend/zarch/opassembler.py b/rpython/jit/backend/zarch/opassembler.py
--- a/rpython/jit/backend/zarch/opassembler.py
+++ b/rpython/jit/backend/zarch/opassembler.py
@@ -228,10 +228,12 @@
         return token
 
     def emit_guard_true(self, op, arglocs, regalloc):
+        print("GUARD_TRUE condition to jump is:", self.guard_success_cc)
         self._emit_guard(op, arglocs)
 
     def emit_guard_false(self, op, arglocs, regalloc):
         self.guard_success_cc = c.negate(self.guard_success_cc)
+        print("GUARD_FALSE condition to jump is:", self.guard_success_cc)
         self._emit_guard(op, arglocs)
 
     def emit_guard_overflow(self, op, arglocs, regalloc):


More information about the pypy-commit mailing list