This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports 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: [PATCH] [BZ #2749] soft-fp fixes


Jakub Jelinek wrote:
>On Thu, Oct 12, 2006 at 10:57:50AM -0500, Steven Munroe wrote:
>  
>>2006-10-05  Steven Munroe  <sjmunroe@us.ibm.com>
>>	    Joe Kerian  <jkerian@us.us.ibm.com>
>>
>>	[BZ #2749]
>>	* soft-fp/fenv_libc.h: New file.
>>    
>
>Top level soft-fp directory doesn't sound like a good place for this,
>it has nothing to common with fenv_libc.h.  IMHO either stick it into
>math/fenv_libc.h, or let just each port provide its own (all current
>in tree arches that ever use fenv_libc.h do that, so ppc no-fpu could
>do the same).
>
>  
Ok, Moved fenv_libc.h to sysdeps/powerpc/nofpu.
>>	(_FP_PACK_SEMIRAW): Update comment.  Do not round if NaN.
>>    
>
>  
>>--- libc25-cvstip-20061005/soft-fp/op-common.h	2006-04-04 03:24:47.000000000 -0500
>>+++ libc24/soft-fp/op-common.h	2006-10-10 09:45:04.000000000 -0500
>>@@ -131,10 +131,12 @@
>>
>> /* Prepare to pack an fp value in semi-raw mode: the mantissa is
>>    rounded and shifted right, with the rounding possibly increasing
>>-   the exponent (including changing a finite value to infinity).  */
>>+   the exponent (including changing a finite value to infinity).
>>+   Be sure not to round NaNs.  */
>> #define _FP_PACK_SEMIRAW(fs, wc, X)				\
>> do {								\
>>-  _FP_ROUND(wc, X);						\
>>+  if(X##_e != _FP_EXPMAX_##fs)					\
>>+    _FP_ROUND(wc, X);						\
>>   if (_FP_FRAC_HIGH_##fs(X)					\
>>       & (_FP_OVERFLOW_##fs >> 1))				\
>>     {								\
>>    
>
>Can you please explain where does this make a difference?
>NaNs should have the least significant 3 bits (_FP_WORKBITS) cleared
>since they were shifted up during unpacking, so even when _FP_ROUND is
>called on the NaN, it shouldn't affect it in any way (_FP_ROUND does
>nothing if the work bits are all 0).
>
>  
This pops up for operations like:


    /* take care of Inf and NaN */
    if((ix&0x7f800000)==0x7f800000) {           
        return x*x+x;        /* sqrt(NaN)=NaN, sqrt(+inf)=+inf,
sqrt(-inf)=sNaN */

this will happen for sqrtf(-inf) for example but instead of a NaN we get
0.0.  and results in 14 detected errors in test-float.

While the fraction is zero for -inf , the test in _FP_ROUND_NEAREST is

#define _FP_ROUND_NEAREST(wc, X)            \
do {                            \
    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)    \
      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);        \
} while (0)

so even if the guard bits are zero going in (0b0000 != 0b0100) , the
_FP_FRAC_ADDI_ occurs.  These causes problems for float because
_FP_FRAC_LOW_ and _FP_FRAC_HIGH_ are the sameword. I have not verified
this but I suspect this cases the exponent to be incremented past
_FP_EXPMAX_ , The final _FP_PACK_RAW_1 results in a zeros in the
exponent and mantisa.


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