This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: More support for non-standard IEEE float variants
- To: Richard Henderson <rth at redhat dot com>
- Subject: Re: More support for non-standard IEEE float variants
- From: Richard Sandiford <rsandifo at redhat dot com>
- Date: Fri, 23 Feb 2001 14:37:56 +0000 (GMT)
- Cc: <gcc-patches at gcc dot gnu dot org>
On Thu, 22 Feb 2001, Richard Henderson wrote:
> On Thu, Feb 22, 2001 at 06:11:41PM +0000, Richard Sandiford wrote:
> > I'm trying to use a 32-bit float format that is based on the IEEE one, but
> > which doesn't support NaNs or denormals. The NaN exponent can be used for
> > normal numbers instead.
>
> I don't like using just the NaN trigger for this. You need to know that
> there are no infinities either. I liked the LARGEST_EXPONENT_NORMAL patch
> that came across the internal list.
OK. The patch below reverts that change. In fp-bit.h,
LARGEST_EXPONENT_IS_NORMAL controls NORMAL_EXPMAX and implicitly sets
NO_NANS. NO_NANS_FOR_MODE() becomes LARGEST_EXPONENT_IS_NORMAL_FOR_MODE().
in real.c. (Sorry, I couldn't think of a shorter name!)
Still bootstraps on i686-cygwin.
Richard
2001-02-23 Richard Sandiford <rsandifo@redhat.com>
* config/fp-bit.h (NORMAL_EXPMAX): New macro.
* config/fp-bit.c: (pack_d): Disable denormal handling when
NO_DENORMALS is defined.
Use NORMAL_EXPMAX instead of EXPBIAS to check for overflow.
(unpack_d): Disable NaN handling when NO_NANS is defined.
* real.c (LARGEST_EXPONENT_IS_NORMAL_FOR_MODE): Document, and set
default to 0.
(e24toe): Make detection of NaN & infinity exponent dependent
on LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (SFmode).
(eto24e): Likewise. Issue a warning if infinities aren't allowed
and the number is too large.
* config/float-ieee-nonans.h: New file.
Index: ./gcc/config/fp-bit.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.h,v
retrieving revision 1.4
diff -c -p -d -r1.4 fp-bit.h
*** ./gcc/config/fp-bit.h 2001/02/02 11:02:05 1.4
--- ./gcc/config/fp-bit.h 2001/02/23 11:09:05
***************
*** 1,5 ****
/* Header file for fp-bit.c. */
! /* Copyright (C) 2000
Free Software Foundation, Inc.
This file is part of GNU CC.
--- 1,5 ----
/* Header file for fp-bit.c. */
! /* Copyright (C) 2000, 2001
Free Software Foundation, Inc.
This file is part of GNU CC.
*************** typedef unsigned int UDItype __attribute
*** 239,244 ****
--- 239,249 ----
#define NORMAL_EXPMIN (-(EXPBIAS)+1)
+ #ifdef LARGEST_EXPONENT_IS_NORMAL
+ #define NORMAL_EXPMAX ((EXPMAX)-(EXPBIAS))
+ #else
+ #define NORMAL_EXPMAX ((EXPMAX)-(EXPBIAS)-1)
+ #endif
#define IMPLICIT_1 (1LL<<(FRACBITS+NGARDS))
#define IMPLICIT_2 (1LL<<(FRACBITS+1+NGARDS))
*************** extern DFtype __make_dp (fp_class_type,
*** 413,417 ****
--- 418,426 ----
extern SFtype df_to_sf (DFtype);
#endif
#endif /* ! FLOAT */
+
+ #ifdef LARGEST_EXPONENT_IS_NORMAL
+ #define NO_NANS
+ #endif
#endif /* __FP_BIT_H__ */
Index: ./gcc/config/fp-bit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v
retrieving revision 1.25
diff -c -p -d -r1.25 fp-bit.c
*** ./gcc/config/fp-bit.c 2001/02/02 11:02:05 1.25
--- ./gcc/config/fp-bit.c 2001/02/23 11:09:06
*************** Boston, MA 02111-1307, USA. */
*** 63,68 ****
--- 63,70 ----
two integers to the FLO_union_type.
NO_DENORMALS: Disable handling of denormals.
NO_NANS: Disable nan and infinity handling
+ LARGEST_EXPONENT_IS_NORMAL: Like NO_NANS, but the largest exponent
+ value can be used for normal numbers instead.
SMALL_MACHINE: Useful when operations on QIs and HIs are faster
than on an SI */
*************** pack_d ( fp_number_type * src)
*** 209,214 ****
--- 211,223 ----
{
if (src->normal_exp < NORMAL_EXPMIN)
{
+ #ifdef NO_DENORMALS
+ /* Go straight to a zero representation if denormals are not
+ supported. The denormal handling would be harmless but
+ isn't unnecessary. */
+ exp = 0;
+ fraction = 0;
+ #else /* NO_DENORMALS */
/* This number's exponent is too low to fit into the bits
available in the number, so we'll store 0 in the exponent and
shift the fraction to the right to make up for it. */
*************** pack_d ( fp_number_type * src)
*** 244,252 ****
exp += 1;
}
fraction >>= NGARDS;
}
! else if (src->normal_exp > EXPBIAS)
{
exp = EXPMAX;
fraction = 0;
}
--- 253,266 ----
exp += 1;
}
fraction >>= NGARDS;
+ #endif /* NO_DENORMALS */
}
! else if (src->normal_exp > NORMAL_EXPMAX)
{
+ /* Approximate to infinity any number with an exponent larger than
+ NORMAL_EXPMAX. This is not selected out by NO_NANS because
+ there's no sensible alternative if infinities are not
+ supported. */
exp = EXPMAX;
fraction = 0;
}
*************** unpack_d (FLO_union_type * src, fp_numbe
*** 361,366 ****
--- 375,381 ----
dst->fraction.ll = fraction;
}
}
+ #ifndef NO_NANS
else if (exp == EXPMAX)
{
/* Huge exponent*/
*************** unpack_d (FLO_union_type * src, fp_numbe
*** 384,389 ****
--- 399,405 ----
dst->fraction.ll = fraction;
}
}
+ #endif /* ! NO_NANS */
else
{
/* Nothing strange about this number */
Index: ./gcc/real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.46
diff -c -p -d -r1.46 real.c
*** ./gcc/real.c 2001/01/24 04:30:46 1.46
--- ./gcc/real.c 2001/02/23 11:09:12
***************
*** 1,7 ****
/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
and support for XFmode IEEE extended real floating point arithmetic.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
! 1999, 2000 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
This file is part of GNU CC.
--- 1,7 ----
/* real.c - implementation of REAL_ARITHMETIC, REAL_VALUE_ATOF,
and support for XFmode IEEE extended real floating point arithmetic.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
! 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
This file is part of GNU CC.
*************** netlib.att.com: netlib/cephes. */
*** 69,74 ****
--- 69,86 ----
XFmode `long double' data structure used by the Intel 80x86 series
processors.
+ 'IEEE' behaviour can be modified by the macro
+ LARGEST_EXPONENT_IS_NORMAL_FOR_MODE. Some floating-point formats are
+ based on the IEEE standard but do not implement the NaN and infinity
+ functionality, allowing the largest exponent value to be used for normal
+ numbers instead. LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (MODE) should be
+ true if floats with mode MODE are in this category. Not defining the
+ macro is equivalent to returning 0 in every case.
+ ??? The macro is only used for SFmode floats at the moment. The DFmode
+ handler saturates to the largest value if INFINITY is not defined: should
+ it do the same if LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (DFmode) is true,
+ or should it report an overflow?
+
`DEC' refers specifically to the Digital Equipment Corp PDP-11
and VAX floating point data structure. This model currently
supports no type wider than DFmode.
*************** unknown arithmetic type
*** 182,187 ****
--- 194,203 ----
#define INFINITY
#endif
#endif
+
+ #ifndef LARGEST_EXPONENT_IS_NORMAL_FOR_MODE
+ #define LARGEST_EXPONENT_IS_NORMAL_FOR_MODE(MODE) 0
+ #endif
/* Find a host integer type that is at least 16 bits wide,
and another type at least twice whatever that size is. */
*************** e24toe (pe, y)
*** 3458,3464 ****
yy[M] = (r & 0x7f) | 0200;
r &= ~0x807f; /* strip sign and 7 significand bits */
#ifdef INFINITY
! if (r == 0x7f80)
{
#ifdef NANS
if (REAL_WORDS_BIG_ENDIAN)
--- 3474,3480 ----
yy[M] = (r & 0x7f) | 0200;
r &= ~0x807f; /* strip sign and 7 significand bits */
#ifdef INFINITY
! if (! LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (SFmode) && r == 0x7f80)
{
#ifdef NANS
if (REAL_WORDS_BIG_ENDIAN)
*************** toe24 (x, y)
*** 4054,4060 ****
#ifdef NANS
if (eiisnan (x))
{
! make_nan (y, eiisneg (x), SFmode);
return;
}
#endif
--- 4070,4079 ----
#ifdef NANS
if (eiisnan (x))
{
! if (LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (SFmode))
! warning ("32-bit floats cannot hold NaNs on this target");
! else
! make_nan (y, eiisneg (x), SFmode);
return;
}
#endif
*************** toe24 (x, y)
*** 4072,4078 ****
i = *p++;
/* Handle overflow cases. */
! if (i >= 255)
{
#ifdef INFINITY
*y |= (unsigned EMUSHORT) 0x7f80;
--- 4091,4102 ----
i = *p++;
/* Handle overflow cases. */
! if (LARGEST_EXPONENT_IS_NORMAL_FOR_MODE (SFmode))
! {
! if (i > 255)
! warning ("floating point overflow in expression");
! }
! else if (i >= 255)
{
#ifdef INFINITY
*y |= (unsigned EMUSHORT) 0x7f80;
*** /dev/null Fri Feb 23 11:10:48 2001
--- ./gcc/config/float-ieee-nonans.h Thu Feb 22 18:10:34 2001
***************
*** 0 ****
--- 1,69 ----
+ /* float.h for an IEEE-based format that doesn't use NaNs. FLT_MAX
+ is twice the IEEE value. */
+
+ #ifndef _FLOAT_H_
+ #define _FLOAT_H_
+
+ /* Radix of exponent representation */
+ #undef FLT_RADIX
+ #define FLT_RADIX 2
+ /* Number of base-FLT_RADIX digits in the significand of a float */
+ #undef FLT_MANT_DIG
+ #define FLT_MANT_DIG 24
+ /* Number of decimal digits of precision in a float */
+ #undef FLT_DIG
+ #define FLT_DIG 6
+ /* Addition rounds to 0: zero, 1: nearest, 2: +inf, 3: -inf, -1: unknown */
+ #undef FLT_ROUNDS
+ #define FLT_ROUNDS 1
+ /* Difference between 1.0 and the minimum float greater than 1.0 */
+ #undef FLT_EPSILON
+ #define FLT_EPSILON 0X1P-23f
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+ #undef FLT_MIN_EXP
+ #define FLT_MIN_EXP (-125)
+ /* Minimum normalised float */
+ #undef FLT_MIN
+ #define FLT_MIN 0X1.000002P-126f
+ /* Minimum int x such that 10**x is a normalised float */
+ #undef FLT_MIN_10_EXP
+ #define FLT_MIN_10_EXP (-37)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+ #undef FLT_MAX_EXP
+ #define FLT_MAX_EXP 129
+ /* Maximum float */
+ #undef FLT_MAX
+ #define FLT_MAX 0X1.FFFFFEP128f
+ /* Maximum int x such that 10**x is a representable float */
+ #undef FLT_MAX_10_EXP
+ #define FLT_MAX_10_EXP 38
+
+ /* Number of base-FLT_RADIX digits in the significand of a double */
+ #undef DBL_MANT_DIG
+ #define DBL_MANT_DIG 53
+ /* Number of decimal digits of precision in a double */
+ #undef DBL_DIG
+ #define DBL_DIG 15
+ /* Difference between 1.0 and the minimum double greater than 1.0 */
+ #undef DBL_EPSILON
+ #define DBL_EPSILON 2.2204460492503131e-16
+ /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+ #undef DBL_MIN_EXP
+ #define DBL_MIN_EXP (-1021)
+ /* Minimum normalised double */
+ #undef DBL_MIN
+ #define DBL_MIN 2.2250738585072014e-308
+ /* Minimum int x such that 10**x is a normalised double */
+ #undef DBL_MIN_10_EXP
+ #define DBL_MIN_10_EXP (-307)
+ /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+ #undef DBL_MAX_EXP
+ #define DBL_MAX_EXP 1024
+ /* Maximum double */
+ #undef DBL_MAX
+ #define DBL_MAX 1.7976931348623157e+308
+ /* Maximum int x such that 10**x is a representable double */
+ #undef DBL_MAX_10_EXP
+ #define DBL_MAX_10_EXP 308
+
+ #endif /* _FLOAT_H___ */