float.h: C2x decimal signaling NaN macros
authorJoseph Myers <joseph@codesourcery.com>
Tue, 17 Nov 2020 00:27:06 +0000 (00:27 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 17 Nov 2020 00:27:06 +0000 (00:27 +0000)
C2x adds macros for decimal floating-point signaling NaNs to
<float.h>.  Add these macros to GCC's <float.h> implementation.

Note that the current C2x draft has these under incorrect names
D32_SNAN, D64_SNAN, D128_SNAN.  The intent was to change the naming
convention to be consistent with other <float.h> macros when they were
moved to <float.h>, so DEC32_SNAN, DEC64_SNAN, DEC128_NAN, which this
patch uses (as does the current draft integration of TS 18661-3 as an
Annex to C2x, for its _Decimal* and _Decimal*x types).

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/
2020-11-17  Joseph Myers  <joseph@codesourcery.com>

* ginclude/float.h (DEC32_SNAN, DEC64_SNAN, DEC128_SNAN): New C2x
macros.

gcc/testsuite/
2020-11-17  Joseph Myers  <joseph@codesourcery.com>

* gcc.dg/dfp/c2x-float-dfp-7.c, gcc.dg/dfp/c2x-float-dfp-8.c: New
tests.
* gcc.dg/c2x-float-no-dfp-3.c: Also check that DEC32_SNAN,
DEC64_SNAN and DEC128_SNAN are not defined.

gcc/ginclude/float.h
gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c
gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c [new file with mode: 0644]

index 7744699..0fa0046 100644 (file)
@@ -601,6 +601,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #undef DEC_NAN
 #define DEC_NAN                (__builtin_nand32 (""))
 
+/* Signaling NaN in each decimal floating-point type.  */
+#undef DEC32_SNAN
+#define DEC32_SNAN     (__builtin_nansd32 (""))
+#undef DEC64_SNAN
+#define DEC64_SNAN     (__builtin_nansd64 (""))
+#undef DEC128_SNAN
+#define DEC128_SNAN    (__builtin_nansd128 (""))
+
 #endif /* C2X */
 
 #endif /* __DEC32_MANT_DIG__ */
index d8a239c..aa790c8 100644 (file)
 #ifdef DEC_NAN
 # error "DEC_NAN defined"
 #endif
+
+#ifdef DEC32_SNAN
+# error "DEC32_SNAN defined"
+#endif
+
+#ifdef DEC64_SNAN
+# error "DEC64_SNAN defined"
+#endif
+
+#ifdef DEC128_SNAN
+# error "DEC128_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c
new file mode 100644 (file)
index 0000000..dec6b50
--- /dev/null
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros defined in <float.h> with DFP support.  */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC32_SNAN
+# error "DEC32_SNAN not defined"
+#endif
+
+#ifndef DEC64_SNAN
+# error "DEC64_SNAN not defined"
+#endif
+
+#ifndef DEC128_SNAN
+# error "DEC128_SNAN not defined"
+#endif
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+  (void) _Generic (DEC32_SNAN, _Decimal32 : 0);
+  if (!__builtin_isnan (DEC32_SNAN))
+    abort ();
+  if (!__builtin_isnan (d32))
+    abort ();
+  (void) _Generic (DEC64_SNAN, _Decimal64 : 0);
+  if (!__builtin_isnan (DEC64_SNAN))
+    abort ();
+  if (!__builtin_isnan (d64))
+    abort ();
+  (void) _Generic (DEC128_SNAN, _Decimal128 : 0);
+  if (!__builtin_isnan (DEC128_SNAN))
+    abort ();
+  if (!__builtin_isnan (d128))
+    abort ();
+  exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c
new file mode 100644 (file)
index 0000000..4169602
--- /dev/null
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros.  Test requiring runtime exceptions
+   support.  */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions_dfp } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+#include <float.h>
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+  feclearexcept (FE_ALL_EXCEPT);
+  d32 += d32;
+  if (!fetestexcept (FE_INVALID))
+    abort ();
+  feclearexcept (FE_ALL_EXCEPT);
+  d32 += d32;
+  if (fetestexcept (FE_INVALID))
+    abort ();
+  feclearexcept (FE_ALL_EXCEPT);
+  d64 += d64;
+  if (!fetestexcept (FE_INVALID))
+    abort ();
+  feclearexcept (FE_ALL_EXCEPT);
+  d64 += d64;
+  if (fetestexcept (FE_INVALID))
+    abort ();
+  feclearexcept (FE_ALL_EXCEPT);
+  d128 += d128;
+  if (!fetestexcept (FE_INVALID))
+    abort ();
+  feclearexcept (FE_ALL_EXCEPT);
+  d128 += d128;
+  if (fetestexcept (FE_INVALID))
+    abort ();
+  exit (0);
+}