+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.
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),
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),
}
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);
+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.
/* 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);
};
/* 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;
+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
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. */
#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
/* 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;
*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
/* 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. */
+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
--- /dev/null
+/* 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
--- /dev/null
+/* 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);
+}