From: Toni Wilen Date: Tue, 21 Mar 2017 19:17:45 +0000 (+0200) Subject: FPU cleanup. X-Git-Tag: 3500~77 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=6a86b4369f6496980172d87995095c0d489e76fc;p=francis%2Fwinuae.git FPU cleanup. --- diff --git a/fpp_softfloat.cpp b/fpp_softfloat.cpp index 04b8141a..b6779ee2 100644 --- a/fpp_softfloat.cpp +++ b/fpp_softfloat.cpp @@ -59,19 +59,19 @@ static void fp_set_mode(uae_u32 mode_control) } switch(mode_control & FPCR_ROUNDING_MODE) { - case FPCR_ROUND_NEAR: // to neareset - set_float_rounding_mode(float_round_nearest_even, &fs); - break; - case FPCR_ROUND_ZERO: // to zero - set_float_rounding_mode(float_round_to_zero, &fs); - break; - case FPCR_ROUND_MINF: // to minus - set_float_rounding_mode(float_round_down, &fs); - break; - case FPCR_ROUND_PINF: // to plus - set_float_rounding_mode(float_round_up, &fs); - break; - } + case FPCR_ROUND_NEAR: // to neareset + set_float_rounding_mode(float_round_nearest_even, &fs); + break; + case FPCR_ROUND_ZERO: // to zero + set_float_rounding_mode(float_round_to_zero, &fs); + break; + case FPCR_ROUND_MINF: // to minus + set_float_rounding_mode(float_round_down, &fs); + break; + case FPCR_ROUND_PINF: // to plus + set_float_rounding_mode(float_round_up, &fs); + break; + } } static void fp_get_status(uae_u32 *status) @@ -93,7 +93,7 @@ static void fp_get_status(uae_u32 *status) } STATIC_INLINE void fp_clear_status(void) { - fs.float_exception_flags = 0; + fs.float_exception_flags = 0; } @@ -112,7 +112,7 @@ static const TCHAR *fp_printx80(floatx80 *fx, int mode) n = floatx80_is_negative(*fx); u = floatx80_is_unnormal(*fx); d = floatx80_is_denormal(*fx); - + if (floatx80_is_zero(*fx)) { #if USE_LONG_DOUBLE _stprintf(fsout, _T("%c%#.17Le%s%s"), n?'-':'+', (fptype) 0.0, u ? _T("U") : _T(""), d ? _T("D") : _T("")); @@ -153,36 +153,36 @@ static const TCHAR *fp_print(fpdata *fpd, int mode) /* Functions for detecting float type */ static bool fp_is_snan(fpdata *fpd) { - return floatx80_is_signaling_nan(fpd->fpx) != 0; + return floatx80_is_signaling_nan(fpd->fpx) != 0; } static bool fp_unset_snan(fpdata *fpd) { - fpd->fpx.low |= LIT64(0x4000000000000000); + fpd->fpx.low |= LIT64(0x4000000000000000); return 0; } static bool fp_is_nan (fpdata *fpd) { - return floatx80_is_any_nan(fpd->fpx) != 0; + return floatx80_is_any_nan(fpd->fpx) != 0; } static bool fp_is_infinity (fpdata *fpd) { - return floatx80_is_infinity(fpd->fpx) != 0; + return floatx80_is_infinity(fpd->fpx) != 0; } static bool fp_is_zero(fpdata *fpd) { - return floatx80_is_zero(fpd->fpx) != 0; + return floatx80_is_zero(fpd->fpx) != 0; } static bool fp_is_neg(fpdata *fpd) { - return floatx80_is_negative(fpd->fpx) != 0; + return floatx80_is_negative(fpd->fpx) != 0; } static bool fp_is_denormal(fpdata *fpd) { - return floatx80_is_denormal(fpd->fpx) != 0; + return floatx80_is_denormal(fpd->fpx) != 0; } static bool fp_is_unnormal(fpdata *fpd) { - return floatx80_is_unnormal(fpd->fpx) != 0; + return floatx80_is_unnormal(fpd->fpx) != 0; } /* Functions for converting between float formats */ @@ -190,47 +190,47 @@ static const fptype twoto32 = 4294967296.0; static void to_native(fptype *fp, fpdata *fpd) { - int expon; - fptype frac; - - expon = fpd->fpx.high & 0x7fff; - - if (fp_is_zero(fpd)) { - *fp = fp_is_neg(fpd) ? -0.0 : +0.0; - return; - } - if (fp_is_nan(fpd)) { + int expon; + fptype frac; + + expon = fpd->fpx.high & 0x7fff; + + if (fp_is_zero(fpd)) { + *fp = fp_is_neg(fpd) ? -0.0 : +0.0; + return; + } + if (fp_is_nan(fpd)) { #if USE_LONG_DOUBLE - *fp = sqrtl(-1); + *fp = sqrtl(-1); #else - *fp = sqrt(-1); + *fp = sqrt(-1); #endif - return; - } - if (fp_is_infinity(fpd)) { + return; + } + if (fp_is_infinity(fpd)) { double zero = 0.0; #if USE_LONG_DOUBLE *fp = fp_is_neg(fpd) ? logl(0.0) : (1.0 / zero); #else *fp = fp_is_neg(fpd) ? log(0.0) : (1.0 / zero); #endif - return; - } - - frac = (fptype)fpd->fpx.low / (fptype)(twoto32 * 2147483648.0); - if (fp_is_neg(fpd)) - frac = -frac; + return; + } + + frac = (fptype)fpd->fpx.low / (fptype)(twoto32 * 2147483648.0); + if (fp_is_neg(fpd)) + frac = -frac; #if USE_LONG_DOUBLE - *fp = ldexpl (frac, expon - 16383); + *fp = ldexpl (frac, expon - 16383); #else - *fp = ldexp (frac, expon - 16383); + *fp = ldexp (frac, expon - 16383); #endif } static bool to_native_checked(fptype *fp, fpdata *fpd, fpdata *dst) { - uint64_t aSig = extractFloatx80Frac(fpd->fpx); - int32_t aExp = extractFloatx80Exp(fpd->fpx); + uint64_t aSig = extractFloatx80Frac(fpd->fpx); + int32_t aExp = extractFloatx80Exp(fpd->fpx); if (aExp == 0x7FFF && (uint64_t)(aSig << 1)) { dst->fpx = propagateFloatx80NaN(fpd->fpx, fpd->fpx, &fs); return true; @@ -241,74 +241,74 @@ static bool to_native_checked(fptype *fp, fpdata *fpd, fpdata *dst) static void from_native(fptype fp, fpdata *fpd) { - int expon; - fptype frac; - - if (signbit(fp)) - fpd->fpx.high = 0x8000; - else - fpd->fpx.high = 0x0000; - - if (isnan(fp)) { - fpd->fpx.high |= 0x7fff; - fpd->fpx.low = LIT64(0xffffffffffffffff); - return; - } - if (isinf(fp)) { - fpd->fpx.high |= 0x7fff; - fpd->fpx.low = LIT64(0x0000000000000000); - return; - } - if (fp == 0.0) { - fpd->fpx.low = LIT64(0x0000000000000000); - return; - } - if (fp < 0.0) - fp = -fp; - + int expon; + fptype frac; + + if (signbit(fp)) + fpd->fpx.high = 0x8000; + else + fpd->fpx.high = 0x0000; + + if (isnan(fp)) { + fpd->fpx.high |= 0x7fff; + fpd->fpx.low = LIT64(0xffffffffffffffff); + return; + } + if (isinf(fp)) { + fpd->fpx.high |= 0x7fff; + fpd->fpx.low = LIT64(0x0000000000000000); + return; + } + if (fp == 0.0) { + fpd->fpx.low = LIT64(0x0000000000000000); + return; + } + if (fp < 0.0) + fp = -fp; + #if USE_LONG_DOUBLE - frac = frexpl (fp, &expon); + frac = frexpl (fp, &expon); #else - frac = frexp (fp, &expon); + frac = frexp (fp, &expon); #endif - frac += 0.5 / (twoto32 * twoto32); - if (frac >= 1.0) { - frac /= 2.0; - expon++; - } - fpd->fpx.high |= (expon + 16383 - 1) & 0x7fff; - fpd->fpx.low = (uint64_t)(frac * (fptype)(twoto32 * twoto32)); - - while (!(fpd->fpx.low & LIT64( 0x8000000000000000))) { - if (fpd->fpx.high == 0) { - break; - } - fpd->fpx.low <<= 1; - fpd->fpx.high--; - } + frac += 0.5 / (twoto32 * twoto32); + if (frac >= 1.0) { + frac /= 2.0; + expon++; + } + fpd->fpx.high |= (expon + 16383 - 1) & 0x7fff; + fpd->fpx.low = (uint64_t)(frac * (fptype)(twoto32 * twoto32)); + + while (!(fpd->fpx.low & LIT64( 0x8000000000000000))) { + if (fpd->fpx.high == 0) { + break; + } + fpd->fpx.low <<= 1; + fpd->fpx.high--; + } } static void to_single(fpdata *fpd, uae_u32 wrd1) { float32 f = wrd1; - fpd->fpx = float32_to_floatx80_allowunnormal(f, &fs); + fpd->fpx = float32_to_floatx80_allowunnormal(f, &fs); } static uae_u32 from_single(fpdata *fpd) { - float32 f = floatx80_to_float32(fpd->fpx, &fs); - return f; + float32 f = floatx80_to_float32(fpd->fpx, &fs); + return f; } static void to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2) { - float64 f = ((float64)wrd1 << 32) | wrd2; - fpd->fpx = float64_to_floatx80_allowunnormal(f, &fs); + float64 f = ((float64)wrd1 << 32) | wrd2; + fpd->fpx = float64_to_floatx80_allowunnormal(f, &fs); } static void from_double(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2) { - float64 f = floatx80_to_float64(fpd->fpx, &fs); - *wrd1 = f >> 32; - *wrd2 = (uae_u32)f; + float64 f = floatx80_to_float64(fpd->fpx, &fs); + *wrd1 = f >> 32; + *wrd2 = (uae_u32)f; } static void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) @@ -343,11 +343,11 @@ static uae_s64 to_int(fpdata *src, int size) case 1: return floatx80_to_int16(src->fpx, &fs); case 2: return floatx80_to_int32(src->fpx, &fs); default: return 0; - } + } } static void from_int(fpdata *fpd, uae_s32 src) { - fpd->fpx = int32_to_floatx80(src); + fpd->fpx = int32_to_floatx80(src); } /* Functions for returning exception state data */ @@ -365,7 +365,7 @@ static void fp_get_internal_round_all(fpdata *fpd) } static void fp_get_internal_round(fpdata *fpd) { - fpd->fpx = getFloatInternalRoundedSome(); + fpd->fpx = getFloatInternalRoundedSome(); } static void fp_get_internal_round_exten(fpdata *fpd) { @@ -373,18 +373,18 @@ static void fp_get_internal_round_exten(fpdata *fpd) } static void fp_get_internal(fpdata *fpd) { - fpd->fpx = getFloatInternalUnrounded(); + fpd->fpx = getFloatInternalUnrounded(); } static uae_u32 fp_get_internal_grs(void) { - return (uae_u32)getFloatInternalGRS(); + return (uae_u32)getFloatInternalGRS(); } /* Functions for rounding */ static floatx80 fp_to_sgl(floatx80 a) { - floatx80 v = floatx80_round32(a, &fs); + floatx80 v = floatx80_round32(a, &fs); v.high &= 0x7fff; v.high |= a.high & 0x7fff; return v; @@ -393,13 +393,13 @@ static floatx80 fp_to_sgl(floatx80 a) // round to float with extended precision exponent static void fp_round32(fpdata *fpd) { - fpd->fpx = floatx80_round32(fpd->fpx, &fs); + fpd->fpx = floatx80_round32(fpd->fpx, &fs); } // round to double with extended precision exponent static void fp_round64(fpdata *fpd) { - fpd->fpx = floatx80_round64(fpd->fpx, &fs); + fpd->fpx = floatx80_round64(fpd->fpx, &fs); } // round to float @@ -433,122 +433,122 @@ static void fp_round(fpdata *a) static void fp_int(fpdata *a, fpdata *b) { - a->fpx = floatx80_round_to_int(b->fpx, &fs); + a->fpx = floatx80_round_to_int(b->fpx, &fs); } static void fp_intrz(fpdata *a, fpdata *b) { - a->fpx = floatx80_round_to_int_toward_zero(b->fpx, &fs); + a->fpx = floatx80_round_to_int_toward_zero(b->fpx, &fs); } static void fp_lognp1(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_lognp1_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = logl(a->fp + 1.0); - from_native(fpa, a); + to_native(&fpa, b); + fpa = logl(a->fp + 1.0); + from_native(fpa, a); } static void fp_sin(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_sin_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = sinl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = sinl(fpa); + from_native(fpa, a); } static void fp_tan(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_tan_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = tanl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = tanl(fpa); + from_native(fpa, a); } static void fp_logn(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_logn_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = logl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = logl(fpa); + from_native(fpa, a); } static void fp_log10(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_log10_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = log10l(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = log10l(fpa); + from_native(fpa, a); } static void fp_log2(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_log2_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = log2l(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = log2l(fpa); + from_native(fpa, a); } static void fp_cos(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_sin_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = cosl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = cosl(fpa); + from_native(fpa, a); } static void fp_getexp(fpdata *a, fpdata *b) { - a->fpx = floatx80_getexp(b->fpx, &fs); + a->fpx = floatx80_getexp(b->fpx, &fs); } static void fp_getman(fpdata *a, fpdata *b) { - a->fpx = floatx80_getman(b->fpx, &fs); + a->fpx = floatx80_getman(b->fpx, &fs); } static void fp_mod(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) { - a->fpx = floatx80_mod(a->fpx, b->fpx, q, s, &fs); + a->fpx = floatx80_mod(a->fpx, b->fpx, q, s, &fs); } static void fp_sgldiv(fpdata *a, fpdata *b) { - a->fpx = floatx80_sgldiv(a->fpx, b->fpx, &fs); + a->fpx = floatx80_sgldiv(a->fpx, b->fpx, &fs); } static void fp_sglmul(fpdata *a, fpdata *b) { - a->fpx = floatx80_sglmul(a->fpx, b->fpx, &fs); + a->fpx = floatx80_sglmul(a->fpx, b->fpx, &fs); } static void fp_rem(fpdata *a, fpdata *b, uae_u64 *q, uae_u8 *s) { - a->fpx = floatx80_rem(a->fpx, b->fpx, q, s, &fs); + a->fpx = floatx80_rem(a->fpx, b->fpx, q, s, &fs); } static void fp_scale(fpdata *a, fpdata *b) { - a->fpx = floatx80_scale(a->fpx, b->fpx, &fs); + a->fpx = floatx80_scale(a->fpx, b->fpx, &fs); } static void fp_cmp(fpdata *a, fpdata *b) { - a->fpx = floatx80_cmp(a->fpx, b->fpx, &fs); + a->fpx = floatx80_cmp(a->fpx, b->fpx, &fs); } static void fp_tst(fpdata *a, fpdata *b) { @@ -556,9 +556,9 @@ static void fp_tst(fpdata *a, fpdata *b) } #define SETPREC \ - uint8_t oldprec = fs.floatx80_rounding_precision; \ + uint8_t oldprec = fs.floatx80_rounding_precision; \ if (prec > 0) \ - set_floatx80_rounding_precision(prec, &fs); + set_floatx80_rounding_precision(prec, &fs); #define RESETPREC \ if (prec > 0) \ @@ -569,49 +569,49 @@ static void fp_tst(fpdata *a, fpdata *b) static void fp_move(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_move(b->fpx, &fs); + a->fpx = floatx80_move(b->fpx, &fs); RESETPREC } static void fp_abs(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_abs(b->fpx, &fs); + a->fpx = floatx80_abs(b->fpx, &fs); RESETPREC } static void fp_neg(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_neg(b->fpx, &fs); + a->fpx = floatx80_neg(b->fpx, &fs); RESETPREC } static void fp_add(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_add(a->fpx, b->fpx, &fs); + a->fpx = floatx80_add(a->fpx, b->fpx, &fs); RESETPREC } static void fp_sub(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_sub(a->fpx, b->fpx, &fs); + a->fpx = floatx80_sub(a->fpx, b->fpx, &fs); RESETPREC } static void fp_mul(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_mul(a->fpx, b->fpx, &fs); + a->fpx = floatx80_mul(a->fpx, b->fpx, &fs); RESETPREC } static void fp_div(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_div(a->fpx, b->fpx, &fs); + a->fpx = floatx80_div(a->fpx, b->fpx, &fs); RESETPREC } static void fp_sqrt(fpdata *a, fpdata *b, int prec) { SETPREC - a->fpx = floatx80_sqrt(b->fpx, &fs); + a->fpx = floatx80_sqrt(b->fpx, &fs); RESETPREC } @@ -620,134 +620,134 @@ static void fp_sqrt(fpdata *a, fpdata *b, int prec) static void fp_sinh(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_sinh_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = sinhl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = sinhl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_etoxm1(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_etoxm1_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = expl(fpa) - 1.0; - from_native(fpa, a); + to_native(&fpa, b); + fpa = expl(fpa) - 1.0; + from_native(fpa, a); fp_round(a); } static void fp_tanh(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_tanh_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = tanhl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = tanhl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_atan(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_atan_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = atanl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = atanl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_asin(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_asin_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = asinl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = asinl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_atanh(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_atanh_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = atanhl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = atanhl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_etox(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_etox_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = expl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = expl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_twotox(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_twotox_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = powl(2.0, fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = powl(2.0, fpa); + from_native(fpa, a); fp_round(a); } static void fp_tentox(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_tentox_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = powl(10.0, fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = powl(10.0, fpa); + from_native(fpa, a); fp_round(a); } static void fp_cosh(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_cosh_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = coshl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = coshl(fpa); + from_native(fpa, a); fp_round(a); } static void fp_acos(fpdata *a, fpdata *b) { - fptype fpa; + fptype fpa; flag e = 0; a->fpx = floatx80_acos_check(b->fpx, &e, &fs); if (e) return; - to_native(&fpa, b); - fpa = acosl(fpa); - from_native(fpa, a); + to_native(&fpa, b); + fpa = acosl(fpa); + from_native(fpa, a); fp_round(a); } @@ -758,9 +758,13 @@ static void fp_normalize(fpdata *a) static void fp_to_pack(fpdata *fp, uae_u32 *wrd, int dummy) { - uae_s32 exp = 0; - uae_s64 mant = 0; - + floatx80 f; + int i; + uae_s32 exp; + uae_s64 mant; + uae_u32 pack_exp, pack_int, pack_se, pack_sm; + uae_u64 pack_frac; + if (((wrd[0] >> 16) & 0x7fff) == 0x7fff) { // infinity has extended exponent and all 0 packed fraction // nans are copies bit by bit @@ -774,45 +778,36 @@ static void fp_to_pack(fpdata *fp, uae_u32 *wrd, int dummy) return; } - - int i; - - uae_u32 pack_exp = (wrd[0] >> 16) & 0xFFF; // packed exponent - uae_u32 pack_int = wrd[0] & 0xF; // packed integer part - uae_u64 pack_frac = ((uae_u64)wrd[1] << 32) | wrd[2]; // packed fraction - uae_u32 pack_se = (wrd[0] >> 30) & 1; // sign of packed exponent - uae_u32 pack_sm = (wrd[0] >> 31) & 1; // sign of packed significand - + pack_exp = (wrd[0] >> 16) & 0xFFF; // packed exponent + pack_int = wrd[0] & 0xF; // packed integer part + pack_frac = ((uae_u64)wrd[1] << 32) | wrd[2]; // packed fraction + pack_se = (wrd[0] >> 30) & 1; // sign of packed exponent + pack_sm = (wrd[0] >> 31) & 1; // sign of packed significand + exp = 0; for (i = 0; i < 3; i++) { exp *= 10; exp += (pack_exp >> (8 - i * 4)) & 0xF; } - if (pack_se) { exp = -exp; } - exp -= 16; - if (exp < 0) { exp = -exp; pack_se = 1; } - mant = pack_int; - for (i = 0; i < 16; i++) { mant *= 10; mant += (pack_frac >> (60 - i * 4)) & 0xF; } - floatx80 f; f.high = exp & 0x3FFF; f.high |= pack_se ? 0x4000 : 0; f.high |= pack_sm ? 0x8000 : 0; @@ -824,17 +819,13 @@ static void fp_to_pack(fpdata *fp, uae_u32 *wrd, int dummy) static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor) { - floatx80 f = floatx80_to_floatdecimal(fp->fpx, &kfactor, &fs); - - uae_u32 pack_exp = 0; // packed exponent - uae_u32 pack_exp4 = 0; - uae_u32 pack_int = 0; // packed integer part - uae_u64 pack_frac = 0; // packed fraction - uae_u32 pack_se = 0; // sign of packed exponent - uae_u32 pack_sm = 0; // sign of packed significand - - uae_u32 exponent; - uae_u64 significand; + floatx80 f = floatx80_to_floatdecimal(fp->fpx, &kfactor, &fs); + + uae_u32 pack_exp, pack_exp4, pack_int, pack_se, pack_sm; + uae_u64 pack_frac; + + uae_u32 exponent; + uae_u64 significand; uae_s32 len; uae_u64 digit; @@ -861,6 +852,7 @@ static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor) } pack_exp = 0; + pack_exp4 = 0; len = 4; while (len > 0) { len--; @@ -885,8 +877,6 @@ static void fp_from_pack(fpdata *fp, uae_u32 *wrd, int kfactor) wrd[1] = pack_frac >> 32; wrd[2] = pack_frac & 0xffffffff; } - - //printf("PACKED = %08x %08x %08x\n",wrd[0],wrd[1],wrd[2]); } void fp_init_softfloat(void) diff --git a/softfloat/softfloat_decimal.cpp b/softfloat/softfloat_decimal.cpp index 86956d03..6436e270 100644 --- a/softfloat/softfloat_decimal.cpp +++ b/softfloat/softfloat_decimal.cpp @@ -336,7 +336,7 @@ int32_t getDecimalExponent(int32_t aExp, uint64_t aSig) floatx80 floatdecimal_to_floatx80(floatx80 a, float_status *status) { - flag decSign, zSign, decExpSign, increment; + flag decSign, zSign, decExpSign; int32_t decExp, zExp, xExp, shiftCount; uint64_t decSig, zSig0, zSig1, xSig0, xSig1; @@ -365,31 +365,9 @@ floatx80 floatdecimal_to_floatx80(floatx80 a, float_status *status) mul128by128(&zExp, &zSig0, &zSig1, xExp, xSig0, xSig1); } - increment = ( (int64_t) zSig1 < 0 ); - if (status->float_rounding_mode != float_round_nearest_even) { - if (status->float_rounding_mode == float_round_to_zero) { - increment = 0; - } else { - if (zSign) { - increment = (status->float_rounding_mode == float_round_down) && zSig1; - } else { - increment = (status->float_rounding_mode == float_round_up) && zSig1; - } - } - } if (zSig1) float_raise(float_flag_decimal, status); + round128to64(zSign, &zExp, &zSig0, &zSig1, status); - if (increment) { - ++zSig0; - if (zSig0 == 0) { - ++zExp; - zSig0 = LIT64(0x8000000000000000); - } else { - zSig0 &= ~ (((uint64_t) (zSig1<<1) == 0) & (status->float_rounding_mode == float_round_nearest_even)); - } - } else { - if ( zSig0 == 0 ) zExp = 0; - } return packFloatx80( zSign, zExp, zSig0 ); }