From: Joseph Myers Date: Tue, 17 Nov 2020 16:25:45 +0000 (+0000) Subject: float.h: C2x *_IS_IEC_60559 macros X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ac30c8b8d035cd9259040150f059f1cf3542f626;p=gcc.git 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 * c-cppbuiltin.c (builtin_define_float_constants): Define "*_IS_IEC_60559__" macros. gcc/ 2020-11-17 Joseph Myers * 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 * gcc.dg/c11-float-6.c, gcc.dg/c2x-float-10.c: New tests. --- diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 8856a970218..d35b087bdcc 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -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. */ diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h index 0fa00461230..83c5ad55a53 100644 --- a/gcc/ginclude/float.h +++ b/gcc/ginclude/float.h @@ -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 index 00000000000..b0381e57884 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-float-6.c @@ -0,0 +1,17 @@ +/* Test *_IS_IEC_60559 not defined for C11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include + +#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 index 00000000000..7b53a6ab050 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2x-float-10.c @@ -0,0 +1,33 @@ +/* Test *_IS_IEC_60559 macros. */ +/* { dg-do compile } */ +/* { dg-options "-std=c2x -pedantic-errors" } */ + +#include + +#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