This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: More support for non-standard IEEE float variants




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___ */




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]