This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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);
}