]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
FRESTORE updates and cleanups.
authorToni Wilen <twilen@winuae.net>
Wed, 19 Apr 2017 19:35:52 +0000 (22:35 +0300)
committerToni Wilen <twilen@winuae.net>
Wed, 19 Apr 2017 19:35:52 +0000 (22:35 +0300)
fpp.cpp
fpp_native.cpp
fpp_softfloat.cpp
softfloat/softfloat-specialize.h
softfloat/softfloat.h
softfloat/softfloat_decimal.cpp

diff --git a/fpp.cpp b/fpp.cpp
index 9e456ccd9f6f340868249abf6c06856fab1fef75..e0ac93fb92caa91539ea828368abeaa85438b845 100644 (file)
--- a/fpp.cpp
+++ b/fpp.cpp
@@ -2089,7 +2089,8 @@ static bool fp_arithmetic(fpdata *src, fpdata *dst, int extra);
 
 void fpuop_restore (uae_u32 opcode)
 {
-       int fpu_version = get_fpu_version (); // TODO: check version of stack frame
+       int fpu_version = get_fpu_version();
+       int frame_version;
        uaecptr pc = m68k_getpc () - 2;
        uae_u32 ad;
        uae_u32 d;
@@ -2117,6 +2118,8 @@ void fpuop_restore (uae_u32 opcode)
        d = x_get_long (ad);
        ad += 4;
 
+       frame_version = (d >> 24) & 0xff;
+
        if (currprefs.fpu_model == 68060) {
                int ff = (d >> 8) & 0xff;
                uae_u32 v = d & 0x7;
@@ -2148,7 +2151,7 @@ void fpuop_restore (uae_u32 opcode)
 
        } else if (currprefs.fpu_model == 68040) {
 
-               if ((d & 0xff000000) != 0) { // not null frame
+                if (frame_version == fpu_version) { // not null frame
                        uae_u32 frame_size = (d >> 16) & 0xff;
 
                        if (frame_size == 0x60) { // busy
@@ -2186,49 +2189,59 @@ void fpuop_restore (uae_u32 opcode)
                                
                                opclass = (cmdreg1b >> 13) & 0x7; // just to be sure
                                
-                               if (cusavepc == 0xFE && (opclass == 0 || opclass == 2)) {
-                                       fpp_to_exten_fmovem(&dst, fsave_data.fpt[0], fsave_data.fpt[1], fsave_data.fpt[2]);
-                                       fpp_denormalize(&dst, fpte15);
-                                       fpp_to_exten_fmovem(&src, fsave_data.et[0], fsave_data.et[1], fsave_data.et[2]);
-                                       fpp_denormalize(&src, et15);
+                               if (cusavepc == 0xFE) {
+                                       if (opclass == 0 || opclass == 2) {
+                                               fpp_to_exten_fmovem(&dst, fsave_data.fpt[0], fsave_data.fpt[1], fsave_data.fpt[2]);
+                                               fpp_denormalize(&dst, fpte15);
+                                               fpp_to_exten_fmovem(&src, fsave_data.et[0], fsave_data.et[1], fsave_data.et[2]);
+                                               fpp_denormalize(&src, et15);
 #if EXCEPTION_FPP
-                                       uae_u32 tmpsrc[3], tmpdst[3];
-                                       fpp_from_exten_fmovem(&src, &tmpsrc[0], &tmpsrc[1], &tmpsrc[2]);
-                                       fpp_from_exten_fmovem(&dst, &tmpdst[0], &tmpdst[1], &tmpdst[2]);
-                                       write_log (_T("FRESTORE src = %08X %08X %08X, dst = %08X %08X %08X, extra = %04X\n"),
-                                                          tmpsrc[0], tmpsrc[1], tmpsrc[2], tmpdst[0], tmpdst[1], tmpdst[2], cmdreg1b);
-#endif                                 
-                                       fpsr_clear_status();
-
-                                       v = fp_arithmetic(&src, &dst, cmdreg1b);
-                                       
-                                       if (v)
-                                               regs.fp[(cmdreg1b >> 7) & 7] = dst;
-
-                                       fpsr_check_arithmetic_exception(0, &src, regs.fp_opword, cmdreg1b, regs.fp_ea);
+                                               uae_u32 tmpsrc[3], tmpdst[3];
+                                               fpp_from_exten_fmovem(&src, &tmpsrc[0], &tmpsrc[1], &tmpsrc[2]);
+                                               fpp_from_exten_fmovem(&dst, &tmpdst[0], &tmpdst[1], &tmpdst[2]);
+                                               write_log (_T("FRESTORE src = %08X %08X %08X, dst = %08X %08X %08X, extra = %04X\n"),
+                                                                  tmpsrc[0], tmpsrc[1], tmpsrc[2], tmpdst[0], tmpdst[1], tmpdst[2], cmdreg1b);
+#endif
+                                               fpsr_clear_status();
+                                               
+                                               v = fp_arithmetic(&src, &dst, cmdreg1b);
+                                               
+                                               if (v)
+                                                       regs.fp[(cmdreg1b>>7)&7] = dst;
+                                               
+                                               fpsr_check_arithmetic_exception(0, &src, regs.fp_opword, cmdreg1b, regs.fp_ea);
+                                       } else {
+                                               write_log (_T("FRESTORE resume of opclass %d instruction not supported!\n"), opclass);
+                                       }
                                }
 
-                       } else if((frame_size == 0x30 || frame_size == 0x28)) { // unimp
+                       } else if (frame_size == 0x30 || frame_size == 0x28) { // unimp
 
                                // TODO: restore frame contents
                                ad += frame_size;
 
-                       } else if (frame_size != 0x00) { // not idle
-
-                               write_log (_T("FRESTORE invalid frame format %02X!\n"), frame_size);
+                       } else if (frame_size == 0x00) { // idle
+                               regs.fpu_state = 1;
+                               regs.fpu_exp_state = 0;
+                       } else {
+                               write_log (_T("FRESTORE invalid frame size %02X!\n"), frame_size);
 
                                Exception(14);
                                return;
 
                        }
-               } else { // null frame
+               } else if (frame_version == 0x00) { // null frame
                        fpu_null();
+               } else {
+                       write_log (_T("FRESTORE invalid frame version %02X!\n"), frame_version);
+                       Exception(14);
+                       return;
                }
 
        } else {
 
                // 6888x
-               if ((d & 0xff000000) != 0) { // not null frame
+               if (frame_version == fpu_version) { // not null frame
                        uae_u32 biu_flags;
                        uae_u32 frame_size = (d >> 16) & 0xff;
                        uae_u32 biu_offset = frame_size - 4;
@@ -2253,17 +2266,24 @@ void fpuop_restore (uae_u32 opcode)
                                if ((biu_flags & 0x08000000) == 0x00000000) {
                                        regs.fpu_exp_state = 2;
                                        regs.fp_exp_pend = fpsr_get_vector(regs.fpsr & regs.fpcr & 0xff00);
+                               } else {
+                                       regs.fpu_exp_state = 0;
+                                       regs.fp_exp_pend = 0;
                                }
                        } else if (frame_size == 0xB4 || frame_size == 0xD4) {
                                write_log (_T("FRESTORE of busy frame not supported\n"));
+                               ad += frame_size;
                        } else {
-                               write_log (_T("FRESTORE invalid frame format %02X!\n"), frame_size);
-
+                               write_log (_T("FRESTORE invalid frame size %02X!\n"), frame_size);
                                Exception(14);
                                return;
                        }
-               } else { // null frame
+               } else if (frame_version == 0x00) { // null frame
                        fpu_null();
+               } else {
+                       write_log (_T("FRESTORE invalid frame version %02X!\n"), frame_version);
+                       Exception(14);
+                       return;
                }
        }
 
@@ -2271,7 +2291,6 @@ void fpuop_restore (uae_u32 opcode)
                m68k_areg (regs, opcode & 7) = ad;
 
        fp_exception_pending(false);
-
 }
 
 static uaecptr fmovem2mem (uaecptr ad, uae_u32 list, int incr, int regdir)
index adda2fdcc689f4aee3d3736272ee9b521feacb3a..3e0a3229775b3c6a425431da2432e6a234d6d9d7 100644 (file)
@@ -46,63 +46,11 @@ double fp_1e8 = 1.0e8;
 float  fp_1e0 = 1, fp_1e1 = 10, fp_1e2 = 100, fp_1e4 = 10000;
 #endif
 
-static uae_u32 xhex_pi[]    ={0x2168c235, 0xc90fdaa2, 0x4000};
-static uae_u32 xhex_l2_e[]  ={0x5c17f0bc, 0xb8aa3b29, 0x3fff};
-static uae_u32 xhex_ln_2[]  ={0xd1cf79ac, 0xb17217f7, 0x3ffe};
-static uae_u32 xhex_inf[]   ={0x00000000, 0x00000000, 0x7fff};
-static uae_u32 xhex_nan[]   ={0xffffffff, 0xffffffff, 0x7fff};
-static uae_u32 xhex_snan[]  ={0xffffffff, 0xbfffffff, 0x7fff};
 #ifdef USE_LONG_DOUBLE
-static long double *fp_pi     = (long double *)xhex_pi;
-static long double *fp_exp_1  = (long double *)xhex_exp_1;
-static long double *fp_l2_e   = (long double *)xhex_l2_e;
-static long double *fp_ln_2   = (long double *)xhex_ln_2;
-static long double *fp_ln_10  = (long double *)xhex_ln_10;
-static long double *fp_l10_2  = (long double *)xhex_l10_2;
-static long double *fp_l10_e  = (long double *)xhex_l10_e;
-static long double *fp_1e16   = (long double *)xhex_1e16;
-static long double *fp_1e32   = (long double *)xhex_1e32;
-static long double *fp_1e64   = (long double *)xhex_1e64;
-static long double *fp_1e128  = (long double *)xhex_1e128;
-static long double *fp_1e256  = (long double *)xhex_1e256;
-static long double *fp_1e512  = (long double *)xhex_1e512;
-static long double *fp_1e1024 = (long double *)xhex_1e1024;
-static long double *fp_1e2048 = (long double *)xhex_1e2048;
-static long double *fp_1e4096 = (long double *)xhex_1e4096;
-static long double *fp_inf    = (long double *)xhex_inf;
+static uae_u32 xhex_nan[]   ={0xffffffff, 0xffffffff, 0x7fff};
 static long double *fp_nan    = (long double *)xhex_nan;
 #else
-static uae_u32 dhex_pi[]    ={0x54442D18, 0x400921FB};
-static uae_u32 dhex_exp_1[] ={0x8B145769, 0x4005BF0A};
-static uae_u32 dhex_l2_e[]  ={0x652B82FE, 0x3FF71547};
-static uae_u32 dhex_ln_2[]  ={0xFEFA39EF, 0x3FE62E42};
-static uae_u32 dhex_ln_10[] ={0xBBB55516, 0x40026BB1};
-static uae_u32 dhex_l10_2[] ={0x509F79FF, 0x3FD34413};
-static uae_u32 dhex_l10_e[] ={0x1526E50E, 0x3FDBCB7B};
-static uae_u32 dhex_1e16[]  ={0x37E08000, 0x4341C379};
-static uae_u32 dhex_1e32[]  ={0xB5056E17, 0x4693B8B5};
-static uae_u32 dhex_1e64[]  ={0xE93FF9F5, 0x4D384F03};
-static uae_u32 dhex_1e128[] ={0xF9301D32, 0x5A827748};
-static uae_u32 dhex_1e256[] ={0x7F73BF3C, 0x75154FDD};
-static uae_u32 dhex_inf[]   ={0x00000000, 0x7ff00000};
 static uae_u32 dhex_nan[]   ={0xffffffff, 0x7fffffff};
-static double *fp_pi     = (double *)dhex_pi;
-static double *fp_exp_1  = (double *)dhex_exp_1;
-static double *fp_l2_e   = (double *)dhex_l2_e;
-static double *fp_ln_2   = (double *)dhex_ln_2;
-static double *fp_ln_10  = (double *)dhex_ln_10;
-static double *fp_l10_2  = (double *)dhex_l10_2;
-static double *fp_l10_e  = (double *)dhex_l10_e;
-static double *fp_1e16   = (double *)dhex_1e16;
-static double *fp_1e32   = (double *)dhex_1e32;
-static double *fp_1e64   = (double *)dhex_1e64;
-static double *fp_1e128  = (double *)dhex_1e128;
-static double *fp_1e256  = (double *)dhex_1e256;
-static double *fp_1e512  = (double *)dhex_inf;
-static double *fp_1e1024 = (double *)dhex_inf;
-static double *fp_1e2048 = (double *)dhex_inf;
-static double *fp_1e4096 = (double *)dhex_inf;
-static double *fp_inf    = (double *)dhex_inf;
 static double *fp_nan    = (double *)dhex_nan;
 #endif
 static const double twoto32 = 4294967296.0;
index db611d602f6fae56fb3ec39dc17b39a62573707d..873e4f47749bfce449df7121c39fed7a2618ee7a 100644 (file)
@@ -285,14 +285,6 @@ static void fp_denormalize(fpdata *fpd, int esign)
 
 /* Functions for rounding */
 
-static floatx80 fp_to_sgl(floatx80 a)
-{
-       floatx80 v = floatx80_round32(a, &fs);
-       v.high &= 0x7fff;
-       v.high |= a.high & 0x7fff;
-       return v;
-}
-
 // round to float with extended precision exponent
 static void fp_round32(fpdata *fpd)
 {
@@ -317,6 +309,7 @@ static void fp_round_double(fpdata *fpd)
        fpd->fpx = floatx80_round_to_float64(fpd->fpx, &fs);
 }
 
+#if 0
 // round to selected precision
 static void fp_round(fpdata *a)
 {
@@ -331,6 +324,7 @@ static void fp_round(fpdata *a)
                break;
        }
 }
+#endif
 
 /* Arithmetic functions */
 
@@ -921,6 +915,7 @@ static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor)
                exponent = f.high & 0x3FFF;
                significand = f.low;
                
+               pack_int = 0;
                pack_frac = 0;
                len = kfactor; // SoftFloat saved len to kfactor variable
                while (len > 0) {
index 315debbbb8ae7f2255ba513c4f8caef407b072d8..8645142cb2fb03f8b5fc530ebdf03fabf119f76f 100644 (file)
@@ -285,6 +285,24 @@ static float64 propagateFloat64NaN( float64 a, float64 b, float_status *status )
     }
 
 }
+
+/*----------------------------------------------------------------------------
+| Returns 1 if the extended double-precision floating-point value `a' is a
+| signaling NaN; otherwise returns 0.
+*----------------------------------------------------------------------------*/
+
+static inline flag floatx80_is_signaling_nan( floatx80 a )
+{
+    uint64_t aLow;
+
+    aLow = a.low & ~ LIT64( 0x4000000000000000 );
+    return
+           ( ( a.high & 0x7FFF ) == 0x7FFF )
+        && (uint64_t) ( aLow<<1 )
+        && ( a.low == aLow );
+
+}
+
 /*----------------------------------------------------------------------------
 | Returns the result of converting the extended double-precision floating-
 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
@@ -370,23 +388,6 @@ static inline floatx80 propagateFloatx80NaNOneArg(floatx80 a, float_status *stat
 }
 #endif
 
-/*----------------------------------------------------------------------------
-| Returns 1 if the extended double-precision floating-point value `a' is a
-| signaling NaN; otherwise returns 0.
-*----------------------------------------------------------------------------*/
-
-static flag floatx80_is_signaling_nan( floatx80 a )
-{
-    uint64_t aLow;
-
-    aLow = a.low & ~ LIT64( 0x4000000000000000 );
-    return
-           ( ( a.high & 0x7FFF ) == 0x7FFF )
-        && (uint64_t) ( aLow<<1 )
-        && ( a.low == aLow );
-
-}
-
 // 28-12-2016: Added for Previous:
 
 /*----------------------------------------------------------------------------
index 3d18e89013445331aa32ccbb4c0fcd619d08fb98..ee89d11c7eb019902fd848585035c6c242b9c86d 100644 (file)
@@ -401,13 +401,6 @@ flag floatx80_le( floatx80, floatx80, float_status *status);
 flag floatx80_lt( floatx80, floatx80, float_status *status);
 
 #ifdef SOFTFLOAT_68K
-flag floatx80_is_zero( floatx80 );
-flag floatx80_is_infinity( floatx80 );
-flag floatx80_is_negative( floatx80 );
-flag floatx80_is_denormal( floatx80 );
-flag floatx80_is_unnormal( floatx80 );
-flag floatx80_is_normal( floatx80 );
-
 // functions are in softfloat.c
 floatx80 floatx80_move( floatx80 a, float_status *status );
 floatx80 floatx80_abs( floatx80 a, float_status *status );
@@ -448,9 +441,6 @@ void normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t *zSig
 floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig );
 floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status);
 
-// functions are in softfloat-specialize.h
-floatx80 propagateFloatx80NaNOneArg( floatx80 a, float_status *status );
-floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b, float_status *status );
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision operations.
 *----------------------------------------------------------------------------*/
@@ -460,7 +450,6 @@ floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
 floatx80 floatx80_mul(floatx80, floatx80, float_status *status);
 floatx80 floatx80_div(floatx80, floatx80, float_status *status);
 floatx80 floatx80_sqrt(floatx80, float_status *status);
-flag floatx80_is_signaling_nan(floatx80);
 floatx80 floatx80_normalize(floatx80);
 floatx80 floatx80_denormalize(floatx80, flag);
 
@@ -496,9 +485,4 @@ static inline bool floatx80_invalid_encoding(floatx80 a)
 #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL)
 #define floatx80_infinity make_floatx80(0x7fff, 0x8000000000000000LL)
 
-/*----------------------------------------------------------------------------
-| The pattern for a default generated extended double-precision NaN.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_default_nan(float_status *status);
-
 #endif /* SOFTFLOAT_H */
index 6436e27088b697bc1f90c73f02e5a08250ba5e17..2c0eb5a4d879bc2143510bad43dbfad5130064ca 100644 (file)
@@ -26,7 +26,7 @@ Arithmetic Package, Release 2a.
 | Methods for converting decimal floats to binary extended precision floats.
 *----------------------------------------------------------------------------*/
 
-void round128to64(flag aSign, int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, float_status *status)
+static void round128to64(flag aSign, int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, float_status *status)
 {
        flag increment;
        int32_t zExp;
@@ -66,7 +66,7 @@ void round128to64(flag aSign, int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, f
        *aSig1 = 0;
 }
 
-void mul128by128round(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1, float_status *status)
+static void mul128by128round(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1, float_status *status)
 {
        int32_t zExp;
        uint64_t zSig0, zSig1, zSig2, zSig3;
@@ -91,7 +91,7 @@ void mul128by128round(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t b
        round128to64(0, aExp, aSig0, aSig1, status);
 }
 
-void mul128by128(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1)
+static void mul128by128(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1)
 {
        int32_t zExp;
        uint64_t zSig0, zSig1, zSig2, zSig3;
@@ -112,7 +112,7 @@ void mul128by128(int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t bExp,
        *aSig1 = zSig1;
 }
 
-void div128by128(int32_t *paExp, uint64_t *paSig0, uint64_t *paSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1)
+static void div128by128(int32_t *paExp, uint64_t *paSig0, uint64_t *paSig1, int32_t bExp, uint64_t bSig0, uint64_t bSig1)
 {
        int32_t zExp, aExp;
        uint64_t zSig0, zSig1, aSig0, aSig1;
@@ -178,7 +178,7 @@ void tentoint128(flag mSign, flag eSign, int32_t *aExp, uint64_t *aSig0, uint64_
 
 #else
 
-void tentoint128(flag mSign, flag eSign, int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t scale, float_status *status)
+static void tentoint128(flag mSign, flag eSign, int32_t *aExp, uint64_t *aSig0, uint64_t *aSig1, int32_t scale, float_status *status)
  {
     int8_t save_rounding_mode;
     int32_t mExp;
@@ -230,7 +230,7 @@ void tentoint128(flag mSign, flag eSign, int32_t *aExp, uint64_t *aSig0, uint64_
 
 #endif
 
-int64_t tentointdec(int32_t scale)
+static int64_t tentointdec(int32_t scale)
 {
        uint64_t decM, decX;
         
@@ -249,7 +249,7 @@ int64_t tentointdec(int32_t scale)
 }
 
 
-int64_t float128toint64(flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status)
+static int64_t float128toint64(flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1, float_status *status)
 {
        int8_t roundingMode;
        flag roundNearestEven, increment;
@@ -280,7 +280,7 @@ int64_t float128toint64(flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1
        return z;
 }
 
-int32_t getDecimalExponent(int32_t aExp, uint64_t aSig)
+static int32_t getDecimalExponent(int32_t aExp, uint64_t aSig)
 {
        flag zSign;
        int32_t zExp, shiftCount;