float.h: C2x *_IS_IEC_60559 macros
authorJoseph Myers <joseph@codesourcery.com>
Tue, 17 Nov 2020 16:25:45 +0000 (16:25 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 17 Nov 2020 16:28:11 +0000 (16:28 +0000)
C2x adds float.h macros that say whether float, double and long double
match an IEC 60559 (IEEE 754) format and operations.  Add these
macros to GCC's float.h.

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

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

* c-cppbuiltin.c (builtin_define_float_constants): Define
"*_IS_IEC_60559__" macros.

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

* ginclude/float.h [__STDC_VERSION__ > 201710L] (FLT_IS_IEC_60559,
DBL_IS_IEC_60559, LDBL_IS_IEC_60559): New macros.

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

* gcc.dg/c11-float-6.c, gcc.dg/c2x-float-10.c: New tests.

gcc/c-family/c-cppbuiltin.c
gcc/ginclude/float.h
gcc/testsuite/gcc.dg/c11-float-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-float-10.c [new file with mode: 0644]

index 8856a97021804df222a70f0a3c41eedb1faf6981..d35b087bdcc4639c66c351a45b4307fb92d84955 100644 (file)
@@ -317,6 +317,16 @@ builtin_define_float_constants (const char *name_prefix,
       sprintf (name, "__FP_FAST_FMA%s", fma_suffix);
       builtin_define_with_int_value (name, 1);
     }
+
+  /* For C2x *_IS_IEC_60559.  0 means the type does not match an IEC
+     60559 format, 1 that it matches a format but not operations and 2
+     that it matches a format and operations (but may not conform to
+     Annex F; we take this as meaning exceptions and rounding modes
+     need not be supported).  */
+  sprintf (name, "__%s_IS_IEC_60559__", name_prefix);
+  builtin_define_with_int_value (name,
+                                (fmt->ieee_bits == 0
+                                 ? 0 : (fmt->round_towards_zero ? 1 : 2)));
 }
 
 /* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
index 0fa00461230af71ad807ca6d715c16580c5fa86c..83c5ad55a530cae0699cb3d4fae17004c0739553 100644 (file)
@@ -248,6 +248,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define DBL_NORM_MAX   __DBL_NORM_MAX__
 #define LDBL_NORM_MAX  __LDBL_NORM_MAX__
 
+/* Whether each type matches an IEC 60559 format (1 for format, 2 for
+   format and operations).  */
+#undef FLT_IS_IEC_60559
+#undef DBL_IS_IEC_60559
+#undef LDBL_IS_IEC_60559
+#define FLT_IS_IEC_60559       __FLT_IS_IEC_60559__
+#define DBL_IS_IEC_60559       __DBL_IS_IEC_60559__
+#define LDBL_IS_IEC_60559      __LDBL_IS_IEC_60559__
+
 /* Infinity in type float, or overflow if infinity not supported.  */
 #undef INFINITY
 #define INFINITY       (__builtin_inff ())
diff --git a/gcc/testsuite/gcc.dg/c11-float-6.c b/gcc/testsuite/gcc.dg/c11-float-6.c
new file mode 100644 (file)
index 0000000..b0381e5
--- /dev/null
@@ -0,0 +1,17 @@
+/* Test *_IS_IEC_60559 not defined for C11.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 defined"
+#endif
+
+#ifdef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 defined"
+#endif
+
+#ifdef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-10.c b/gcc/testsuite/gcc.dg/c2x-float-10.c
new file mode 100644 (file)
index 0000000..7b53a6a
--- /dev/null
@@ -0,0 +1,33 @@
+/* Test *_IS_IEC_60559 macros.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 undefined"
+#endif
+
+#ifndef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 undefined"
+#endif
+
+#ifndef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 undefined"
+#endif
+
+#if defined __pdp11__ || defined __vax__
+_Static_assert (FLT_IS_IEC_60559 == 0);
+_Static_assert (DBL_IS_IEC_60559 == 0);
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (FLT_IS_IEC_60559 == 2);
+_Static_assert (DBL_IS_IEC_60559 == 2);
+#if LDBL_MANT_DIG == 106 || LDBL_MIN_EXP == -16382
+/* IBM long double and m68k extended format do not meet the definition
+   of an IEC 60559 interchange or extended format.  */
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (LDBL_IS_IEC_60559 == 2);
+#endif
+#endif