Patch to add more floating point target macros

Richard Sandiford rsandifo@redhat.com
Fri Mar 8 08:21:00 GMT 2002


This patch adds two macros to control the floating point format:

    ROUND_TOWARDS_ZERO
    LARGEST_EXPONENT_IS_NORMAL

In principle. ROUND_TOWARDS_ZERO can be used with any floating point
format.  It applies to all sizes of floats, because real.c does
arithmetic rounding on the internal format, rather than to a
specific precision.  It forces rounding towards zero rather
than towards nearest.

LARGEST_EXPONENT_IS_NORMAL applies to floats that have an IEEE layout,
but use the largest exponent for normal numbers rather then NaNs and
infinities.  It takes the size of the float as argument, and can
have different values for different precisions.

A bootstrap on i686-pc-linux-gnu failed in libjava because of the
"Missing REG_EH_REGION note" thing, but the compiler itself
boostrapped fine.  Tested for regressions on arm-elf and
i686-pc-linux-gnu.  OK to install?

Richard


	* defaults.h (LARGEST_EXPONENT_IS_NORMAL, ROUND_TOWARDS_ZERO): New.
	(MODE_HAS_NANS, MODE_HAS_INFINITIES): Evaluate to false if
	LARGEST_EXPONENT_IS_NORMAL for the given mode.
	(MODE_HAS_SIGN_DEPENDENT_ROUNDING): False when ROUND_TOWARDS_ZERO.
	* real.c (eadd1: Make rounding dependent on !ROUND_TOWARDS_ZERO.
	(ediv, emul, eldexp, esqrt): Likewise.
	(etoe113, etoe64, etoe53, etoe24, etodec, etoibm, etoc4x): Likewise.
	(e24toe): Only check NaNs & infinities if !LARGEST_EXPONENT_IS_NORMAL.
	(saturate): New function.
	(toe53, toe24): Saturate on overflow if LARGEST_EXPONENT_IS_NORMAL.
	(make_nan): Use a saturation value instead of a NaN if
	LARGEST_EXPONENT_IS_NORMAL.  Warn when this happens.
	* fp-bit.c (pack_d): Saturate on NaN, infinite or overflowing
	inputs if LARGEST_EXPONENT_IS_NORMAL.  Represent subnormals as
	zero if NO_DENORMALS.  Only round to nearest if !ROUND_TOWARDS_ZERO.
	(unpack_d): No NaNs or infinities if LARGEST_EXPONENT_IS_NORMAL.
	(_fpmul_parts, _fpdiv_parts): Only round to nearest if
	!ROUND_TOWARDS_ZERO.
	* doc/tm.texi (LARGEST_EXPONENT_IS_NORMAL): Document.
	(ROUND_TOWARDS_ZERO): Document.

Index: defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.68
diff -c -p -d -r1.68 defaults.h
*** defaults.h	2002/03/07 11:36:59	1.68
--- defaults.h	2002/03/08 16:10:35
*************** You Lose!  You must define PREFERRED_DEB
*** 465,478 ****
  #define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
  #endif
  
  #ifndef MODE_HAS_NANS
! #define MODE_HAS_NANS(MODE) \
!   (FLOAT_MODE_P (MODE) && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
  #endif
  
  #ifndef MODE_HAS_INFINITIES
! #define MODE_HAS_INFINITIES(MODE) \
!   (FLOAT_MODE_P (MODE) && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
  #endif
  
  #ifndef MODE_HAS_SIGNED_ZEROS
--- 465,490 ----
  #define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
  #endif
  
+ #ifndef LARGEST_EXPONENT_IS_NORMAL
+ #define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0
+ #endif
+ 
+ #ifndef ROUND_TOWARDS_ZERO
+ #define ROUND_TOWARDS_ZERO 0
+ #endif
+ 
  #ifndef MODE_HAS_NANS
! #define MODE_HAS_NANS(MODE)					\
!   (FLOAT_MODE_P (MODE)						\
!    && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT			\
!    && !LARGEST_EXPONENT_IS_NORMAL (GET_MODE_BITSIZE (MODE)))
  #endif
  
  #ifndef MODE_HAS_INFINITIES
! #define MODE_HAS_INFINITIES(MODE)				\
!   (FLOAT_MODE_P (MODE)						\
!    && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT			\
!    && !LARGEST_EXPONENT_IS_NORMAL (GET_MODE_BITSIZE (MODE)))
  #endif
  
  #ifndef MODE_HAS_SIGNED_ZEROS
*************** You Lose!  You must define PREFERRED_DEB
*** 481,488 ****
  #endif
  
  #ifndef MODE_HAS_SIGN_DEPENDENT_ROUNDING
! #define MODE_HAS_SIGN_DEPENDENT_ROUNDING(MODE) \
!   (FLOAT_MODE_P (MODE) && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
  #endif
  
  #endif  /* ! GCC_DEFAULTS_H */
--- 493,502 ----
  #endif
  
  #ifndef MODE_HAS_SIGN_DEPENDENT_ROUNDING
! #define MODE_HAS_SIGN_DEPENDENT_ROUNDING(MODE)			\
!   (FLOAT_MODE_P (MODE)						\
!    && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT			\
!    && !ROUND_TOWARDS_ZERO)
  #endif
  
  #endif  /* ! GCC_DEFAULTS_H */
Index: real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.62
diff -c -p -d -r1.62 real.c
*** real.c	2002/03/03 21:09:46	1.62
--- real.c	2002/03/08 16:10:36
*************** static int eiisnan	PARAMS ((const UEMUSH
*** 336,341 ****
--- 336,342 ----
  static int eiisneg	PARAMS ((const UEMUSHORT *));
  static void make_nan	PARAMS ((UEMUSHORT *, int, enum machine_mode));
  #endif
+ static void saturate	PARAMS ((UEMUSHORT *, int, int, int));
  static void emovi	PARAMS ((const UEMUSHORT *, UEMUSHORT *));
  static void emovo	PARAMS ((const UEMUSHORT *, UEMUSHORT *));
  static void ecleaz	PARAMS ((UEMUSHORT *));
*************** eadd1 (a, b, c)
*** 2871,2877 ****
        esubm (ai, bi);
        subflg = 1;
      }
!   emdnorm (bi, lost, subflg, ltb, 64);
  
   done:
    emovo (bi, c);
--- 2872,2878 ----
        esubm (ai, bi);
        subflg = 1;
      }
!   emdnorm (bi, lost, subflg, ltb, !ROUND_TOWARDS_ZERO);
  
   done:
    emovo (bi, c);
*************** ediv (a, b, c)
*** 2967,2973 ****
    i = edivm (ai, bi);
    /* calculate exponent */
    lt = ltb - lta + EXONE;
!   emdnorm (bi, i, 0, lt, 64);
    emovo (bi, c);
  
   divsign:
--- 2968,2974 ----
    i = edivm (ai, bi);
    /* calculate exponent */
    lt = ltb - lta + EXONE;
!   emdnorm (bi, i, 0, lt, !ROUND_TOWARDS_ZERO);
    emovo (bi, c);
  
   divsign:
*************** emul (a, b, c)
*** 3064,3070 ****
    j = emulm (ai, bi);
    /* calculate exponent */
    lt = lta + ltb - (EXONE - 1);
!   emdnorm (bi, j, 0, lt, 64);
    emovo (bi, c);
  
   mulsign:
--- 3065,3071 ----
    j = emulm (ai, bi);
    /* calculate exponent */
    lt = lta + ltb - (EXONE - 1);
!   emdnorm (bi, j, 0, lt, !ROUND_TOWARDS_ZERO);
    emovo (bi, c);
  
   mulsign:
*************** e24toe (pe, y)
*** 3445,3451 ****
    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)
--- 3446,3452 ----
    yy[M] = (r & 0x7f) | 0200;
    r &= ~0x807f;			/* strip sign and 7 significand bits */
  #ifdef INFINITY
!   if (!LARGEST_EXPONENT_IS_NORMAL (32) && r == 0x7f80)
      {
  #ifdef NANS
        if (REAL_WORDS_BIG_ENDIAN)
*************** etoe113 (x, e)
*** 3536,3542 ****
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 113;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
--- 3537,3543 ----
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 113;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
*************** etoe64 (x, e)
*** 3632,3638 ****
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 64;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
--- 3633,3639 ----
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 64;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
*************** etoe53 (x, e)
*** 3852,3858 ****
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 53;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
--- 3853,3859 ----
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 53;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
*************** toe53 (x, y)
*** 3877,3882 ****
--- 3878,3888 ----
        return;
      }
  #endif
+   if (LARGEST_EXPONENT_IS_NORMAL (64) && x[1] > 2047)
+     {
+       saturate (y, eiisneg (x), 64, 1);
+       return;
+     }
    p = &x[0];
  #ifdef IEEE
    if (! REAL_WORDS_BIG_ENDIAN)
*************** etoe24 (x, e)
*** 4031,4037 ****
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 24;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
--- 4037,4043 ----
    /* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 24;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
  #ifdef INFINITY
   nonorm:
*************** toe24 (x, y)
*** 4056,4061 ****
--- 4062,4072 ----
        return;
      }
  #endif
+   if (LARGEST_EXPONENT_IS_NORMAL (32) && x[1] > 255)
+     {
+       saturate (y, eiisneg (x), 32, 1);
+       return;
+     }
    p = &x[0];
  #ifdef IEEE
    if (! REAL_WORDS_BIG_ENDIAN)
*************** toe24 (x, y)
*** 4070,4076 ****
  
    i = *p++;
  /* Handle overflow cases.  */
!   if (i >= 255)
      {
  #ifdef INFINITY
        *y |= (UEMUSHORT) 0x7f80;
--- 4081,4087 ----
  
    i = *p++;
  /* Handle overflow cases.  */
!   if (!LARGEST_EXPONENT_IS_NORMAL (32) && i >= 255)
      {
  #ifdef INFINITY
        *y |= (UEMUSHORT) 0x7f80;
*************** eldexp (x, pwr2, y)
*** 5628,5634 ****
    li = xi[1];
    li += pwr2;
    i = 0;
!   emdnorm (xi, i, i, li, 64);
    emovo (xi, y);
  }
  
--- 5639,5645 ----
    li = xi[1];
    li += pwr2;
    i = 0;
!   emdnorm (xi, i, i, li, !ROUND_TOWARDS_ZERO);
    emovo (xi, y);
  }
  
*************** etodec (x, d)
*** 5826,5832 ****
    /* Round off to nearest or even.  */
    rndsav = rndprc;
    rndprc = 56;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
    todec (xi, d);
  }
--- 5837,5843 ----
    /* Round off to nearest or even.  */
    rndsav = rndprc;
    rndprc = 56;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
    todec (xi, d);
  }
*************** etoibm (x, d, mode)
*** 5938,5944 ****
  							/* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 56;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
    toibm (xi, d, mode);
  }
--- 5949,5955 ----
  							/* round off to nearest or even */
    rndsav = rndprc;
    rndprc = 56;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
    toibm (xi, d, mode);
  }
*************** etoc4x (x, d, mode)
*** 6136,6142 ****
    /* Round off to nearest or even.  */
    rndsav = rndprc;
    rndprc = mode == QFmode ? 24 : 32;
!   emdnorm (xi, 0, 0, exp, 64);
    rndprc = rndsav;
    toc4x (xi, d, mode);
  }
--- 6147,6153 ----
    /* Round off to nearest or even.  */
    rndsav = rndprc;
    rndprc = mode == QFmode ? 24 : 32;
!   emdnorm (xi, 0, 0, exp, !ROUND_TOWARDS_ZERO);
    rndprc = rndsav;
    toc4x (xi, d, mode);
  }
*************** make_nan (nan, sign, mode)
*** 6298,6304 ****
--- 6309,6323 ----
  {
    int n;
    const UEMUSHORT *p;
+   int size;
  
+   size = GET_MODE_BITSIZE (mode);
+   if (LARGEST_EXPONENT_IS_NORMAL (size))
+     {
+       warning ("%d-bit floats cannot hold NaNs", size);
+       saturate (nan, sign, size, 0);
+       return;
+     }
    switch (mode)
      {
  /* Possibly the `reserved operand' patterns on a VAX can be
*************** make_nan (nan, sign, mode)
*** 6353,6358 ****
--- 6372,6405 ----
  }
  #endif /* NANS */
  
+ 
+ /* Create a saturation value for a SIZE-bit float, assuming that
+    LARGEST_EXPONENT_IS_NORMAL (SIZE).
+ 
+    If SIGN is true, fill X with the most negative value, otherwise fill
+    it with the most positive value.  WARN is true if the function should
+    warn about overflow.  */
+ 
+ static void
+ saturate (x, sign, size, warn)
+      UEMUSHORT *x;
+      int sign, size, warn;
+ {
+   int i;
+ 
+   if (warn && extra_warnings)
+     warning ("value exceeds the range of a %d-bit float", size);
+ 
+   /* Create the most negative value.  */
+   for (i = 0; i < size / EMUSHORT_SIZE; i++)
+     x[i] = 0xffff;
+ 
+   /* Make it positive, if necessary.  */
+   if (!sign)
+     x[REAL_WORDS_BIG_ENDIAN? 0 : i - 1] = 0x7fff;
+ }
+ 
+ 
  /* This is the inverse of the function `etarsingle' invoked by
     REAL_VALUE_TO_TARGET_SINGLE.  */
  
*************** esqrt (x, y)
*** 6876,6882 ****
      k |= (int) num[i];
  
    /* Renormalize and round off.  */
!   emdnorm (sq, k, 0, exp, 64);
    emovo (sq, y);
  }
  #endif
--- 6923,6929 ----
      k |= (int) num[i];
  
    /* Renormalize and round off.  */
!   emdnorm (sq, k, 0, exp, !ROUND_TOWARDS_ZERO);
    emovo (sq, y);
  }
  #endif
Index: config/fp-bit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v
retrieving revision 1.28
diff -c -p -d -r1.28 fp-bit.c
*** config/fp-bit.c	2001/12/12 06:59:23	1.28
--- config/fp-bit.c	2002/03/08 16:10:36
***************
*** 1,6 ****
  /* This is a software floating point library which can be used
     for targets without hardware floating point. 
!    Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001
     Free Software Foundation, Inc.
  
  This file is free software; you can redistribute it and/or modify it
--- 1,6 ----
  /* This is a software floating point library which can be used
     for targets without hardware floating point. 
!    Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002
     Free Software Foundation, Inc.
  
  This file is free software; you can redistribute it and/or modify it
*************** pack_d ( fp_number_type *  src)
*** 181,187 ****
    int sign = src->sign;
    int exp = 0;
  
!   if (isnan (src))
      {
        exp = EXPMAX;
        if (src->class == CLASS_QNAN || 1)
--- 181,195 ----
    int sign = src->sign;
    int exp = 0;
  
!   if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
!     {
!       /* We can't represent these values accurately.  By using the
! 	 largest possible magnitude, we guarantee that the conversion
! 	 of infinity is at least as big as any finite number.  */
!       exp = EXPMAX;
!       fraction = ((fractype) 1 << FRACBITS) - 1;
!     }
!   else if (isnan (src))
      {
        exp = EXPMAX;
        if (src->class == CLASS_QNAN || 1)
*************** pack_d ( fp_number_type *  src)
*** 207,212 ****
--- 215,227 ----
      {
        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)
*** 242,249 ****
  	      exp += 1;
  	    }
  	  fraction >>= NGARDS;
  	}
!       else if (src->normal_exp > EXPBIAS)
  	{
  	  exp = EXPMAX;
  	  fraction = 0;
--- 257,266 ----
  	      exp += 1;
  	    }
  	  fraction >>= NGARDS;
+ #endif /* NO_DENORMALS */
  	}
!       else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
! 	       && src->normal_exp > EXPBIAS)
  	{
  	  exp = EXPMAX;
  	  fraction = 0;
*************** pack_d ( fp_number_type *  src)
*** 251,275 ****
        else
  	{
  	  exp = src->normal_exp + EXPBIAS;
! 	  /* IF the gard bits are the all zero, but the first, then we're
! 	     half way between two numbers, choose the one which makes the
! 	     lsb of the answer 0.  */
! 	  if ((fraction & GARDMASK) == GARDMSB)
! 	    {
! 	      if (fraction & (1 << NGARDS))
! 		fraction += GARDROUND + 1;
! 	    }
! 	  else
  	    {
! 	      /* Add a one to the guards to round up */
! 	      fraction += GARDROUND;
  	    }
! 	  if (fraction >= IMPLICIT_2)
  	    {
! 	      fraction >>= 1;
! 	      exp += 1;
  	    }
- 	  fraction >>= NGARDS;
  	}
      }
  
--- 268,302 ----
        else
  	{
  	  exp = src->normal_exp + EXPBIAS;
! 	  if (!ROUND_TOWARDS_ZERO)
  	    {
! 	      /* IF the gard bits are the all zero, but the first, then we're
! 		 half way between two numbers, choose the one which makes the
! 		 lsb of the answer 0.  */
! 	      if ((fraction & GARDMASK) == GARDMSB)
! 		{
! 		  if (fraction & (1 << NGARDS))
! 		    fraction += GARDROUND + 1;
! 		}
! 	      else
! 		{
! 		  /* Add a one to the guards to round up */
! 		  fraction += GARDROUND;
! 		}
! 	      if (fraction >= IMPLICIT_2)
! 		{
! 		  fraction >>= 1;
! 		  exp += 1;
! 		}
  	    }
! 	  fraction >>= NGARDS;
! 
! 	  if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
  	    {
! 	      /* Saturate on overflow.  */
! 	      exp = EXPMAX;
! 	      fraction = ((fractype) 1 << FRACBITS) - 1;
  	    }
  	}
      }
  
*************** unpack_d (FLO_union_type * src, fp_numbe
*** 359,365 ****
  	  dst->fraction.ll = fraction;
  	}
      }
!   else if (exp == EXPMAX)
      {
        /* Huge exponent*/
        if (fraction == 0)
--- 386,392 ----
  	  dst->fraction.ll = fraction;
  	}
      }
!   else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX)
      {
        /* Huge exponent*/
        if (fraction == 0)
*************** _fpmul_parts ( fp_number_type *  a,
*** 729,735 ****
  	}
      }
  #endif
!   if ((high & GARDMASK) == GARDMSB)
      {
        if (high & (1 << NGARDS))
  	{
--- 756,762 ----
  	}
      }
  #endif
!   if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
      {
        if (high & (1 << NGARDS))
  	{
*************** _fpdiv_parts (fp_number_type * a,
*** 839,845 ****
  	numerator *= 2;
        }
  
!     if ((quotient & GARDMASK) == GARDMSB)
        {
  	if (quotient & (1 << NGARDS))
  	  {
--- 866,872 ----
  	numerator *= 2;
        }
  
!     if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
        {
  	if (quotient & (1 << NGARDS))
  	  {
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.109
diff -c -p -d -r1.109 tm.texi
*** doc/tm.texi	2002/03/07 11:37:16	1.109
--- doc/tm.texi	2002/03/08 16:10:36
*************** towards @minus{}infinity and towards +in
*** 1385,1390 ****
--- 1385,1430 ----
  
  The default definition of this macro is true if @var{mode} is
  a floating-point mode and the target format is IEEE@.
+ 
+ @findex ROUND_TOWARDS_ZERO
+ @item ROUND_TOWARDS_ZERO
+ If defined, this macro should be true if the prevailing rounding
+ mode is towards zero.  A true value has the following effects:
+ 
+ @itemize @bullet
+ @item
+ @samp{MODE_HAS_SIGN_DEPENDENT_ROUNDING} will be false for all modes.
+ 
+ @item
+ @file{libgcc.a}'s floating-point emulator will round towards zero
+ rather than towards nearest.
+ 
+ @item
+ The compiler's floating-point emulator will round towards zero after
+ doing arithmetic, and when converting from the internal float format to
+ the target format.
+ @end itemize
+ 
+ The macro does not affect the parsing of string literals.  When the
+ primary rounding mode is towards zero, library functions like
+ @samp{strtod} might still round towards nearest, and the compiler's
+ parser should behave like the target's @samp{strtod} where possible.
+ 
+ Not defining this macro is equivalent to returning zero.
+ 
+ @findex LARGEST_EXPONENT_IS_NORMAL
+ @item LARGEST_EXPONENT_IS_NORMAL (@var{size})
+ This macro should only be defined when the target float format is
+ described as IEEE@.  It should return true if floats with @var{size}
+ bits do not have a NaN or infinity representation, but use the largest
+ exponent for normal numbers instead.
+ 
+ Defining this macro to true for @var{size} causes @samp{MODE_HAS_NANS}
+ and @samp{MODE_HAS_INFINITIES} to be false for @var{size}-bit modes.
+ It also affects the way @file{libgcc.a} and @file{real.c} emulate
+ floating-point arithmetic.
+ 
+ The default definition of this macro returns false for all sizes.
  @end table
  
  @deftypefn {Target Hook} bool TARGET_MS_BITFIELD_LAYOUT_P (tree @var{record_type})



More information about the Gcc-patches mailing list