Patchwork [V2,12/18] softfloat: Fix float64_to_uint32_round_to_zero

login
register
mail settings
Submitter Tom Musta
Date Dec. 11, 2013, 7:16 p.m.
Message ID <1386789398-5239-13-git-send-email-tommusta@gmail.com>
Download mbox | patch
Permalink /patch/300321/
State New
Headers show

Comments

Tom Musta - Dec. 11, 2013, 7:16 p.m.
The float64_to_uint32_round_to_zero routine is incorrect.

For example, the following test pattern:

    425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38

will erroneously set the inexact flag.

This patch re-implements the routine to temporarily force the
rounding mode and use the float64_to_uint32 routine.

Signed-off-by: Tom Musta <tommusta@gmail.com>
---
 fpu/softfloat.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)
Peter Maydell - Dec. 11, 2013, 7:54 p.m.
On 11 December 2013 19:16, Tom Musta <tommusta@gmail.com> wrote:
> The float64_to_uint32_round_to_zero routine is incorrect.
>
> For example, the following test pattern:
>
>     425F81378DC0CD1F / 0x1.f81378dc0cd1fp+38
>
> will erroneously set the inexact flag.
>
> This patch re-implements the routine to temporarily force the
> rounding mode and use the float64_to_uint32 routine.

>  uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
>  {
> -    int64_t v;
> +    uint64_t v;
>      uint32 res;
>
> -    v = float64_to_int64_round_to_zero(a STATUS_VAR);
> -    if (v < 0) {
> -        res = 0;
> -        float_raise( float_flag_invalid STATUS_VAR);
> -    } else if (v > 0xffffffff) {
> +    v = float64_to_uint64_round_to_zero(a STATUS_VAR);
> +    if (v > 0xffffffff) {
>          res = 0xffffffff;
> +        STATUS(float_exception_flags) &= ~float_flag_inexact;
>          float_raise( float_flag_invalid STATUS_VAR);
>      } else {
>          res = v;

The patch doesn't seem to be doing what the commit message
says it does?

thanks
-- PMM

Patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6a8b6f5..052c202 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6594,15 +6594,13 @@  uint32 float64_to_uint32( float64 a STATUS_PARAM )
 
 uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
 {
-    int64_t v;
+    uint64_t v;
     uint32 res;
 
-    v = float64_to_int64_round_to_zero(a STATUS_VAR);
-    if (v < 0) {
-        res = 0;
-        float_raise( float_flag_invalid STATUS_VAR);
-    } else if (v > 0xffffffff) {
+    v = float64_to_uint64_round_to_zero(a STATUS_VAR);
+    if (v > 0xffffffff) {
         res = 0xffffffff;
+        STATUS(float_exception_flags) &= ~float_flag_inexact;
         float_raise( float_flag_invalid STATUS_VAR);
     } else {
         res = v;