[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64
From: |
Alexander Graf |
Subject: |
Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64 |
Date: |
Tue, 17 Dec 2013 14:42:06 +0100 |
On 01.11.2013, at 14:35, Tom Musta <address@hidden> wrote:
> The comment preceding the float64_to_uint64 routine suggests that
> the implementation is broken. And this is, indeed, the case.
>
> This patch properly implements the conversion of a 64-bit floating
> point number to an unsigned, 64 bit integer.
>
> This contribution can be licensed under either the softfloat-2a or -2b
> license.
>
> V2: Added softfloat license statement.
>
> V3: Modified to meet QEMU coding conventions.
>
> Signed-off-by: Tom Musta <address@hidden>
Softfloat really isn't my area of expertise and I'd prefer to see these patches
go in through a different tree :). Peter, do you want to take care of this
patch and "Add float32_to_uint64()"? Or at least give me your reviewed-by tag
and I'll send it through my tree since the second one is a build dependency for
VSX patches.
I've also seen comments on folding in bugfixes for patches that occurred
earlier. I presume this is one of these cases. Mind to shed some light on this?
Alex
> ---
> fpu/softfloat.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 files changed, 87 insertions(+), 8 deletions(-)
>
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index 7ba51b6..3070eaa 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -204,6 +204,47 @@ static int64 roundAndPackInt64( flag zSign, uint64_t
> absZ0, uint64_t absZ1 STATU
> }
>
> /*----------------------------------------------------------------------------
> +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
> +| `absZ1', with binary point between bits 63 and 64 (between the input
> words),
> +| and returns the properly rounded 64-bit unsigned integer corresponding to
> the
> +| input. Ordinarily, the fixed-point input is simply rounded to an integer,
> +| with the inexact exception raised if the input cannot be represented
> exactly
> +| as an integer. However, if the fixed-point input is too large, the invalid
> +| exception is raised and the largest unsigned integer is returned.
> +*----------------------------------------------------------------------------*/
> +
> +static int64 roundAndPackUint64(uint64_t absZ0, uint64_t absZ1 STATUS_PARAM)
> +{
> + int8 roundingMode;
> + flag roundNearestEven, increment;
> + int64_t z;
> +
> + roundingMode = STATUS(float_rounding_mode);
> + roundNearestEven = (roundingMode == float_round_nearest_even);
> + increment = ((int64_t) absZ1 < 0);
> + if (!roundNearestEven) {
> + if (roundingMode == float_round_to_zero) {
> + increment = 0;
> + } else {
> + increment = (roundingMode == float_round_up) && absZ1;
> + }
> + }
> + if (increment) {
> + ++absZ0;
> + if (absZ0 == 0) {
> + float_raise(float_flag_invalid STATUS_VAR);
> + return LIT64(0xFFFFFFFFFFFFFFFF);
> + }
> + absZ0 &= ~(((uint64_t)(absZ1<<1) == 0) & roundNearestEven);
> + }
> + z = absZ0;
> + if (absZ1) {
> + STATUS(float_exception_flags) |= float_flag_inexact;
> + }
> + return z;
> +}
> +
> +/*----------------------------------------------------------------------------
> | Returns the fraction bits of the single-precision floating-point value `a'.
> *----------------------------------------------------------------------------*/
>
> @@ -6536,18 +6577,56 @@ uint_fast16_t float64_to_uint16_round_to_zero(float64
> a STATUS_PARAM)
> return res;
> }
>
> -/* FIXME: This looks broken. */
> -uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
> -{
> - int64_t v;
> +/*----------------------------------------------------------------------------
> +| Returns the result of converting the double-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. If the conversion overflows, the
> +| largest unsigned integer is returned. If 'a' is negative, zero is
> +| returned.
> +*----------------------------------------------------------------------------*/
>
> - v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
> - v += float64_val(a);
> - v = float64_to_int64(make_float64(v) STATUS_VAR);
> +uint64_t float64_to_uint64(float64 a STATUS_PARAM)
> +{
> + flag aSign;
> + int_fast16_t aExp, shiftCount;
> + uint64_t aSig, aSigExtra;
> + a = float64_squash_input_denormal(a STATUS_VAR);
>
> - return v - INT64_MIN;
> + aSig = extractFloat64Frac(a);
> + aExp = extractFloat64Exp(a);
> + aSign = extractFloat64Sign(a);
> + if (aSign) {
> + if (aExp) {
> + float_raise(float_flag_invalid STATUS_VAR);
> + } else if (aSig) { /* negative denormalized */
> + float_raise(float_flag_inexact STATUS_VAR);
> + }
> + return 0;
> + }
> + if (aExp) {
> + aSig |= LIT64(0x0010000000000000);
> + }
> + shiftCount = 0x433 - aExp;
> + if (shiftCount <= 0) {
> + if (0x43E < aExp) {
> + if ((aSig != LIT64(0x0010000000000000)) ||
> + (aExp == 0x7FF)) {
> + float_raise(float_flag_invalid STATUS_VAR);
> + }
> + return LIT64(0xFFFFFFFFFFFFFFFF);
> + }
> + aSigExtra = 0;
> + aSig <<= -shiftCount;
> + } else {
> + shift64ExtraRightJamming(aSig, 0, shiftCount, &aSig, &aSigExtra);
> + }
> + return roundAndPackUint64(aSig, aSigExtra STATUS_VAR);
> }
>
> +
> uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
> {
> int64_t v;
> --
> 1.7.1
>
>
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64,
Alexander Graf <=
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Peter Maydell, 2013/12/17
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Alexander Graf, 2013/12/17
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Tom Musta, 2013/12/18
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Peter Maydell, 2013/12/18
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Tom Musta, 2013/12/18
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Peter Maydell, 2013/12/18
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Tom Musta, 2013/12/18
- Re: [Qemu-devel] [Qemu-ppc] [PATCH V3 01/19] Fix float64_to_uint64, Tom Musta, 2013/12/18