Patchwork [v3,01/20] softfloat: fix floatx80 handling of NaN

login
register
mail settings
Submitter Aurelien Jarno
Date April 20, 2011, 11:24 a.m.
Message ID <20110420112420.GE24035@volta.aurel32.net>
Download mbox | patch
Permalink /patch/92195/
State New
Headers show

Comments

Aurelien Jarno - April 20, 2011, 11:24 a.m.
The floatx80 format uses an explicit bit that should be taken into account
when converting to and from commonNaN format.

When converting to commonNaN, the explicit bit should be removed if it is
a 1, and a default NaN should be used if it is 0.

When converting from commonNan, the explicit bit should be added.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-specialize.h |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

v1 -> v2: fix wrong condition that may create an infinity instead of a
          NaN
v2 -> v3: don't change the sign of the default NaN.
Peter Maydell - April 20, 2011, 11:28 a.m.
On 20 April 2011 12:24, Aurelien Jarno <aurelien@aurel32.net> wrote:
> The floatx80 format uses an explicit bit that should be taken into account
> when converting to and from commonNaN format.
>
> When converting to commonNaN, the explicit bit should be removed if it is
> a 1, and a default NaN should be used if it is 0.
>
> When converting from commonNan, the explicit bit should be added.
>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
> ---
>  fpu/softfloat-specialize.h |   23 ++++++++++++++++-------
>  1 files changed, 16 insertions(+), 7 deletions(-)
>
> v1 -> v2: fix wrong condition that may create an infinity instead of a
>          NaN
> v2 -> v3: don't change the sign of the default NaN.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

-- PMM

Patch

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index b110187..9d68aae 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -603,9 +603,15 @@  static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
     commonNaNT z;
 
     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
-    z.sign = a.high>>15;
-    z.low = 0;
-    z.high = a.low;
+    if ( a.low >> 63 ) {
+        z.sign = a.high >> 15;
+        z.low = 0;
+        z.high = a.low << 1;
+    } else {
+        z.sign = floatx80_default_nan_high >> 15;
+        z.low = 0;
+        z.high = floatx80_default_nan_low << 1;
+    }
     return z;
 }
 
@@ -624,11 +630,14 @@  static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
         return z;
     }
 
-    if (a.high)
-        z.low = a.high;
-    else
+    if (a.high >> 1) {
+        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
+        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+    } else {
         z.low = floatx80_default_nan_low;
-    z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
+        z.high = floatx80_default_nan_high;
+    }
+
     return z;
 }