]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
FPU update 20b merge + nan/invalid fix.
authorToni Wilen <twilen@winuae.net>
Tue, 7 Feb 2017 15:05:41 +0000 (17:05 +0200)
committerToni Wilen <twilen@winuae.net>
Tue, 7 Feb 2017 15:05:41 +0000 (17:05 +0200)
fpp_softfloat.cpp
softfloat/softfloat-specialize.h
softfloat/softfloat.cpp
softfloat/softfloat.h

index 7043ebab494f11273f50f9a9964bb4f4ba191379..b30f2620a979636c42963bfb2e957a269428aa97 100644 (file)
@@ -44,6 +44,7 @@ static struct float_status fs;
 static void fp_set_mode(uae_u32 mode_control)
 {
        set_floatx80_rounding_precision(80, &fs);
+       set_float_detect_tininess(float_tininess_before_rounding, &fs);
     switch(mode_control & FPCR_ROUNDING_MODE) {
         case FPCR_ROUND_NEAR: // to neareset
             set_float_rounding_mode(float_round_nearest_even, &fs);
index 1586f3f770cbff0d4ca6fbcde4bccafa36946703..315debbbb8ae7f2255ba513c4f8caef407b072d8 100644 (file)
@@ -97,15 +97,9 @@ static inline flag floatx80_is_nan( floatx80 a )
 static floatx80 floatx80_default_nan(float_status *status)
 {
     floatx80 r;
-
-    if (status->snan_bit_is_one) {
-        r.low = LIT64(0xBFFFFFFFFFFFFFFF);
-        r.high = 0x7FFF;
-    } else {
-        r.low = LIT64(0xC000000000000000);
-        r.high = 0xFFFF;
-    }
-    return r;
+    r.high = 0x7FFF;
+    r.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+       return r;
 }
 
 /*----------------------------------------------------------------------------
index d61934f9515280f61b64a63c477473e5bdab851f..781178c2dcc3ae7a138239b59e6e660aa64d1f3d 100644 (file)
@@ -425,7 +425,12 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig,
              || (    ( zExp == 0xFD )
                   && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )
            ) {
+#ifdef SOFTFLOAT_68K
+            float_raise( float_flag_overflow, status );
+            if ( roundBits ) float_raise( float_flag_inexact, status );
+#else
             float_raise(float_flag_overflow | float_flag_inexact, status);
+#endif
             return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
         }
         if ( zExp < 0 ) {
@@ -441,9 +446,13 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig,
             shift32RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x7F;
+#ifdef SOFTFLOAT_68K
+            if ( isTiny ) float_raise( float_flag_underflow, status );
+#else
             if (isTiny && roundBits) {
                 float_raise(float_flag_underflow, status);
             }
+#endif
         }
     }
     if (roundBits) {
@@ -617,7 +626,12 @@ static float64 roundAndPackFloat64(flag zSign, int zExp, uint64_t zSig,
              || (    ( zExp == 0x7FD )
                   && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )
            ) {
+#ifdef SOFTFLOAT_68K
+                       float_raise( float_flag_overflow, status );
+            if ( roundBits ) float_raise( float_flag_inexact, status );
+#else
             float_raise(float_flag_overflow | float_flag_inexact, status);
+#endif
             return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
         }
         if ( zExp < 0 ) {
@@ -633,9 +647,13 @@ static float64 roundAndPackFloat64(flag zSign, int zExp, uint64_t zSig,
             shift64RightJamming( zSig, - zExp, &zSig );
             zExp = 0;
             roundBits = zSig & 0x3FF;
+#ifdef SOFTFLOAT_68K
+            if ( isTiny ) float_raise( float_flag_underflow, status );
+#else
             if (isTiny && roundBits) {
                 float_raise(float_flag_underflow, status);
             }
+#endif
         }
     }
     if (roundBits) {
@@ -839,10 +857,14 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
 #endif
             zExp = 0;
             roundBits = zSig0 & roundMask;
+#ifdef SOFTFLOAT_68K
+            if ( isTiny ) float_raise( float_flag_underflow, status );
+#else
             if (isTiny && roundBits) {
                 float_raise(float_flag_underflow, status);
             }
-            if (roundBits) {
+#endif
+if (roundBits) {
                 status->float_exception_flags |= float_flag_inexact;
             }
             zSig0 += roundIncrement;
@@ -903,8 +925,13 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
            ) {
             roundMask = 0;
  overflow:
+#ifndef SOFTFLOAT_68K
             float_raise(float_flag_overflow | float_flag_inexact, status);
-            if (    ( roundingMode == float_round_to_zero )
+#else
+            float_raise( float_flag_overflow, status );
+            if ( ( zSig0 & roundMask ) || zSig1 ) float_raise( float_flag_inexact, status );
+#endif
+                       if (    ( roundingMode == float_round_to_zero )
                  || ( zSign && ( roundingMode == float_round_up ) )
                  || ( ! zSign && ( roundingMode == float_round_down ) )
                ) {
@@ -933,9 +960,13 @@ floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
                        shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
 #endif
             zExp = 0;
+#ifdef SOFTFLOAT_68K
+            if ( isTiny ) float_raise( float_flag_underflow, status );
+#else
             if (isTiny && zSig1) {
                 float_raise(float_flag_underflow, status);
             }
+#endif
             if (zSig1) {
                 status->float_exception_flags |= float_flag_inexact;
             }
@@ -1019,7 +1050,8 @@ floatx80 roundAndPackFloatx80Sgl( flag zSign, int32_t zExp, uint64_t zSig0, uint
         if (    ( 0x7FFE < zExp )
             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
             ) {
-            float_raise( float_flag_overflow | float_flag_inexact, status );
+            float_raise( float_flag_overflow, status );
+                       if ( zSig0 & roundMask ) float_raise( float_flag_inexact, status );
             if (    ( roundingMode == float_round_to_zero )
                 || ( zSign && ( roundingMode == float_round_up ) )
                 || ( ! zSign && ( roundingMode == float_round_down ) )
@@ -1037,7 +1069,7 @@ floatx80 roundAndPackFloatx80Sgl( flag zSign, int32_t zExp, uint64_t zSig0, uint
             shift64RightJamming( zSig0, -zExp, &zSig0 );
             zExp = 0;
             roundBits = zSig0 & roundMask;
-            if ( isTiny && roundBits ) float_raise( float_flag_underflow, status );
+            if ( isTiny ) float_raise( float_flag_underflow, status );
             if ( roundBits ) status->float_exception_flags |= float_flag_inexact;
             if ( ( zSig0 & ~roundMask ) == 0 ) {
                 zSig0 = ( roundIncrement != roundMask );
index 3ec8ebc75d86e77adfd95992b765da975003369d..9d59a6e5e94b3b71bb364964b8ddbffa9a57b69c 100644 (file)
@@ -456,7 +456,7 @@ static inline int floatx80_is_any_nan(floatx80 a)
 *----------------------------------------------------------------------------*/
 static inline bool floatx80_invalid_encoding(floatx80 a)
 {
-    return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
+    return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0 && (a.high & 0x7FFF) != 0x7FFF;
 }
 
 #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)