From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36791) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VtKyq-0000a3-PK for qemu-devel@nongnu.org; Wed, 18 Dec 2013 12:32:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VtKyi-0002sM-Bn for qemu-devel@nongnu.org; Wed, 18 Dec 2013 12:32:20 -0500 Message-ID: <52B1DC18.4080106@gmail.com> Date: Wed, 18 Dec 2013 11:32:08 -0600 From: Tom Musta MIME-Version: 1.0 References: <1386789398-5239-1-git-send-email-tommusta@gmail.com> <1386789398-5239-12-git-send-email-tommusta@gmail.com> <52A8CD67.8060804@gmail.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [V2 PATCH 11/18] softfloat: Fix float64_to_uint32 List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell Cc: "qemu-ppc@nongnu.org" , QEMU Developers On 12/17/2013 11:45 AM, Peter Maydell wrote: > On 11 December 2013 20:39, Tom Musta wrote: >> On 12/11/2013 1:53 PM, Peter Maydell wrote: >>> On 11 December 2013 19:16, Tom Musta 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; }