aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-09-21 09:27:40 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-09-21 09:27:40 -0700
commit3fdacdf9e310dc1ff0f7773b3d3383dbbcdd3f05 (patch)
tree4618876e1da3518fd1f181a85167f59d5312e039 /gcc
parentaa2046c41feedde364b54351b44ac6b9fb16017e (diff)
downloadgcc-3fdacdf9e310dc1ff0f7773b3d3383dbbcdd3f05.zip
gcc-3fdacdf9e310dc1ff0f7773b3d3383dbbcdd3f05.tar.gz
gcc-3fdacdf9e310dc1ff0f7773b3d3383dbbcdd3f05.tar.bz2
c-common.c (builtin_define_float_constants): Use real_format to get the floating-point parameters.
* c-common.c (builtin_define_float_constants): Use real_format to get the floating-point parameters. From-SVN: r57390
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-common.c192
2 files changed, 44 insertions, 153 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62058c3..6e6487a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2002-09-21 Richard Henderson <rth@redhat.com>
+ * c-common.c (builtin_define_float_constants): Use real_format
+ to get the floating-point parameters.
+
+2002-09-21 Richard Henderson <rth@redhat.com>
+
* real.c (struct real_format): Move to real.h.
(real_format_for_mode): Rename from fmt_for_mode; update all users;
initialize with ieee defaults.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 0da5ce8..8104248 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4802,141 +4802,23 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
mean time, I suspect using doubles won't harm the bootstrap here. */
const double log10_2 = .30102999566398119521;
- const double log10_16 = 1.20411998265592478085;
- const double log10_b
- = TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT ? log10_16 : log10_2;
-
- const int log2_b = TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT ? 4 : 1;
+ double log10_b;
+ const struct real_format *fmt;
char name[64], buf[128];
- int mant_dig, max_exp, min_exp;
int dig, min_10_exp, max_10_exp;
int decimal_dig;
- /* ??? This information should be shared with real.c. */
+ fmt = real_format_for_mode[TYPE_MODE (type) - QFmode];
-#ifndef INTEL_EXTENDED_IEEE_FORMAT
-#define INTEL_EXTENDED_IEEE_FORMAT 0
-#endif
-#ifndef TARGET_G_FLOAT
-#define TARGET_G_FLOAT 0
-#endif
-
- switch (TARGET_FLOAT_FORMAT)
- {
- case IEEE_FLOAT_FORMAT:
- switch (TYPE_PRECISION (type))
- {
- case 32:
- /* ??? Handle MIPS r5900, which doesn't implement Inf or NaN,
- but rather reuses the largest exponent as a normal number. */
- mant_dig = 24;
- min_exp = -125;
- max_exp = 128;
- break;
- case 64:
- mant_dig = 53;
- min_exp = -1021;
- max_exp = 1024;
- break;
- case 128:
- if (!INTEL_EXTENDED_IEEE_FORMAT)
- {
- mant_dig = 113;
- min_exp = -16381;
- max_exp = 16384;
- break;
- }
- /* FALLTHRU */
- case 96:
- mant_dig = 64;
- max_exp = 16384;
- if (INTEL_EXTENDED_IEEE_FORMAT)
- min_exp = -16381;
- else
- /* ??? Otherwise assume m68k. */
- min_exp = -16382;
- break;
- default:
- abort ();
- }
- break;
-
- case VAX_FLOAT_FORMAT:
- switch (TYPE_PRECISION (type))
- {
- case 32: /* F_FLOAT */
- mant_dig = 24;
- min_exp = -127;
- max_exp = 127;
- break;
- case 64: /* G_FLOAT or D_FLOAT */
- if (TARGET_G_FLOAT)
- {
- mant_dig = 53;
- min_exp = -1023;
- max_exp = 1023;
- }
- else
- {
- mant_dig = 56;
- min_exp = -127;
- max_exp = 127;
- }
- break;
- case 128: /* H_FLOAT */
- mant_dig = 113;
- min_exp = -16383;
- max_exp = 16383;
- break;
- default:
- abort ();
- }
- break;
-
- case IBM_FLOAT_FORMAT:
- switch (TYPE_PRECISION (type))
- {
- case 32:
- mant_dig = 6;
- min_exp = -64;
- max_exp = 63;
- break;
- case 64:
- mant_dig = 14;
- min_exp = -64;
- max_exp = 63;
- break;
- default:
- abort ();
- }
- break;
-
- case C4X_FLOAT_FORMAT:
- switch (TYPE_PRECISION (type))
- {
- case 32:
- mant_dig = 24;
- min_exp = -126;
- max_exp = 128;
- break;
- case 64:
- mant_dig = 32;
- min_exp = -126;
- max_exp = 128;
- break;
- default:
- abort ();
- }
- break;
-
- default:
- abort ();
- }
+ /* The radix of the exponent representation. */
+ if (type == float_type_node)
+ builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
+ log10_b = log10_2 * fmt->log2_b;
/* The number of radix digits, p, in the floating-point significand. */
sprintf (name, "__%s_MANT_DIG__", name_prefix);
- builtin_define_with_int_value (name, mant_dig);
+ builtin_define_with_int_value (name, fmt->p);
/* The number of decimal digits, q, such that any floating-point number
with q decimal digits can be rounded into a floating-point number with
@@ -4945,37 +4827,37 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
p log10 b if b is a power of 10
floor((p - 1) log10 b) otherwise
*/
- dig = (mant_dig - 1) * log10_b;
+ dig = (fmt->p - 1) * log10_b;
sprintf (name, "__%s_DIG__", name_prefix);
builtin_define_with_int_value (name, dig);
/* The minimum negative int x such that b**(x-1) is a normalized float. */
sprintf (name, "__%s_MIN_EXP__", name_prefix);
- sprintf (buf, "(%d)", min_exp);
+ sprintf (buf, "(%d)", fmt->emin);
builtin_define_with_value (name, buf, 0);
/* The minimum negative int x such that 10**x is a normalized float,
- ceil (log10 (b ** (min_exp - 1)))
- = ceil (log10 (b) * (min_exp - 1))
+ ceil (log10 (b ** (emin - 1)))
+ = ceil (log10 (b) * (emin - 1))
- Recall that min_exp is negative, so the integer truncation calculates
+ Recall that emin is negative, so the integer truncation calculates
the ceiling, not the floor, in this case. */
- min_10_exp = (min_exp - 1) * log10_b;
+ min_10_exp = (fmt->emin - 1) * log10_b;
sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
sprintf (buf, "(%d)", min_10_exp);
builtin_define_with_value (name, buf, 0);
/* The maximum int x such that b**(x-1) is a representable float. */
sprintf (name, "__%s_MAX_EXP__", name_prefix);
- builtin_define_with_int_value (name, max_exp);
+ builtin_define_with_int_value (name, fmt->emax);
/* The maximum int x such that 10**x is in the range of representable
finite floating-point numbers,
- floor (log10((1 - b**-p) * b**max_exp))
- = floor (log10(1 - b**-p) + log10(b**max_exp))
- = floor (log10(1 - b**-p) + log10(b)*max_exp)
+ floor (log10((1 - b**-p) * b**emax))
+ = floor (log10(1 - b**-p) + log10(b**emax))
+ = floor (log10(1 - b**-p) + log10(b)*emax)
The safest thing to do here is to just compute this number. But since
we don't link cc1 with libm, we cannot. We could implement log10 here
@@ -4996,7 +4878,7 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
Hand-waving aside, crunching all of the sets of constants above by hand
does not yield a case for which the first term is significant, which
in the end is all that matters. */
- max_10_exp = max_exp * log10_b;
+ max_10_exp = fmt->emax * log10_b;
sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
builtin_define_with_int_value (name, max_10_exp);
@@ -5010,7 +4892,7 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
The only macro we care about is this number for the widest supported
floating type, but we want this value for rendering constants below. */
{
- double d_decimal_dig = 1 + mant_dig * log10_b;
+ double d_decimal_dig = 1 + fmt->p * log10_b;
decimal_dig = d_decimal_dig;
if (decimal_dig < d_decimal_dig)
decimal_dig++;
@@ -5023,40 +4905,49 @@ builtin_define_float_constants (name_prefix, fp_suffix, type)
constants. */
/* The maximum representable finite floating-point number,
- (1 - b**-p) * b**max_exp */
+ (1 - b**-p) * b**emax */
{
int i, n;
char *p;
strcpy (buf, "0x0.");
- n = mant_dig * log2_b;
+ n = fmt->p * fmt->log2_b;
for (i = 0, p = buf + 4; i + 3 < n; i += 4)
*p++ = 'f';
if (i < n)
*p++ = "08ce"[n - i];
- sprintf (p, "p%d", max_exp * log2_b);
+ sprintf (p, "p%d", fmt->emax * fmt->log2_b);
}
sprintf (name, "__%s_MAX__", name_prefix);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* The minimum normalized positive floating-point number,
- b**(min_exp-1). */
+ b**(emin-1). */
sprintf (name, "__%s_MIN__", name_prefix);
- sprintf (buf, "0x1p%d", (min_exp - 1) * log2_b);
+ sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* The difference between 1 and the least value greater than 1 that is
representable in the given floating point type, b**(1-p). */
sprintf (name, "__%s_EPSILON__", name_prefix);
- sprintf (buf, "0x1p%d", (1 - mant_dig) * log2_b);
+ sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
- positive floating-point number, b**(min_exp-p). Winds up being zero
- for targets that don't support denormals. */
+ positive floating-point number, b**(emin-p). Zero for formats that
+ don't support denormals. */
sprintf (name, "__%s_DENORM_MIN__", name_prefix);
- sprintf (buf, "0x1p%d", (min_exp - mant_dig) * log2_b);
- builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+ if (fmt->has_denorm)
+ {
+ sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig,
+ buf, fp_suffix);
+ }
+ else
+ {
+ sprintf (buf, "0.0%s", fp_suffix);
+ builtin_define_with_value (name, buf, 0);
+ }
}
/* Hook that registers front end and target-specific built-ins. */
@@ -5114,11 +5005,6 @@ cb_register_builtins (pfile)
/* float.h needs to know these. */
- /* The radix of the exponent representation. */
- builtin_define_with_int_value ("__FLT_RADIX__",
- (TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
- ? 16 : 2));
-
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
TARGET_FLT_EVAL_METHOD);