From 0ab5481f30050ed8a84fb6f77fdf48f0fc0678c4 Mon Sep 17 00:00:00 2001
From: janis <janis@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 16 Jan 2007 18:53:16 +0000
Subject: [PATCH] gcc/ 	* config/dfp-bit.c (dfp_compare_op): Return separate
 value for NaN. 	(DFP_NE, DFP_LE, DFP_GE): Return false for NaN.
 gcc/testsuite/ 	* gcc.dg/dfp/compare-special.h: New file. 	*
 gcc.dg/dfp/compare-special-32.c: New test. 	*
 gcc.dg/dfp/compare-special-64.c: New test. 	*
 gcc.dg/dfp/compare-special-128.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120830 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                                 |   5 +
 gcc/config/dfp-bit.c                          |  10 +-
 gcc/testsuite/ChangeLog                       |   7 +
 .../gcc.dg/dfp/compare-special-d128.c         |  15 +
 .../gcc.dg/dfp/compare-special-d32.c          |  15 +
 .../gcc.dg/dfp/compare-special-d64.c          |  15 +
 gcc/testsuite/gcc.dg/dfp/compare-special.h    | 287 ++++++++++++++++++
 7 files changed, 353 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
 create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
 create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
 create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special.h

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf4cd24f51d9..80e90935bbd6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-16  Janis Johnson  <janis187@us.ibm.com>
+
+	* config/dfp-bit.c (dfp_compare_op): Return separate value for NaN.
+	(DFP_NE, DFP_LE, DFP_GE): Return false for NaN.
+
 2007-01-16  David Edelsohn  <edelsohn@gnu.org>
 
 	* config/rs6000/darwin-ldouble.c: Build file for SOFT_FLOAT.
diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c
index 0ee2083e835b..47575ccc8b77 100644
--- a/gcc/config/dfp-bit.c
+++ b/gcc/config/dfp-bit.c
@@ -146,6 +146,8 @@ dfp_compare_op (dfp_binary_func op, DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
     result = -1;
   else if (decNumberIsZero (&res))
     result = 0;
+  else if (decNumberIsNaN (&res))
+    result = -2;
   else
     result = 1;
 
@@ -302,7 +304,9 @@ DFP_NE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
 {
   int stat;
   stat = dfp_compare_op (decNumberCompare, arg_a, arg_b);
-  /* For NE return nonzero for true, zero for false.  */
+  /* For NE return zero for true, nonzero for false.  */
+  if (__builtin_expect (stat == -2, 0))  /* An operand is NaN.  */
+    return 1;
   return stat != 0;
 }
 #endif /* L_ne */
@@ -336,6 +340,8 @@ DFP_LE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
   int stat;
   stat = dfp_compare_op (decNumberCompare, arg_a, arg_b);
   /* For LE return 0 (<= 0) for true, 1 for false.  */
+  if (__builtin_expect (stat == -2, 0))  /* An operand is NaN.  */
+    return 1;
   return stat == 1;
 }
 #endif /* L_le */
@@ -347,6 +353,8 @@ DFP_GE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
   int stat;
   stat = dfp_compare_op (decNumberCompare, arg_a, arg_b);
   /* For GE return 1 (>=0) for true, -1 for false.  */
+  if (__builtin_expect (stat == -2, 0))  /* An operand is NaN.  */
+    return -1;
   return (stat != -1) ? 1 : -1;
 }
 #endif /* L_ge */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5d3374783bbb..b098046ddbce 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2007-01-16  Janis Johnson  <janis187@us.ibm.com>
+
+	* gcc.dg/dfp/compare-special.h: New file.
+	* gcc.dg/dfp/compare-special-32.c: New test.
+	* gcc.dg/dfp/compare-special-64.c: New test.
+	* gcc.dg/dfp/compare-special-128.c: New test.
+
 2007-01-16  Roger Sayle  <roger@eyesopen.com>
 	    Paul Thomas  <pault@gcc.gnu.org>
 	    Steven G. Kargl  <kargl@gcc.gnu.org>
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
new file mode 100644
index 000000000000..cef4670b7664
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c
@@ -0,0 +1,15 @@
+/* { dg-options "-std=gnu99 -O0" } */
+
+/* C99 6.5.8 Relational operators.
+   C99 6.5.9 Equality operators.
+   Compare decimal float special values at runtime.  */
+
+#define WIDTH 128
+#include "compare-special.h"
+
+int
+main ()
+{
+  test_compares ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
new file mode 100644
index 000000000000..fa91d7edd33f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c
@@ -0,0 +1,15 @@
+/* { dg-options "-std=gnu99 -O0" } */
+
+/* C99 6.5.8 Relational operators.
+   C99 6.5.9 Equality operators.
+   Compare decimal float special values at runtime.  */
+
+#define WIDTH 32
+#include "compare-special.h"
+
+int
+main ()
+{
+  test_compares ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
new file mode 100644
index 000000000000..2238e0190e3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c
@@ -0,0 +1,15 @@
+/* { dg-options "-std=gnu99 -O0" } */
+
+/* C99 6.5.8 Relational operators.
+   C99 6.5.9 Equality operators.
+   Compare decimal float special values at runtime.  */
+
+#define WIDTH 64
+#include "compare-special.h"
+
+int
+main ()
+{
+  test_compares ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special.h b/gcc/testsuite/gcc.dg/dfp/compare-special.h
new file mode 100644
index 000000000000..1bd77e521563
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/compare-special.h
@@ -0,0 +1,287 @@
+/* Basic test of runtime relational comparisons using NaNs and infinities.  */
+
+#include <stdlib.h>
+
+static int failcnt;
+
+#define PASTE2(A,B) A ## B
+#define PASTE(A,B) PASTE2(A,B)
+
+#ifdef DBG
+#include <stdio.h>
+#define FAILURE(OP,KIND) \
+  { printf ("failed at line %d: %s for %s values\n", __LINE__, OP, KIND); \
+    failcnt++; }
+#else
+#define FAILURE(OP,KIND) abort ();
+#endif
+
+#ifndef WIDTH
+#error define WIDTH as decimal float size in bytes
+#endif
+
+#if WIDTH == 32
+#define DTYPE _Decimal32
+#define SUFFIX DF
+#define SUFFIX2 d32
+#elif WIDTH == 64
+#define DTYPE _Decimal64
+#define SUFFIX DD
+#define SUFFIX2 d64
+#elif WIDTH == 128
+#define DTYPE _Decimal128
+#define SUFFIX DL
+#define SUFFIX2 d128
+#elif WIDTH == 0
+/* This is for testing the test using a type known to work.  */
+#define DTYPE double
+#define SUFFIX
+#define SUFFIX2
+#else
+#error invalid width for decimal float type
+#endif
+
+DTYPE m_two = PASTE(-2.0, SUFFIX);
+DTYPE m_one = PASTE(-1.0, SUFFIX);
+DTYPE zero  = PASTE(0.0, SUFFIX);
+DTYPE one   = PASTE(1.0, SUFFIX);
+DTYPE two   = PASTE(2.0, SUFFIX);
+
+volatile DTYPE x, y, z, nan, inf, m_inf;
+
+void
+test_compares (void)
+{
+  nan = PASTE(__builtin_nan, SUFFIX2) ("");
+  inf = PASTE(__builtin_inf, SUFFIX2) ();
+  m_inf = - PASTE(__builtin_inf, SUFFIX2) ();
+
+  x = PASTE(__builtin_nan, SUFFIX2) ("");
+  y = PASTE(__builtin_inf, SUFFIX2) ();
+  z = - PASTE(__builtin_inf, SUFFIX2) ();
+
+  /* Less than or equal to with NaN.  */
+
+  if (x <= two)   FAILURE ("<=", "NaN")
+  if (x <= zero)  FAILURE ("<=", "NaN")
+  if (x <= m_one) FAILURE ("<=", "NaN")
+  if (x <= nan)   FAILURE ("<=", "NaN")
+  if (x <= inf)   FAILURE ("<=", "NaN")
+  if (x <= m_inf) FAILURE ("<=", "NaN")
+
+  if (two <= x)   FAILURE ("<=", "NaN")
+  if (zero <= x)  FAILURE ("<=", "NaN")
+  if (m_one <= x) FAILURE ("<=", "NaN")
+  if (nan <= x)   FAILURE ("<=", "NaN")
+  if (inf <= x)   FAILURE ("<=", "NaN")
+  if (m_inf <= x) FAILURE ("<=", "NaN")
+
+  /* Less than or equal to with infinities, no NaNs.  */
+
+  if (y <= two)      FAILURE ("<=", "inf")
+  if (y <= zero)     FAILURE ("<=", "inf")
+  if (y <= m_one)    FAILURE ("<=", "inf")
+  if (!(two <= y))   FAILURE ("<=", "inf")
+  if (!(zero <= y))  FAILURE ("<=", "inf")
+  if (!(m_one <= y)) FAILURE ("<=", "inf")
+
+  if (!(z <= two))   FAILURE ("<=", "-inf")
+  if (!(z <= zero))  FAILURE ("<=", "-inf")
+  if (!(z <= m_one)) FAILURE ("<=", "-inf")
+  if (two <= z)      FAILURE ("<=", "-inf")
+  if (zero <= z)     FAILURE ("<=", "-inf")
+  if (m_one <= z)    FAILURE ("<=", "-inf")
+
+  if (!(y <= inf))   FAILURE ("<=", "inf")
+  if (y <= m_inf)    FAILURE ("<=", "inf")
+  if (!(z <= inf))   FAILURE ("<=", "inf")
+  if (!(z <= m_inf)) FAILURE ("<=", "inf")
+
+  /* Less than with NaN.  */
+
+  if (x < two)       FAILURE ("<", "NaN")
+  if (x < zero)      FAILURE ("<", "NaN")
+  if (x < m_one)     FAILURE ("<", "NaN")
+  if (x < nan)       FAILURE ("<", "NaN")
+  if (x < inf)       FAILURE ("<", "NaN")
+  if (x < m_inf)     FAILURE ("<", "NaN")
+
+  if (two < x)       FAILURE ("<", "NaN")
+  if (zero < x)      FAILURE ("<", "NaN")
+  if (m_one < x)     FAILURE ("<", "NaN")
+  if (nan < x)       FAILURE ("<", "NaN")
+  if (inf < x)       FAILURE ("<", "NaN")
+  if (m_inf < x)     FAILURE ("<", "NaN")
+
+  /* Less than with infinities, no NaNs.  */
+
+  if (y < two)       FAILURE ("<", "inf")
+  if (y < zero)      FAILURE ("<", "inf")
+  if (y < m_one)     FAILURE ("<", "inf")
+  if (!(two < y))    FAILURE ("<", "inf")
+  if (!(zero < y))   FAILURE ("<", "inf")
+  if (!(m_one < y))  FAILURE ("<", "inf")
+
+  if (!(z < two))    FAILURE ("<", "-inf")
+  if (!(z < zero))   FAILURE ("<", "-inf")
+  if (!(z < m_one))  FAILURE ("<", "-inf")
+  if (two < z)       FAILURE ("<", "-inf")
+  if (zero < z)      FAILURE ("<", "-inf")
+  if (m_one < z)     FAILURE ("<", "-inf")
+
+  if (y < inf)       FAILURE ("<=", "inf")
+  if (y < m_inf)     FAILURE ("<=", "inf")
+  if (!(z < inf))    FAILURE ("<=", "inf")
+  if (z < m_inf)     FAILURE ("<=", "inf")
+
+  /* Greater than or equal to with NaN.  */
+
+  if (x >= two)      FAILURE (">=", "NaN")
+  if (x >= zero)     FAILURE (">=", "NaN")
+  if (x >= m_one)    FAILURE (">=", "NaN")
+  if (x >= nan)      FAILURE (">=", "NaN")
+  if (x >= inf)      FAILURE (">=", "NaN")
+  if (x >= m_inf)    FAILURE (">=", "NaN")
+
+  if (two >= x)      FAILURE (">=", "NaN")
+  if (zero >= x)     FAILURE (">=", "NaN")
+  if (m_one >= x)    FAILURE (">=", "NaN")
+  if (nan >= x)      FAILURE (">=", "NaN")
+  if (inf >= x)      FAILURE (">=", "NaN")
+  if (m_inf >= x)    FAILURE (">=", "NaN")
+
+  /* Greater than or equal to with infinities, no NaNs.  */
+
+  if (!(y >= two))   FAILURE (">=", "inf")
+  if (!(y >= zero))  FAILURE (">=", "inf")
+  if (!(y >= m_one)) FAILURE (">=", "inf")
+  if (two >= y)      FAILURE (">=", "inf")
+  if (zero >= y)     FAILURE (">=", "inf")
+  if (m_one >= y)    FAILURE (">=", "inf")
+
+  if (z >= two)      FAILURE (">=", "-inf")
+  if (z >= zero)     FAILURE (">=", "-inf")
+  if (z >= m_one)    FAILURE (">=", "-inf")
+  if (!(two >= z))   FAILURE (">=", "-inf")
+  if (!(zero >= z))  FAILURE (">=", "-inf")
+  if (!(m_one >= z)) FAILURE (">=", "-inf")
+
+  if (!(y >= inf))   FAILURE ("<=", "inf")
+  if (!(y >= m_inf)) FAILURE ("<=", "inf")
+  if (z >= inf)      FAILURE ("<=", "inf")
+  if (!(z >= m_inf)) FAILURE ("<=", "inf")
+
+  /* Greater than with NaN.  */
+
+  if (x > two)       FAILURE (">", "NaN")
+  if (x > zero)      FAILURE (">", "NaN")
+  if (x > m_one)     FAILURE (">", "NaN")
+  if (x > nan)       FAILURE (">", "NaN")
+  if (x > inf)       FAILURE (">", "NaN")
+  if (x > m_inf)     FAILURE (">", "NaN")
+
+  if (two > x)       FAILURE (">", "NaN")
+  if (zero > x)      FAILURE (">", "NaN")
+  if (m_one > x)     FAILURE (">", "NaN")
+  if (nan > x)       FAILURE (">", "NaN")
+  if (inf > x)       FAILURE (">", "NaN")
+  if (m_inf > x)     FAILURE (">", "NaN")
+
+  /* Greater than with infinities, no NaNs.  */
+
+  if (!(y > two))    FAILURE (">", "inf")
+  if (!(y > zero))   FAILURE (">", "inf")
+  if (!(y > m_one))  FAILURE (">", "inf")
+  if (two > y)       FAILURE (">", "inf")
+  if (zero > y)      FAILURE (">", "inf")
+  if (m_one > y)     FAILURE (">", "inf")
+
+  if (z > two)       FAILURE (">", "-inf")
+  if (z > zero)      FAILURE (">", "-inf")
+  if (z > m_one)     FAILURE (">", "-inf")
+  if (!(two > z))    FAILURE (">", "-inf")
+  if (!(zero > z))   FAILURE (">", "-inf")
+  if (!(m_one > z))  FAILURE (">", "-inf")
+
+  if (y > inf)       FAILURE (">", "inf")
+  if (!(y > m_inf))  FAILURE (">", "inf")
+  if (z > inf)       FAILURE (">", "inf")
+  if (z > m_inf)     FAILURE (">", "inf")
+
+  /* Equal with NaN.  */
+
+  if (x == two)      FAILURE ("==", "NaN")
+  if (x == zero)     FAILURE ("==", "NaN")
+  if (x == m_one)    FAILURE ("==", "NaN")
+  if (x == nan)      FAILURE ("==", "NaN")
+  if (x == inf)      FAILURE ("==", "NaN")
+  if (x == m_inf)    FAILURE ("==", "NaN")
+
+  if (two == x)      FAILURE ("==", "NaN")
+  if (zero == x)     FAILURE ("==", "NaN")
+  if (m_one == x)    FAILURE ("==", "NaN")
+  if (nan == x)      FAILURE ("==", "NaN")
+  if (inf == x)      FAILURE ("==", "NaN")
+  if (m_inf == x)    FAILURE ("==", "NaN")
+
+  /* Equal with infinities, no NaNs.  */
+
+  if (y == two)      FAILURE ("==", "inf")
+  if (y == zero)     FAILURE ("==", "inf")
+  if (y == m_one)    FAILURE ("==", "inf")
+  if (two == y)      FAILURE ("==", "inf")
+  if (zero == y)     FAILURE ("==", "inf")
+  if (m_one == y)    FAILURE ("==", "inf")
+
+  if (z == two)      FAILURE ("==", "-inf")
+  if (z == zero)     FAILURE ("==", "-inf")
+  if (z == m_one)    FAILURE ("==", "-inf")
+  if (two == z)      FAILURE ("==", "-inf")
+  if (zero == z)     FAILURE ("==", "-inf")
+  if (m_one == z)    FAILURE ("==", "-inf")
+
+  if (!(y == inf))   FAILURE ("==", "inf")
+  if (y == m_inf)    FAILURE ("==", "inf")
+  if (z == inf)      FAILURE ("==", "inf")
+  if (!(z == m_inf)) FAILURE ("==", "inf")
+
+  /* Not equal with NaN.  */
+
+  if (!(x != two))   FAILURE ("!=", "NaN")
+  if (!(x != zero))  FAILURE ("!=", "NaN")
+  if (!(x != m_one)) FAILURE ("!=", "NaN")
+  if (!(x != nan))   FAILURE ("!=", "NaN")
+  if (!(x != inf))   FAILURE ("!=", "NaN")
+  if (!(x != m_inf)) FAILURE ("!=", "NaN")
+
+  if (!(two != x))   FAILURE ("!=", "NaN")
+  if (!(zero != x))  FAILURE ("!=", "NaN")
+  if (!(m_one != x)) FAILURE ("!=", "NaN")
+  if (!(nan != x))   FAILURE ("!=", "NaN")
+  if (!(inf != x))   FAILURE ("!=", "NaN")
+  if (!(m_inf != x)) FAILURE ("!=", "NaN")
+
+  /* Not equal with infinities, no NaNs.  */
+
+  if (!(y != two))   FAILURE ("!=", "inf")
+  if (!(y != zero))  FAILURE ("!=", "inf")
+  if (!(y != m_one)) FAILURE ("!=", "inf")
+  if (!(two != y))   FAILURE ("!=", "inf")
+  if (!(zero != y))  FAILURE ("!=", "inf")
+  if (!(m_one != y)) FAILURE ("!=", "inf")
+
+  if (!(z != two))   FAILURE ("!=", "-inf")
+  if (!(z != zero))  FAILURE ("!=", "-inf")
+  if (!(z != m_one)) FAILURE ("!=", "-inf")
+  if (!(two != z))   FAILURE ("!=", "-inf")
+  if (!(zero != z))  FAILURE ("!=", "-inf")
+  if (!(m_one != z)) FAILURE ("!=", "-inf")
+
+  if (y != inf)      FAILURE ("!=", "inf")
+  if (!(y != m_inf)) FAILURE ("!=", "inf")
+  if (!(z != inf))   FAILURE ("!=", "inf")
+  if (z != m_inf)    FAILURE ("!=", "inf")
+
+  if (failcnt)
+    abort ();
+}
-- 
GitLab