This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Powerpc64 long double support
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: Steve Munroe <sjmunroe at us dot ibm dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Geoff Keating <geoffk at geoffk dot org>,Andreas Jaeger <aj at suse dot de>, Dwayne McConnell <dgm69 at us dot ibm dot com>,David Edelsohn <dje at watson dot ibm dot com>,Marcus Meissner <meissner at suse dot de>
- Date: Sat, 6 Mar 2004 20:22:13 +1030
- Subject: Re: Powerpc64 long double support
- References: <40491948.2010900@us.ibm.com>
On Fri, Mar 05, 2004 at 06:20:24PM -0600, Steve Munroe wrote:
> Making progress, the code builds but still has a number of make check
> failures. Any one who has time for code review and suggested
> improvements would be greatly appreciated.
>
> One make check failure may be a code gen bug in hammer3_3. The problem
> is in nexttoward(). For test-idouble; nexttoward (0, -0) and nexttoward
> (-0, -0) should return -0 but we are getting 0 instead.
>
> The offending statement in s_nexttoward.c is line 54:
>
> if((long double) x==y) return y; /* x=y, return y */
>
> The code generate is:
>
> 10000c9c: fc 00 68 90 fmr f0,f13
> 10000ca0: c8 22 81 50 lfd f1,-32432(r2)
> 10000ca4: ff 80 18 00 fcmpu cr7,f0,f3
> 10000ca8: 40 9e 00 08 bne- cr7,10000cb0
> 10000cac: ff 81 20 00 fcmpu cr7,f1,f4
> 10000cb0: 40 9e 00 18 bne- cr7,10000cc8
> 10000cb4: fc 23 20 2a fadd f1,f3,f4
> 10000cb8: 38 21 00 90 addi r1,r1,144
> 10000cbc: e8 01 00 10 ld r0,16(r1)
> 10000cc0: 7c 08 03 a6 mtlr r0
> 10000cc4: 4e 80 00 20 blr
>
> It seems that the coversion of y (a long double) to double generates a
> fadd f1,f3,f4 which seems to change the sign.
This is due to another error in real.c:encode_ibm_extended.
* real.c (encode_ibm_extended): Duplicate high double in low for
zeros, infinities and nans. Explain why.
Index: gcc/real.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/real.c,v
retrieving revision 1.103.2.7
diff -u -p -r1.103.2.7 real.c
--- gcc/real.c 5 Mar 2004 15:06:08 -0000 1.103.2.7
+++ gcc/real.c 6 Mar 2004 09:48:23 -0000
@@ -3298,8 +3298,9 @@ const struct real_format ieee_extended_i
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. */
+ ignored. Zeroes are set in both doubles so that conversion of a
+ long double -0.0 to double by adding the two doubles will result in
+ -0.0. Infinities and NaNs do the same due to precedent. */
static void encode_ibm_extended PARAMS ((const struct real_format *fmt,
long *, const REAL_VALUE_TYPE *));
@@ -3337,10 +3338,8 @@ encode_ibm_extended (fmt, buf, r)
}
else
{
- /* Inf, NaN, 0 are all representable as doubles, so the
- least-significant part can be 0.0. */
- buf[2] = 0;
- buf[3] = 0;
+ buf[2] = buf[0];
+ buf[3] = buf[1];
}
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre