float.h: C2x *_IS_IEC_60559 macros

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.
This commit is contained in:
Joseph Myers 2020-11-17 16:25:45 +00:00
parent 8895913273
commit ac30c8b8d0
4 changed files with 69 additions and 0 deletions

View 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. */

View 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 ())

View File

@ -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

View File

@ -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