qemu-ppc
[Top][All Lists]
Advanced

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

Re: [Qemu-ppc] [Qemu-devel] [V2 PATCH 11/18] softfloat: Fix float64_to_u


From: Tom Musta
Subject: Re: [Qemu-ppc] [Qemu-devel] [V2 PATCH 11/18] softfloat: Fix float64_to_uint32
Date: Wed, 18 Dec 2013 11:32:08 -0600
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0

On 12/17/2013 11:45 AM, Peter Maydell wrote:
> On 11 December 2013 20:39, Tom Musta <address@hidden> wrote:
>> On 12/11/2013 1:53 PM, Peter Maydell wrote:
>>> On 11 December 2013 19:16, Tom Musta <address@hidden> wrote:
>>>>  uint32 float64_to_uint32( float64 a STATUS_PARAM )
>>>>  {
>>>> -    int64_t v;
>>>> +    uint64_t v;
>>>>      uint32 res;
>>>>
>>>> -    v = float64_to_int64(a STATUS_VAR);
>>>> -    if (v < 0) {
>>>> -        res = 0;
>>>> -        float_raise( float_flag_invalid STATUS_VAR);
>>>> -    } else if (v > 0xffffffff) {
>>>> +    v = float64_to_uint64(a STATUS_VAR);
>>>> +    if (v > 0xffffffff) {
>>>>          res = 0xffffffff;
>>>> +        STATUS(float_exception_flags) &= ~float_flag_inexact;
>>>
>>> The IEEE exception flags are cumulative (ie never get cleared
>>> except by guest program explicit request); this change means
>>> that if a previous operation raised the inexact flag you've just
>>> lost that.
>>>
>>> thanks
>>> -- PMM
>>>
>> Thank you, Peter.  I will fix.
> 
> I'm partway through fixing this bug in an implementation of
> float*_to_uint16 which the ARM AArch64 needs. I think the
> cleanest approach to this looks like this:
> 
> uint32 float64_to_uint32( float64 a STATUS_PARAM )
> {
>     int64_t v;
>     uint32 res;
>     int old_exc_flags = get_float_exception_flags(status);
> 
>     v = float64_to_uint64(a STATUS_VAR);
>     if (v > 0xffffffff) {
>         res = 0xffffffff;
>     } else {
>         return v;
>     }
>     set_float_exception_flags(old_exc_flags);
>     float_raise(float_flag_invalid STATUS_VAR);
>     return res;
> }
> 
> thanks
> -- PMM
> 

This seems to assume that the only case where flags could be set in
float64_to_uint32 is the case where a large result is returned. Is
this really the case?

I was thinking something like this:

uint32 float64_to_uint32( float64 a STATUS_PARAM )
{
    uint64_t v;
    uint32 res;
    int inexact = (STATUS(float_exception_flags) & float_flag_inexact) != 0;

    v = float64_to_uint64(a STATUS_VAR);
    if (v > 0xffffffff) {
        res = 0xffffffff;
        /* If the inexact flag was set during this operation, then clear it. */
        if (!inexact) {
            STATUS(float_exception_flags) &= ~float_flag_inexact;
        }
        float_raise( float_flag_invalid STATUS_VAR);
    } else {
        res = v;
    }
    return res;
}




reply via email to

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