qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC PATCH] softfloat: re-factor float to float convers


From: Richard Henderson
Subject: Re: [Qemu-devel] [RFC PATCH] softfloat: re-factor float to float conversions
Date: Thu, 26 Apr 2018 11:13:06 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

On 04/26/2018 05:40 AM, Alex Bennée wrote:
> +    bool arm_hp = !ieee && (src_sz == 16);

Surely you should be testing the destination format.
The float16_unpack_canonical step should be handling
the (non-)special cases to get into FloatParts.

It would probably be better to invert the parameter to be arm_hp rather than
ieee; that way you don't need to test the format; it'll be implied.

> +        /* Our only option now is to "re-pack" the NaN. As the
> +         * canonilization process doesn't mess with fraction bits for
> +         * NaNs we do it all here
> +         */
> +        switch (src_sz) {
> +        case 64:
> +            break;
> +        case 32:
> +            a.frac = deposit64(0, 29, 22, extract64(a.frac, 0, 22));
> +            break;
> +        case 16:
> +            a.frac = deposit64(0, 42, 9, extract64(a.frac, 0, 9));
> +            break;
> +        default:
> +            g_assert_not_reached();
> +            break;
> +        }
> +
> +        /* Get all the frac bits we need with MSB set */

This is assuming QNaN has MSB set.  We also support SNaN with MSB set.

> +        switch (dst_sz) {
> +        case 64:
> +            a.frac = (1ULL << 51) | extract64(a.frac, 0, 51);
> +            break;
> +        case 32:
> +            a.frac = (1 << 22) | extract64(a.frac, 29, 22);
> +            break;
> +        case 16:
> +            a.frac = (1 << 9) | extract64(a.frac, 42, 9);
> +            break;
> +        default:
> +            g_assert_not_reached();
> +            break;
> +        }

This would be better with

  a.frac = a.frac << (64 - src->frac_size) >> (64 - dst->frac_size);
  a.cls = float_class_msnan;

which has no such magic numbers.

> +    } else if (a.cls == float_class_inf && arm_hp) {
> +        /* FPProcessException(FPExc_InvalidOp, fpcr); */
> +        s->float_exception_flags |= float_flag_invalid;
> +        /* Alt HP returns result = sign:Ones(M-1) - faking qnan
> +         * forces round_canonical to use frac for the final bits
> +         */
> +        a.cls = float_class_qnan;
> +        a.frac = -1;

Wow, that's... ugly.  I would really prefer that you put the correct values
into the structure.

You'll need to pass ieee into float16_round_pack_canonical anyway, since
otherwise you'll get the wrong results for e.g. 1.111p31 (overflows to inf with
ieee hp; representable with armhp).


r~



reply via email to

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