1.0.10.43: Fix NaN comparison on x86-64
authorNIIMI Satoshi <sa2c@users.sourceforge.net>
Thu, 11 Oct 2007 09:20:36 +0000 (09:20 +0000)
committerNIIMI Satoshi <sa2c@users.sourceforge.net>
Thu, 11 Oct 2007 09:20:36 +0000 (09:20 +0000)
Comisd and comiss sets all of ZF, PF, and CF of EFLAGS if its
operand contains NaN.  Because PF is never set by normal
comparison, we use it to check NaN.  This is same as "=" vops.

BUGS
NEWS
src/compiler/x86-64/float.lisp
tests/float.pure.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index cbcb818..9e778d1 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -1788,11 +1788,6 @@ WORKAROUND:
   implementation of read circularity, using a symbol as a marker for
   the previously-referenced object.
 
-411: NAN issues on x86-64
-  Test :NAN-COMPARISONS in float.pure.lisp fails on x86-64, and has been
-  disabled on those platforms. Since x86 does not exhibit any problems
-  the problem is probably with the new FP implementation.
-
 413: type-errors in ROOM
 
   (defvar *a* (make-array (expt 2 27)))
diff --git a/NEWS b/NEWS
index e6b1d1e..7421548 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ changes in sbcl-1.0.11 relative to sbcl-1.0.10:
     if the mutex is uncontested on Linux.
   * bug fix: symbol-macro expansion now uses the *MACROEXPAND-HOOK*
     as specified by the CLHS. (thanks to Tobias Rittweiler)
+  * bug fix: NaN comparison now works on x86-64.
 
 changes in sbcl-1.0.10 relative to sbcl-1.0.9:
   * minor incompatible change: the MSI installer on Windows no longer
index 63ae040..f1b7f41 100644 (file)
              (inst jmp :e target)
              (emit-label not-lab))))))
 
-;; XXX all of these probably have bad NaN behaviour
 (define-vop (<double-float double-float-compare)
   (:translate <)
   (:info target not-p)
-  (:generator 2
+  (:generator 3
     (inst comisd x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (cond (not-p
+           (inst jmp :p target)
+           (inst jmp :nc target))
+          (t
+           (let ((not-lab (gen-label)))
+             (inst jmp :p not-lab)
+             (inst jmp :c target)
+             (emit-label not-lab))))))
 
 (define-vop (<single-float single-float-compare)
   (:translate <)
   (:info target not-p)
-  (:generator 2
+  (:generator 3
     (inst comiss x y)
-    (inst jmp (if not-p :nc :c) target)))
+    (cond (not-p
+           (inst jmp :p target)
+           (inst jmp :nc target))
+          (t
+           (let ((not-lab (gen-label)))
+             (inst jmp :p not-lab)
+             (inst jmp :c target)
+             (emit-label not-lab))))))
 
 (define-vop (>double-float double-float-compare)
   (:translate >)
   (:info target not-p)
-  (:generator 2
+  (:generator 3
     (inst comisd x y)
-    (inst jmp (if not-p :na :a) target)))
+    (cond (not-p
+           (inst jmp :p target)
+           (inst jmp :na target))
+          (t
+           (let ((not-lab (gen-label)))
+             (inst jmp :p not-lab)
+             (inst jmp :a target)
+             (emit-label not-lab))))))
 
 (define-vop (>single-float single-float-compare)
   (:translate >)
   (:info target not-p)
-  (:generator 2
+  (:generator 3
     (inst comiss x y)
-    (inst jmp (if not-p :na :a) target)))
+    (cond (not-p
+           (inst jmp :p target)
+           (inst jmp :na target))
+          (t
+           (let ((not-lab (gen-label)))
+             (inst jmp :p not-lab)
+             (inst jmp :a target)
+             (emit-label not-lab))))))
 
 
 \f
index e9fbd86..724d208 100644 (file)
 
 
 (with-test (:name :nan-comparisons
-            :fails-on '(or :x86-64 :sparc :mips))
+            :fails-on '(or :sparc :mips))
   (sb-int:with-float-traps-masked (:invalid)
     (macrolet ((test (form)
                  (let ((nform (subst '(/ 0.0 0.0) 'nan form)))
index 809f581..ca2ed52 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.10.42"
+"1.0.10.43"