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


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


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