qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [RFC PATCH v0] softfloat: Add float128_to_uint64_round_to


From: Peter Maydell
Subject: Re: [Qemu-ppc] [RFC PATCH v0] softfloat: Add float128_to_uint64_round_to_zero()
Date: Fri, 3 Feb 2017 14:40:09 +0000

On 1 February 2017 at 10:49, Bharata B Rao <address@hidden> wrote:
> Implement float128_to_uint64() and use that to implement
> float128_to_uint64_round_to_zero()
>
> This is required by xscvqpudz instruction of PowerPC ISA 3.0.
>
> Signed-off-by: Bharata B Rao <address@hidden>
> ---
>  fpu/softfloat.c         | 65 
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/fpu/softfloat.h |  2 ++
>  2 files changed, 67 insertions(+)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index c295f31..49a06c5 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -6110,6 +6110,71 @@ int64_t float128_to_int64_round_to_zero(float128 a, 
> float_status *status)
>
>  
> /*----------------------------------------------------------------------------
>  | Returns the result of converting the quadruple-precision floating-point
> +| value `a' to the 64-bit unsigned integer format.  The conversion
> +| is performed according to the IEC/IEEE Standard for Binary Floating-Point
> +| Arithmetic---which means in particular that the conversion is rounded
> +| according to the current rounding mode.  If `a' is a NaN, the largest
> +| positive integer is returned.  Otherwise, if the conversion overflows, the
> +| largest unsigned integer is returned. If 'a' is negative, the value is
> +| rounded and zero is returned; negative values that do not round to zero
> +| will raise the inexact exception.
> +*----------------------------------------------------------------------------*/
> +
> +uint64_t float128_to_uint64(float128 a, float_status *status)
> +{
> +    flag aSign;
> +    int32_t aExp, shiftCount;
> +    uint64_t aSig0, aSig1;

I think we should have a float128_squash_input_denormal() function
which we call here (compare float64_to_uint64).

> +
> +    aSig1 = extractFloat128Frac1( a );

Can you use the QEMU coding style for this rather than following
the softfloat weird one, please?

> +    aSig0 = extractFloat128Frac0( a );
> +    aExp = extractFloat128Exp( a );
> +    aSign = extractFloat128Sign( a );
> +    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
> +    shiftCount = 0x402F - aExp;
> +    if ( shiftCount <= 0 ) {
> +        if ( 0x403E < aExp ) {
> +            float_raise(float_flag_invalid, status);
> +            if (    ! aSign
> +                 || (    ( aExp == 0x7FFF )
> +                      && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) 
> )
> +                    )
> +               ) {
> +                return LIT64( 0xFFFFFFFFFFFFFFFF );
> +            }
> +            return 0;
> +        }
> +        shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
> +    }
> +    else {
> +        shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
> +    }
> +    return roundAndPackUint64(aSign, aSig0, aSig1, status);

I'm finding this a bit difficult to understand, because it doesn't
follow the code pattern of (for instance) float64_to_uint64().
Is it based on some other existing function?

> +}
> +
> +/*----------------------------------------------------------------------------
> +| Returns the result of converting the quadruple-precision floating-point
> +| value `a' to the 64-bit unsigned integer format.  The conversion
> +| is performed according to the IEC/IEEE Standard for Binary Floating-Point
> +| Arithmetic, except that the conversion is always rounded toward zero.
> +| according to the current rounding mode.  If `a' is a NaN, the largest
> +| positive integer is returned.  Otherwise, if the conversion overflows, the
> +| largest unsigned integer is returned. If 'a' is negative, the value is
> +| rounded and zero is returned; negative values that do not round to zero
> +| will raise the inexact exception.
> +*----------------------------------------------------------------------------*/
> +
> +uint64_t float128_to_uint64_round_to_zero(float128 a, float_status *status)
> +{
> +    signed char current_rounding_mode = status->float_rounding_mode;
> +    set_float_rounding_mode(float_round_to_zero, status);
> +    uint64_t v = float128_to_uint64(a, status);
> +    set_float_rounding_mode(current_rounding_mode, status);
> +    return v;
> +}

This function is OK, though our coding style would suggest putting
the declaration of 'uint64_t v;' at the top of the function.

> +
> +/*----------------------------------------------------------------------------
> +| Returns the result of converting the quadruple-precision floating-point
>  | value `a' to the single-precision floating-point format.  The conversion
>  | is performed according to the IEC/IEEE Standard for Binary Floating-Point
>  | Arithmetic.
> diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
> index 842ec6b..4e99253 100644
> --- a/include/fpu/softfloat.h
> +++ b/include/fpu/softfloat.h
> @@ -712,6 +712,8 @@ int32_t float128_to_int32(float128, float_status *status);
>  int32_t float128_to_int32_round_to_zero(float128, float_status *status);
>  int64_t float128_to_int64(float128, float_status *status);
>  int64_t float128_to_int64_round_to_zero(float128, float_status *status);
> +uint64_t float128_to_uint64(float128, float_status *status);
> +uint64_t float128_to_uint64_round_to_zero(float128, float_status *status);
>  float32 float128_to_float32(float128, float_status *status);
>  float64 float128_to_float64(float128, float_status *status);
>  floatx80 float128_to_floatx80(float128, float_status *status);
> --
> 2.7.4

thanks
-- PMM



reply via email to

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