This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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: PowerPC floating point little-endian [4 of 15]


On Wed, Oct 02, 2013 at 11:17:13AM -0300, Adhemerval Zanella wrote:
> >  	if(__builtin_expect(hx<=hy,0)) {
> > -	    if((hx<hy)||(lx<ly)) return x;	/* |x|<|y| return x */
> > -	    if(lx==ly)
> > -		return Zero[(u_int64_t)sx>>63];	/* |x|=|y| return x*0*/
> > +	    if (hx < hy
> > +		|| (((ly ^ sy) & 0x8000000000000000LL) == 0
> > +		    && (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy))
> > +		|| (((lx ^ sx) & 0x8000000000000000LL) != 0
> > +		    && (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy)))
> > +		return x;			/* |x|<|y| return x */
> > +	    if ((lx ^ sx) == (ly ^ sy))
> > +		return Zero[(uint64_t)sx>>63];	/* |x|=|y| return x*0*/
> 
> These bitwise operations are kinda crypt at first sign, care to add a comment
> for the need of less than and greater than comparison expressing the need
> to check the magnitudes?

You're right, the code was a little cryptic, especially the last
magnitude test which would need uint64_t casts to handle the same sign
y doubles.  This is how I'll commit it.

-	if(__builtin_expect(hx<=hy,0)) {
-	    if((hx<hy)||(lx<ly)) return x;	/* |x|<|y| return x */
-	    if(lx==ly)
-		return Zero[(u_int64_t)sx>>63];	/* |x|=|y| return x*0*/
+	if (__builtin_expect (hx <= hy, 0))
+	  {
+	    /* If |x| < |y| return x.  */
+	    if (hx < hy)
+	      return x;
+	    /* At this point the absolute value of the high doubles of
+	       x and y must be equal.  */
+	    /* If the low double of y is the same sign as the high
+	       double of y (ie. the low double increases |y|)...  */
+	    if (((ly ^ sy) & 0x8000000000000000LL) == 0
+		/* ... then a different sign low double to high double
+		   for x or same sign but lower magnitude...  */
+		&& (int64_t) (lx ^ sx) < (int64_t) (ly ^ sy))
+	      /* ... means |x| < |y|.  */
+	      return x;
+	    /* If the low double of x differs in sign to the high
+	       double of x (ie. the low double decreases |x|)...  */
+	    if (((lx ^ sx) & 0x8000000000000000LL) != 0
+		/* ... then a different sign low double to high double
+		   for y with lower magnitude (we've already caught
+		   the same sign for y case above)...  */
+		&& (int64_t) (lx ^ sx) > (int64_t) (ly ^ sy))
+	      /* ... means |x| < |y|.  */
+	      return x;
+	    /* If |x| == |y| return x*0.  */
+	    if ((lx ^ sx) == (ly ^ sy))
+	      return Zero[(uint64_t) sx >> 63];
 	}


-- 
Alan Modra
Australia Development Lab, IBM


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