qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH 4/5] softfloat: add float{32, 64, x80, 128}_unor


From: Peter Maydell
Subject: [Qemu-devel] Re: [PATCH 4/5] softfloat: add float{32, 64, x80, 128}_unordered() functions
Date: Sun, 10 Apr 2011 20:59:04 +0100

On 10 April 2011 20:13, Aurelien Jarno <address@hidden> wrote:
> Add float{32,64,x80,128}_unordered() functions to softfloat, matching
> the softfloat-native ones. This allow target-i386/ops_sse.h to be
> compiled with softfloat.

I guess you could have made the x86 target use float*_compare()
instead, but I agree that it makes sense to have the unordered()
comparison to match the other specific-comparison ops.

>  
> /*----------------------------------------------------------------------------
> +| Returns 1 if the single-precision floating-point values `a' and `b' cannot
> +| be compared, and 0 otherwise. The comparison is performed according to the
> +| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
> +*----------------------------------------------------------------------------*/
> +
> +int float32_unordered( float32 a, float32 b STATUS_PARAM )
> +{
> +    a = float32_squash_input_denormal(a STATUS_VAR);
> +    b = float32_squash_input_denormal(b STATUS_VAR);
> +
> +    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
> +         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
> +       ) {
> +        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) 
> ) {
> +            float_raise( float_flag_invalid STATUS_VAR);
> +        }
> +        return 1;
> +    }
> +
> +    return 0;
> +}

So the NaN signalling semantics here are that we raise Invalid
for an SNaN but not for a QNaN. That's correct for the x86 op
we're implementing, but the float*_lt, _le and _compare functions
use the _quiet suffix for these semantics (with plain float*_lt
etc being "raise Invalid for both QNaN and SNaN"). So I think
these functions should be float*_unordered_quiet().

Annoyingly for eq the two versions use a different convention,
so we have float*_eq [raise Invalid only if SNaN] and
float*_eq_signaling [for any NaN] -- ideally that inconsistency
should be fixed...

> +int float64_unordered( float64 a, float64 b STATUS_PARAM )
> +{
> +    a = float64_squash_input_denormal(a STATUS_VAR);
> +    b = float64_squash_input_denormal(b STATUS_VAR);
> +
> +    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) 
> )
> +         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) 
> )
> +       ) {
> +        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) 
> ) {
> +            float_raise( float_flag_invalid STATUS_VAR);
> +        }
> +        return 0;
> +    }
> +    return 1;
> +}

You've got the sense the wrong way round on this one, I think.

I note that target-mips has a private float32_is_unordered()
and float64_is_unordered() which could probably be cleaned
up to use these instead. You'd need to implement both the
float*_unordered() and float*_unordered_quiet() versions.

-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]