Patchwork [3/9] softfloat: fix default-NaN mode

login
register
mail settings
Submitter Aurelien Jarno
Date Jan. 11, 2011, 9:01 p.m.
Message ID <1294779698-17694-4-git-send-email-aurelien@aurel32.net>
Download mbox | patch
Permalink /patch/78442/
State New
Headers show

Comments

Aurelien Jarno - Jan. 11, 2011, 9:01 p.m.
When the default-NaN mode is enabled, it should return the default NaN
value, but it should anyway raise the invalid operation flag if one of
the operand is an sNaN.

I have checked that this behavior matches the ARM and SH4 manuals, as
well as real SH4 hardware.

Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
 fpu/softfloat-specialize.h |   36 ++++++++++++++++++------------------
 1 files changed, 18 insertions(+), 18 deletions(-)
Peter Maydell - Jan. 11, 2011, 9:29 p.m.
On 11 January 2011 15:01, Aurelien Jarno <aurelien@aurel32.net> wrote:
> When the default-NaN mode is enabled, it should return the default NaN
> value, but it should anyway raise the invalid operation flag if one of
> the operand is an sNaN.
>
> I have checked that this behavior matches the ARM and SH4 manuals, as
> well as real SH4 hardware.
>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

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

-- PMM

Patch

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 186b4da..11521ce 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -278,9 +278,6 @@  static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
     flag aIsLargerSignificand;
     bits32 av, bv;
 
-    if ( STATUS(default_nan_mode) )
-        return float32_default_nan;
-
     aIsQuietNaN = float32_is_quiet_nan( a );
     aIsSignalingNaN = float32_is_signaling_nan( a );
     bIsQuietNaN = float32_is_quiet_nan( b );
@@ -290,6 +287,9 @@  static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
 
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
 
+    if ( STATUS(default_nan_mode) )
+        return float32_default_nan;
+
     if ((bits32)(av<<1) < (bits32)(bv<<1)) {
         aIsLargerSignificand = 0;
     } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
@@ -423,9 +423,6 @@  static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
     flag aIsLargerSignificand;
     bits64 av, bv;
 
-    if ( STATUS(default_nan_mode) )
-        return float64_default_nan;
-
     aIsQuietNaN = float64_is_quiet_nan( a );
     aIsSignalingNaN = float64_is_signaling_nan( a );
     bIsQuietNaN = float64_is_quiet_nan( b );
@@ -435,6 +432,9 @@  static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
 
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
 
+    if ( STATUS(default_nan_mode) )
+        return float64_default_nan;
+
     if ((bits64)(av<<1) < (bits64)(bv<<1)) {
         aIsLargerSignificand = 0;
     } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
@@ -574,12 +574,6 @@  static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
     flag aIsLargerSignificand;
 
-    if ( STATUS(default_nan_mode) ) {
-        a.low = floatx80_default_nan_low;
-        a.high = floatx80_default_nan_high;
-        return a;
-    }
-
     aIsQuietNaN = floatx80_is_quiet_nan( a );
     aIsSignalingNaN = floatx80_is_signaling_nan( a );
     bIsQuietNaN = floatx80_is_quiet_nan( b );
@@ -587,6 +581,12 @@  static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
 
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
 
+    if ( STATUS(default_nan_mode) ) {
+        a.low = floatx80_default_nan_low;
+        a.high = floatx80_default_nan_high;
+        return a;
+    }
+
     if (a.low < b.low) {
         aIsLargerSignificand = 0;
     } else if (b.low < a.low) {
@@ -719,12 +719,6 @@  static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
     flag aIsLargerSignificand;
 
-    if ( STATUS(default_nan_mode) ) {
-        a.low = float128_default_nan_low;
-        a.high = float128_default_nan_high;
-        return a;
-    }
-
     aIsQuietNaN = float128_is_quiet_nan( a );
     aIsSignalingNaN = float128_is_signaling_nan( a );
     bIsQuietNaN = float128_is_quiet_nan( b );
@@ -732,6 +726,12 @@  static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
 
     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
 
+    if ( STATUS(default_nan_mode) ) {
+        a.low = float128_default_nan_low;
+        a.high = float128_default_nan_high;
+        return a;
+    }
+
     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
         aIsLargerSignificand = 0;
     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {