[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