aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/builtins.c6
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-cppbuiltin.c11
-rw-r--r--gcc/d/ChangeLog5
-rw-r--r--gcc/d/d-target.cc2
-rw-r--r--gcc/ginclude/float.h12
-rw-r--r--gcc/real.c15
-rw-r--r--gcc/real.h2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-3.c17
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-1.c37
12 files changed, 115 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fdc7805..5a52fd6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2019-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * ginclude/float.c [__STDC_VERSION__ > 201710L] (FLT_NORM_MAX,
+ DBL_NORM_MAX, LDBL_NORM_MAX): Define.
+ * real.c (get_max_float): Add norm_max argument.
+ * real.h (get_max_float): Update prototype.
+ * builtins.c (fold_builtin_interclass_mathfn): Update calls to
+ get_max_float.
+
2019-11-13 Martin Liska <mliska@suse.cz>
* dbgcnt.c (test_sorted_dbg_counters): New.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 450cc7a..f94151b 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -9038,7 +9038,7 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
mode = DFmode;
arg = fold_build1_loc (loc, NOP_EXPR, type, arg);
}
- get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
+ get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false);
real_from_string (&r, buf);
result = build_call_expr (isgr_fn, 2,
fold_build1_loc (loc, ABS_EXPR, type, arg),
@@ -9062,7 +9062,7 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
mode = DFmode;
arg = fold_build1_loc (loc, NOP_EXPR, type, arg);
}
- get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
+ get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false);
real_from_string (&r, buf);
result = build_call_expr (isle_fn, 2,
fold_build1_loc (loc, ABS_EXPR, type, arg),
@@ -9101,7 +9101,7 @@ fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
}
arg = fold_build1_loc (loc, ABS_EXPR, type, arg);
- get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
+ get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf), false);
real_from_string (&rmax, buf);
sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (orig_mode)->emin - 1);
real_from_string (&rmin, buf);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c7813a1..e96ed63 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,10 @@
+2019-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * c-cppbuiltin.c (builtin_define_float_constants): Also define
+ NORM_MAX constants. Update call to get_max_float.
+ (LAZY_HEX_FP_VALUES_CNT): Update value to include NORM_MAX
+ constants.
+
2019-11-13 Eric Botcazou <ebotcazou@adacore.com>
* c-ada-spec.c (get_underlying_decl): Do not look through typedefs.
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index cf3d437..76d1e4a 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -259,11 +259,16 @@ builtin_define_float_constants (const char *name_prefix,
/* Since, for the supported formats, B is always a power of 2, we
construct the following numbers directly as a hexadecimal
constants. */
- get_max_float (fmt, buf, sizeof (buf));
+ get_max_float (fmt, buf, sizeof (buf), false);
sprintf (name, "__%s_MAX__", name_prefix);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
+ get_max_float (fmt, buf, sizeof (buf), true);
+
+ sprintf (name, "__%s_NORM_MAX__", name_prefix);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix, fp_cast);
+
/* The minimum normalized positive floating-point number,
b**(emin-1). */
sprintf (name, "__%s_MIN__", name_prefix);
@@ -1607,10 +1612,10 @@ struct GTY(()) lazy_hex_fp_value_struct
};
/* Number of the expensive to compute macros we should evaluate lazily.
Each builtin_define_float_constants invocation calls
- builtin_define_with_hex_fp_value 4 times and builtin_define_float_constants
+ builtin_define_with_hex_fp_value 5 times and builtin_define_float_constants
is called for FLT, DBL, LDBL and up to NUM_FLOATN_NX_TYPES times for
FLTNN*. */
-#define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES))
+#define LAZY_HEX_FP_VALUES_CNT (5 * (3 + NUM_FLOATN_NX_TYPES))
static GTY(()) struct lazy_hex_fp_value_struct
lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT];
static GTY(()) unsigned lazy_hex_fp_value_count;
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 2591b4c..012d495 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * d-target.cc (define_float_constants): Update call to
+ get_max_float.
+
2019-11-04 Richard Sandiford <richard.sandiford@arm.com>
* d-builtins.cc (build_frontend_type): Cope with variable
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index dfaf9bf..37a07b1 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -82,7 +82,7 @@ define_float_constants (tree type)
const real_format *fmt = REAL_MODE_FORMAT (mode);
/* The largest representable value that's not infinity. */
- get_max_float (fmt, buf, sizeof (buf));
+ get_max_float (fmt, buf, sizeof (buf), false);
real_from_string (&T::max.rv (), buf);
/* The smallest representable normalized value that's not 0. */
diff --git a/gcc/ginclude/float.h b/gcc/ginclude/float.h
index dc91c75..cafedc1 100644
--- a/gcc/ginclude/float.h
+++ b/gcc/ginclude/float.h
@@ -238,6 +238,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif /* C11 */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L
+/* Maximum finite positive value with MANT_DIG digits in the
+ significand taking their maximum value. */
+#undef FLT_NORM_MAX
+#undef DBL_NORM_MAX
+#undef LDBL_NORM_MAX
+#define FLT_NORM_MAX __FLT_NORM_MAX__
+#define DBL_NORM_MAX __DBL_NORM_MAX__
+#define LDBL_NORM_MAX __LDBL_NORM_MAX__
+
+#endif /* C2X */
+
#ifdef __STDC_WANT_IEC_60559_BFP_EXT__
/* Number of decimal digits for which conversions between decimal
character strings and binary formats, in both directions, are
diff --git a/gcc/real.c b/gcc/real.c
index 6e6a394..90067f0 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -5242,13 +5242,19 @@ real_nextafter (REAL_VALUE_TYPE *r, format_helper fmt,
/* Write into BUF the maximum representable finite floating-point
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
float string. LEN is the size of BUF, and the buffer must be large
- enough to contain the resulting string. */
+ enough to contain the resulting string. If NORM_MAX, instead write
+ the maximum representable finite normalized floating-point number,
+ defined to be such that all choices of digits for that exponent are
+ representable in the format (this only makes a difference for IBM
+ long double). */
void
-get_max_float (const struct real_format *fmt, char *buf, size_t len)
+get_max_float (const struct real_format *fmt, char *buf, size_t len,
+ bool norm_max)
{
int i, n;
char *p;
+ bool is_ibm_extended = fmt->pnan < fmt->p;
strcpy (buf, "0x0.");
n = fmt->p;
@@ -5256,8 +5262,9 @@ get_max_float (const struct real_format *fmt, char *buf, size_t len)
*p++ = 'f';
if (i < n)
*p++ = "08ce"[n - i];
- sprintf (p, "p%d", fmt->emax);
- if (fmt->pnan < fmt->p)
+ sprintf (p, "p%d",
+ (is_ibm_extended && norm_max) ? fmt->emax - 1 : fmt->emax);
+ if (is_ibm_extended && !norm_max)
{
/* This is an IBM extended double format made up of two IEEE
doubles. The value of the long double is the sum of the
diff --git a/gcc/real.h b/gcc/real.h
index 2f41834..0f660c9 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -524,7 +524,7 @@ extern bool real_nextafter (REAL_VALUE_TYPE *, format_helper,
/* Write into BUF the maximum representable finite floating-point
number, (1 - b**-p) * b**emax for a given FP format FMT as a hex
float string. BUF must be large enough to contain the result. */
-extern void get_max_float (const struct real_format *, char *, size_t);
+extern void get_max_float (const struct real_format *, char *, size_t, bool);
#ifndef GENERATOR_FILE
/* real related routines. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 23ad51b..9e062e7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-11-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/c11-float-3.c, gcc.dg/c2x-float-1.c: New tests.
+
2019-11-13 Martin Jambor <mjambor@suse.cz>
PR ipa/92454
diff --git a/gcc/testsuite/gcc.dg/c11-float-3.c b/gcc/testsuite/gcc.dg/c11-float-3.c
new file mode 100644
index 0000000..95d2074
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-3.c
@@ -0,0 +1,17 @@
+/* Test *_NORM_MAX not defined for C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef FLT_NORM_MAX
+#error "FLT_NORM_MAX defined"
+#endif
+
+#ifdef DBL_NORM_MAX
+#error "DBL_NORM_MAX defined"
+#endif
+
+#ifdef LDBL_NORM_MAX
+#error "LDBL_NORM_MAX defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-1.c b/gcc/testsuite/gcc.dg/c2x-float-1.c
new file mode 100644
index 0000000..8df85f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-1.c
@@ -0,0 +1,37 @@
+/* Test *_NORM_MAX macros. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef FLT_NORM_MAX
+#error "FLT_NORM_MAX undefined"
+#endif
+
+#ifndef DBL_NORM_MAX
+#error "DBL_NORM_MAX undefined"
+#endif
+
+#ifndef LDBL_NORM_MAX
+#error "LDBL_NORM_MAX undefined"
+#endif
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ if (FLT_NORM_MAX != FLT_MAX)
+ abort ();
+ if (DBL_NORM_MAX != DBL_MAX)
+ abort ();
+#if LDBL_MANT_DIG == 106
+ if (LDBL_NORM_MAX != 0x0.ffffffffffffffffffffffffffcp1023L)
+ abort ();
+#else
+ if (LDBL_NORM_MAX != LDBL_MAX)
+ abort ();
+#endif
+ exit (0);
+}