From a25869115a7298f1a0a2870c28352c1e6612fddd Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Wed, 19 Apr 2017 22:35:52 +0300 Subject: [PATCH] FRESTORE updates and cleanups. --- fpp.cpp | 81 ++++++++++++++++++++------------ fpp_native.cpp | 54 +-------------------- fpp_softfloat.cpp | 11 ++--- softfloat/softfloat-specialize.h | 35 +++++++------- softfloat/softfloat.h | 16 ------- softfloat/softfloat_decimal.cpp | 16 +++---- 6 files changed, 80 insertions(+), 133 deletions(-) diff --git a/fpp.cpp b/fpp.cpp index 9e456ccd..e0ac93fb 100644 --- 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) diff --git a/fpp_native.cpp b/fpp_native.cpp index adda2fdc..3e0a3229 100644 --- a/fpp_native.cpp +++ b/fpp_native.cpp @@ -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; diff --git a/fpp_softfloat.cpp b/fpp_softfloat.cpp index db611d60..873e4f47 100644 --- a/fpp_softfloat.cpp +++ b/fpp_softfloat.cpp @@ -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) { diff --git a/softfloat/softfloat-specialize.h b/softfloat/softfloat-specialize.h index 315debbb..8645142c 100644 --- a/softfloat/softfloat-specialize.h +++ b/softfloat/softfloat-specialize.h @@ -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: /*---------------------------------------------------------------------------- diff --git a/softfloat/softfloat.h b/softfloat/softfloat.h index 3d18e890..ee89d11c 100644 --- a/softfloat/softfloat.h +++ b/softfloat/softfloat.h @@ -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 */ diff --git a/softfloat/softfloat_decimal.cpp b/softfloat/softfloat_decimal.cpp index 6436e270..2c0eb5a4 100644 --- a/softfloat/softfloat_decimal.cpp +++ b/softfloat/softfloat_decimal.cpp @@ -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; -- 2.47.3