Patchwork [1/2] softfloat: Implement floatx80_is_any_nan() and float128_is_any_nan()

login
register
mail settings
Submitter Peter Maydell
Date Jan. 6, 2011, 6:34 p.m.
Message ID <1294338884-20322-2-git-send-email-peter.maydell@linaro.org>
Download mbox | patch
Permalink /patch/77795/
State New
Headers show

Comments

Peter Maydell - Jan. 6, 2011, 6:34 p.m.
Implement versions of float*_is_any_nan() for the floatx80 and
float128 types.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 fpu/softfloat.h |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)
Aurelien Jarno - Jan. 7, 2011, 3:28 p.m.
On Thu, Jan 06, 2011 at 06:34:43PM +0000, Peter Maydell wrote:
> Implement versions of float*_is_any_nan() for the floatx80 and
> float128 types.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  fpu/softfloat.h |   11 +++++++++++
>  1 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/fpu/softfloat.h b/fpu/softfloat.h
> index f2104c6..ac81845 100644
> --- a/fpu/softfloat.h
> +++ b/fpu/softfloat.h
> @@ -469,6 +469,11 @@ INLINE int floatx80_is_zero(floatx80 a)
>      return (a.high & 0x7fff) == 0 && a.low == 0;
>  }
>  
> +INLINE int floatx80_is_any_nan(floatx80 a)
> +{
> +    return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
> +}
> +
>  #endif

While this looks correct, this seems to say that our definition of
floatx80_is_quiet_nan() (for SNAN_BIT_IS_ZERO) is wrong as it is exactly
the same.

>  #ifdef FLOAT128
> @@ -536,6 +541,12 @@ INLINE int float128_is_zero(float128 a)
>      return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
>  }
>  
> +INLINE int float128_is_any_nan(float128 a)
> +{
> +    return ((a.high >> 48) & 0x7fff) == 0x7fff &&
> +        ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
> +}
> +
>  #endif
>  
>  #else /* CONFIG_SOFTFLOAT */
> -- 
> 1.6.3.3
> 

Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Peter Maydell - Jan. 7, 2011, 3:46 p.m.
On 7 January 2011 15:28, Aurelien Jarno <aurelien@aurel32.net> wrote:
> On Thu, Jan 06, 2011 at 06:34:43PM +0000, Peter Maydell wrote:
>> Implement versions of float*_is_any_nan() for the floatx80 and
>> float128 types.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  fpu/softfloat.h |   11 +++++++++++
>>  1 files changed, 11 insertions(+), 0 deletions(-)
>>
>> diff --git a/fpu/softfloat.h b/fpu/softfloat.h
>> index f2104c6..ac81845 100644
>> --- a/fpu/softfloat.h
>> +++ b/fpu/softfloat.h
>> @@ -469,6 +469,11 @@ INLINE int floatx80_is_zero(floatx80 a)
>>      return (a.high & 0x7fff) == 0 && a.low == 0;
>>  }
>>
>> +INLINE int floatx80_is_any_nan(floatx80 a)
>> +{
>> +    return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
>> +}
>> +
>>  #endif
>
> While this looks correct, this seems to say that our definition of
> floatx80_is_quiet_nan() (for SNAN_BIT_IS_ZERO) is wrong as it is exactly
> the same.

Hrm. I suspect this is confusion caused by floatx80 having
an explicit hidden bit (most significant bit of the significand)
where float32/float64 have an implicit hidden bit. I think
floatx80_is_quiet_nan() must be wrong because:

int floatx80_is_quiet_nan( floatx80 a )
{
#if SNAN_BIT_IS_ONE
    bits64 aLow;

    aLow = a.low & ~ LIT64( 0x4000000000000000 );
    return
           ( ( a.high & 0x7FFF ) == 0x7FFF )
        && (bits64) ( aLow<<1 )
        && ( a.low == aLow );
#else
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
#endif
}

the two halves of the ifdef ought to carve the space up
into two disjoint halves, but you can see that the
!SNAN_BIT_IS_ONE condition is a superset of the other.

-- PMM

Patch

diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index f2104c6..ac81845 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -469,6 +469,11 @@  INLINE int floatx80_is_zero(floatx80 a)
     return (a.high & 0x7fff) == 0 && a.low == 0;
 }
 
+INLINE int floatx80_is_any_nan(floatx80 a)
+{
+    return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1);
+}
+
 #endif
 
 #ifdef FLOAT128
@@ -536,6 +541,12 @@  INLINE int float128_is_zero(float128 a)
     return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0;
 }
 
+INLINE int float128_is_any_nan(float128 a)
+{
+    return ((a.high >> 48) & 0x7fff) == 0x7fff &&
+        ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0));
+}
+
 #endif
 
 #else /* CONFIG_SOFTFLOAT */