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]
Other format: [Raw text]

Re: Powerpc64 long double support


Alan Modra <amodra@bigpond.net.au> writes:
> Index: gcc/real.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/real.c,v
> retrieving revision 1.139
> diff -u -p -r1.139 real.c
> --- gcc/real.c	4 Mar 2004 10:23:20 -0000	1.139
> +++ gcc/real.c	9 Mar 2004 23:34:36 -0000
> @@ -3216,10 +3215,9 @@ const struct real_format ieee_extended_i
>     numbers whose sum is equal to the extended precision value.  The number
>     with greater magnitude is first.  This format has the same magnitude
>     range as an IEEE double precision value, but effectively 106 bits of
> -   significand precision.  Infinity and NaN are represented by their IEEE
> -   double precision value stored in the first number, the second number is
> -   ignored.  Zeroes, Infinities, and NaNs are set in both doubles
> -   due to precedent.  */
> +   significand precision.  Zero, Infinity and NaN are represented by their
> +   IEEE double precision value stored in the first number, the second
> +   number is -0.0.  */
>  
>  static void encode_ibm_extended (const struct real_format *fmt,
>  				 long *, const REAL_VALUE_TYPE *);
> @@ -3256,9 +3254,21 @@ encode_ibm_extended (const struct real_f
>    else
>      {
>        /* Inf, NaN, 0 are all representable as doubles, so the
> -	 least-significant part can be 0.0.  */
> -      buf[2] = 0;
> -      buf[3] = 0;
> +	 least-significant part can be zero.  We choose -0.0 because
> +	 conversion of IBM extended precision to double is done by
> +	 adding the two component doubles.  -0.0 is the only value that
> +	 will result in a long double -0.0 correctly converting to a
> +	 -0.0 double.  */
> +      if (FLOAT_WORDS_BIG_ENDIAN)
> +	{
> +	  buf[2] = 0x80000000;
> +	  buf[3] = 0;
> +	}
> +      else
> +	{
> +	  buf[2] = 0;
> +	  buf[3] = 0x80000000;
> +	}
>      }
>  }
>  

This function seems to be developing in a very ad-hoc way.  Is there really
no spec that says what a canonical "IBM format" number should look like?

The current implementation does seem to be correct for IRIX.  It certainly
uses +0.0 as the low part of NaN, +/-Inf and +/-0.0.  We'd need to split
the definition into two if your patch is needed for powerpc.

FWIW, here's the output of the attached program when compiled with MIPSpro cc.

     NaN : 7ff7ffff ffffffff : 00000000 00000000
    +Inf : 7ff00000 00000000 : 00000000 00000000
       0 : 00000000 00000000 : 00000000 00000000
      -0 : 80000000 00000000 : 00000000 00000000
    -Inf : fff00000 00000000 : 00000000 00000000

Richard


#include <float.h>

void print_it (const char *fmt, long double ll)
{
  union { long double ll; unsigned int i[4]; } u;
  u.ll = ll;
  printf ("%8s : %08x %08x : %08x %08x\n",
	  fmt, u.i[0], u.i[1], u.i[2], u.i[3]);
}

int main ()
{
  print_it ("NaN", 0.0L/0.0L);
  print_it ("+Inf", 1.0L/0.0L);
  print_it ("0", LDBL_MIN / 1e100);
  print_it ("-0", -LDBL_MIN / 1e100);
  print_it ("-Inf", -1.0L/0.0L);
  exit (0);
}


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