[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