linux-mips
[Top] [All Lists]

Re: ieee754[sd]p_neg workaround

To: "Maciej W. Rozycki" <macro@linux-mips.org>
Subject: Re: ieee754[sd]p_neg workaround
From: Dominic Sweetman <dom@mips.com>
Date: Wed, 20 Apr 2005 13:57:41 +0100
Cc: Atsushi Nemoto <anemo@mba.ocn.ne.jp>, linux-mips@linux-mips.org, ralf@linux-mips.org
In-reply-to: <Pine.LNX.4.61L.0504201312520.7109@blysk.ds.pg.gda.pl>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20050420.174023.113589096.nemoto@toshiba-tops.co.jp> <Pine.LNX.4.61L.0504201312520.7109@blysk.ds.pg.gda.pl>
Sender: linux-mips-bounce@linux-mips.org
Maciej W. Rozycki (macro@linux-mips.org) writes:

> > I have a long standing patch for FPU emulator to fix a segmentation
> > fault in pow() library function.
> > 
> > Here is a test program to reproduce it.
> > 
> > main()
> > {
> >     union {
> >             double d;
> >             struct {
> > #ifdef __MIPSEB
> >                     unsigned int high, low;
> > #else
> >                     unsigned int low, high;
> > #endif
> >             } i;
> >     } x, y, z;
> >         x.i.low = 0x00000000;
> >         x.i.high = 0xfff00001;
> >         y.i.low = 0x80000000;
> >         y.i.high = 0xcff00000;
> >         z.d = pow(x.d, y.d);
> >         printf("%x %x\n", z.i.high, z.i.low);
> >         return 0;
> > }
> > 
> > 
> > If you run this program, you will get segmentation fault (unless your
> > FPU does not raise Unimplemented exception for NaN operands).  The
> > segmentation fault is caused by endless recursion in __ieee754_pow().
> > 
> > It looks glibc's pow() assume unary '-' operation for any number
> > (including NaN) always invert its sign bit.
> 
>  AFAICS, the IEEE 754 standard explicitly leaves interpretation of the 
> sign bit for NaNs as unspecified.  Therefore our implementation is correct 
> and its glibc that should be fixed instead.  Please file a bug report 
> against glibc.

You are both right, in a sense.

"Annex A Recommended Functions and Predicates" of IEEE754 (the
annexe is not part of the formal spec) includes a recommendation:

   "­x is x copied with its sign reversed, not 0­x; the distinction is
    germane when x is ±0 or NaN."

And in fact that's how the MIPS neg.d operation works: it never
generates an exception, just blindly flips the sign bit.

In the body of IEEE754 it says:

   "This standard does not interpret the sign of an NaN."

So there you are.  According to the book, the library function should
not depend on the sign of a NaN, but it would also be better if the
compiler/emulator/whatever ensures that "-x" is always and only
implemented by reversing the sign bit.

So file a bug against glibc, but we should fix the emulator so it
correctly imitates the MIPS instruction set...

--
Dominic Sweetman
MIPS Technologies.

<Prev in Thread] Current Thread [Next in Thread>