diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp index f825ef0d..714077fa 100644 --- a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp +++ b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp @@ -264,66 +264,61 @@ PRIVATE inline uae_u32 FFPU extract_single(fpu_register const & src) // to_exten PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) { -#if 1 - // FIXME: USE_QUAD_DOUBLE - fpu_extended result; + // is it zero? + if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) + return 0.0; + + fpu_register result; +#ifndef USE_LONG_DOUBLE + uae_u32 sgn = (wrd1 >> 31) & 1; + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + + // the explicit integer bit is not set, must normalize + if ((wrd2 & 0x80000000) == 0) { + fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3)); + if (wrd2 | wrd3) { + // mantissa, not fraction. + uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; + while (exp > 0 && (man & UVAL64(0x8000000000000000)) == 0) { + man <<= 1; + exp--; + } + wrd2 = (uae_u32)(man >> 32); + wrd3 = (uae_u32)(man & 0xFFFFFFFF); + } + else if (exp != 0x7fff) // zero + exp = FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; + } + + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + + fp_declare_init_shape(srp, result, double); + srp->ieee.negative = sgn; + srp->ieee.exponent = exp; + // drop the explicit integer bit + srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; + srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); +#elif USE_QUAD_DOUBLE + fp_declare_init_shape(srp, result, extended); + srp->ieee.negative = (wrd1 >> 31) & 1; + srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; + srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff; + srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff); + srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16; +#else fp_declare_init_shape(srp, result, extended); srp->ieee.negative = (wrd1 >> 31) & 1; srp->ieee.exponent = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX; srp->ieee.mantissa0 = wrd2; srp->ieee.mantissa1 = wrd3; +#endif fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); return result; -#elif 0 /* original code */ - if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) - return 0.0; - - fpu_register result; - uae_u32 *p = (uae_u32 *)&result; - - uae_u32 sign = wrd1 & 0x80000000; - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - - // The explicit integer bit is not set, must normalize. - if((wrd2 & 0x80000000) == 0) { - fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3)); - if( wrd2 | wrd3 ) { - // mantissa, not fraction. - uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3; - while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) { - man <<= 1; - exp--; - } - wrd2 = (uae_u32)( man >> 32 ); - wrd3 = (uae_u32)( man & 0xFFFFFFFF ); - } else { - if(exp == 0x7FFF) { - // Infinity. - } else { - // Zero - exp = 16383 - 1023; - } - } - } - - if(exp < 16383 - 1023) { - // should set underflow. - exp = 0; - } else if(exp > 16383 + 1023) { - // should set overflow. - exp = 2047; - } else { - exp = exp + 1023 - 16383; - } - - // drop the explicit integer bit. - p[FLO] = (wrd2 << 21) | (wrd3 >> 11); - p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11); - - fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); - - return(result); -#endif } /* @@ -335,48 +330,40 @@ PRIVATE inline void FFPU make_extended_no_normalize( uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result ) { -#if 1 + // is it zero? + if ((wrd1 && 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { + make_zero_positive(result); + return; + } + // is it NaN? + if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) { + make_nan(result); + return; + } +#ifndef USE_LONG_DOUBLE + uae_u32 exp = (wrd1 >> 16) & 0x7fff; + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + + fp_declare_init_shape(srp, result, double); + srp->ieee.negative = (wrd1 >> 31) & 1; + srp->ieee.exponent = exp; + // drop the explicit integer bit + srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11; + srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11); +#else // FIXME: USE_QUAD_DOUBLE fp_declare_init_shape(srp, result, extended); srp->ieee.negative = (wrd1 & 0x80000000) != 0; srp->ieee.exponent = (wrd1 >> 16) & 0x7fff; srp->ieee.mantissa0 = wrd2; srp->ieee.mantissa1 = wrd3; -#elif 0 /* original code */ - // Is it zero? - if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) { - make_zero_positive(result); - return; - } - - // Is it NaN? - if( (wrd1 & 0x7FFF0000) == 0x7FFF0000 ) { - if( (wrd1 & 0x0000FFFF) || wrd2 || wrd3 ) { - make_nan(result); - return; - } - } - - uae_u32 sign = wrd1 & 0x80000000; - uae_u32 exp = (wrd1 >> 16) & 0x7fff; - - if(exp < 16383 - 1023) { - // should set underflow. - exp = 0; - } else if(exp > 16383 + 1023) { - // should set overflow. - exp = 2047; - } else { - exp = exp + 1023 - 16383; - } - - // drop the explicit integer bit. - uae_u32 *p = (uae_u32 *)&result; - p[FLO] = (wrd2 << 21) | (wrd3 >> 11); - p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11); - - fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(float)(*(double *)p))); #endif + fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result)); } // from_exten @@ -384,40 +371,40 @@ PRIVATE inline void FFPU extract_extended(fpu_register const & src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3 ) { -#if 1 - // FIXME: USE_QUAD_DOUBLE and non little-endian specificities - uae_u32 *p = (uae_u32 *)&src; - *wrd3 = p[0]; - *wrd2 = p[1]; - *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16; - fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); -#elif 0 /* original code */ if (src == 0.0) { *wrd1 = *wrd2 = *wrd3 = 0; return; } - - uae_u32 *p = (uae_u32 *)&src; - - fpu_debug(("extract_extended (%X,%X)\n",p[FLO],p[FHI])); +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(srp, src, double); + fpu_debug(("extract_extended (%d,%d,%X,%X)\n", + srp->ieee.negative , srp->ieee.exponent, + srp->ieee.mantissa0, srp->ieee.mantissa1)); - uae_u32 sign = p[FHI] & 0x80000000; + uae_u32 exp = srp->ieee.exponent; - uae_u32 exp = ((p[FHI] >> 20) & 0x7ff); - // Check for maximum - if(exp == 0x7FF) { - exp = 0x7FFF; - } else { - exp += 16383 - 1023; - } + if (exp == FP_DOUBLE_EXP_MAX) + exp = FP_EXTENDED_EXP_MAX; + else + exp += FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS; - *wrd1 = sign | (exp << 16); + *wrd1 = (srp->ieee.negative << 31) | (exp << 16); // always set the explicit integer bit. - *wrd2 = 0x80000000 | ((p[FHI] & 0x000FFFFF) << 11) | ((p[FLO] & 0xFFE00000) >> 21); - *wrd3 = p[FLO] << 11; - - fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); + *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 11) | ((srp->ieee.mantissa1 & 0xffe00000) >> 21); + *wrd3 = srp->ieee.mantissa1 << 11; +#else + // FIXME: USE_QUAD_DOUBLE +#ifdef WORDS_BIGENDIAN + *wrd1 = p[0]; + *wrd2 = p[1]; + *wrd3 = p[2]; +#else + *wrd3 = p[0]; + *wrd2 = p[1]; + *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16; #endif +#endif + fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3)); } // to_double @@ -425,7 +412,7 @@ PRIVATE inline fpu_register FFPU make_double(uae_u32 wrd1, uae_u32 wrd2) { union { fpu_double value; - uae_u32 parts[2]; + uae_u32 parts[2]; } dest; #ifdef WORDS_BIGENDIAN dest.parts[0] = wrd1; @@ -445,7 +432,7 @@ PRIVATE inline void FFPU extract_double(fpu_register const & src, { union { fpu_double value; - uae_u32 parts[2]; + uae_u32 parts[2]; } dest; dest.value = (fpu_double)src; #ifdef WORDS_BIGENDIAN @@ -1989,18 +1976,32 @@ void FFPU fpuop_arithmetic(uae_u32 opcode, uae_u32 extra) case 0x26: /* FSCALE */ fpu_debug(("FSCALE %.04f\n",(double)src)); - - // TODO: - // Overflow, underflow - - if( isinf(FPU registers[reg]) ) { - make_nan( FPU registers[reg] ); - } - else { + // TODO: overflow flags + get_dest_flags(FPU registers[reg]); + get_source_flags(src); + if (fl_source.in_range && fl_dest.in_range) { // When the absolute value of the source operand is >= 2^14, // an overflow or underflow always results. // Here (int) cast is okay. - fast_scale( FPU registers[reg], (int)fp_round_to_zero(src) ); + int scale_factor = (int)fp_round_to_zero(src); +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, FPU registers[reg], double); + uae_u32 exp = sxp->ieee.exponent + scale_factor; + if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS) + exp = 0; + else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS) + exp = FP_DOUBLE_EXP_MAX; + else + exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS; + sxp->ieee.exponent = exp; +#else + fp_declare_init_shape(sxp, FPU registers[reg], extended); + sxp->ieee.exponent += scale_factor; +#endif + } + else if (fl_source.infinity) { + // Returns NaN for any Infinity source + make_nan( FPU registers[reg] ); } make_fpsr(FPU registers[reg]); break; diff --git a/BasiliskII/src/uae_cpu/fpu/mathlib.h b/BasiliskII/src/uae_cpu/fpu/mathlib.h index 514d6ae6..3c11abb7 100644 --- a/BasiliskII/src/uae_cpu/fpu/mathlib.h +++ b/BasiliskII/src/uae_cpu/fpu/mathlib.h @@ -187,17 +187,20 @@ union fpu_double_shape { # endif #endif } ieee_nan; + + /* This format is used to extract the sign_exponent and mantissa parts only */ + struct { +#if UAE_FLOAT_WORD_ORDER == UAE_BIG_ENDIAN + unsigned int msw:32; + unsigned int lsw:32; +#else + unsigned int lsw:32; + unsigned int msw:32; +#endif + } parts; }; -#if SIZEOF_LONG_DOUBLE == 12 -# undef USE_QUAD_DOUBLE -#elif SIZEOF_LONG_DOUBLE == 16 -# define USE_QUAD_DOUBLE -#else -# error "unsupported long double format" -#endif - -#ifndef USE_QUAD_DOUBLE +#ifdef USE_LONG_DOUBLE // IEEE-854 long double format union fpu_extended_shape { fpu_extended value; @@ -275,7 +278,9 @@ union fpu_extended_shape { #endif } parts; }; -#else +#endif + +#ifdef USE_QUAD_DOUBLE // IEEE-854 quad double format union fpu_extended_shape { fpu_extended value; @@ -345,7 +350,7 @@ union fpu_extended_shape { } parts32; #endif }; -#endif // !USE_QUAD_DOUBLE +#endif // Declare and initialize a pointer to a shape of the requested FP type #define fp_declare_init_shape(psvar, rfvar, ftype) \ @@ -365,9 +370,17 @@ union fpu_extended_shape { PRIVATE inline bool FFPU fp_do_isnan(fpu_register const & r) { - fp_declare_init_shape(sxp, r, extended); #ifdef BRANCHES_ARE_EXPENSIVE -#ifdef USE_QUAD_DOUBLE +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + uae_s32 hx = sxp->parts.msw; + uae_s32 lx = sxp->parts.lsw; + hx &= 0x7fffffff; + hx |= (uae_u32)(lx | (-lx)) >> 31; + hx = 0x7ff00000 - hx; + return (int)(((uae_u32)hx) >> 31); +#elif USE_QUAD_DOUBLE + fp_declare_init_shape(sxp, r, extended); uae_s64 hx = sxp->parts64.msw; uae_s64 lx = sxp->parts64.lsw; hx &= 0x7fffffffffffffffLL; @@ -375,6 +388,7 @@ PRIVATE inline bool FFPU fp_do_isnan(fpu_register const & r) hx = 0x7fff000000000000LL - hx; return (int)((uae_u64)hx >> 63); #else + fp_declare_init_shape(sxp, r, extended); uae_s32 se = sxp->parts.sign_exponent; uae_s32 hx = sxp->parts.msw; uae_s32 lx = sxp->parts.lsw; @@ -386,7 +400,13 @@ PRIVATE inline bool FFPU fp_do_isnan(fpu_register const & r) return (int)(((uae_u32)(se)) >> 16); #endif #else +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + return (sxp->ieee_nan.exponent == FP_DOUBLE_EXP_MAX) +#else + fp_declare_init_shape(sxp, r, extended); return (sxp->ieee_nan.exponent == FP_EXTENDED_EXP_MAX) +#endif && (sxp->ieee_nan.mantissa0 != 0) && (sxp->ieee_nan.mantissa1 != 0) #ifdef USE_QUAD_DOUBLE @@ -406,15 +426,23 @@ PRIVATE inline bool FFPU fp_do_isnan(fpu_register const & r) PRIVATE inline bool FFPU fp_do_isinf(fpu_register const & r) { - fp_declare_init_shape(sxp, r, extended); #ifdef BRANCHES_ARE_EXPENSIVE -#ifdef USE_QUAD_DOUBLE +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + uae_s32 hx = sxp->parts.msw; + uae_s32 lx = sxp->parts.lsw; + lx |= (hx & 0x7fffffff) ^ 0x7ff00000; + lx |= -lx; + return ~(lx >> 31) & (hx >> 30); +#elif USE_QUAD_DOUBLE + fp_declare_init_shape(sxp, r, extended); uae_s64 hx = sxp->parts64.msw; uae_s64 lx = sxp->parts64.lsw; lx |= (hx & 0x7fffffffffffffffLL) ^ 0x7fff000000000000LL; lx |= -lx; return ~(lx >> 63) & (hx >> 62); #else + fp_declare_init_shape(sxp, r, extended); uae_s32 se = sxp->parts.sign_exponent; uae_s32 hx = sxp->parts.msw; uae_s32 lx = sxp->parts.lsw; @@ -431,7 +459,13 @@ PRIVATE inline bool FFPU fp_do_isinf(fpu_register const & r) return ~(lx >> 31) & (1 - (se >> 14)); #endif #else +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + return (sxp->ieee_nan.exponent == FP_DOUBLE_EXP_MAX) +#else + fp_declare_init_shape(sxp, r, extended); return (sxp->ieee_nan.exponent == FP_EXTENDED_EXP_MAX) +#endif && (sxp->ieee_nan.mantissa0 == 0) && (sxp->ieee_nan.mantissa1 == 0) #ifdef USE_QUAD_DOUBLE @@ -447,9 +481,12 @@ PRIVATE inline bool FFPU fp_do_isinf(fpu_register const & r) PRIVATE inline bool FFPU fp_do_isneg(fpu_register const & r) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); +#else fp_declare_init_shape(sxp, r, extended); - return (sxp->ieee.negative) - ; +#endif + return sxp->ieee.negative; } #undef iszero @@ -458,7 +495,11 @@ PRIVATE inline bool FFPU fp_do_isneg(fpu_register const & r) PRIVATE inline bool FFPU fp_do_iszero(fpu_register const & r) { // TODO: BRANCHES_ARE_EXPENSIVE +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); +#else fp_declare_init_shape(sxp, r, extended); +#endif return (sxp->ieee.exponent == 0) && (sxp->ieee.mantissa0 == 0) && (sxp->ieee.mantissa1 == 0) @@ -490,9 +531,15 @@ PRIVATE inline void FFPU get_source_flags(fpu_register const & r) PRIVATE inline void FFPU make_nan(fpu_register & r) { // FIXME: is that correct ? +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + sxp->ieee.exponent = FP_DOUBLE_EXP_MAX; + sxp->ieee.mantissa0 = 0xfffff; +#else fp_declare_init_shape(sxp, r, extended); sxp->ieee.exponent = FP_EXTENDED_EXP_MAX; sxp->ieee.mantissa0 = 0xffffffff; +#endif sxp->ieee.mantissa1 = 0xffffffff; #ifdef USE_QUAD_DOUBLE sxp->ieee.mantissa2 = 0xffffffff; @@ -504,8 +551,12 @@ PRIVATE inline void FFPU make_zero_positive(fpu_register & r) { #if 1 r = +0.0; +#else +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); #else fp_declare_init_shape(sxp, r, extended); +#endif sxp->ieee.negative = 0; sxp->ieee.exponent = 0; sxp->ieee.mantissa0 = 0; @@ -521,8 +572,12 @@ PRIVATE inline void FFPU make_zero_negative(fpu_register & r) { #if 1 r = -0.0; +#else +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); #else fp_declare_init_shape(sxp, r, extended); +#endif sxp->ieee.negative = 1; sxp->ieee.exponent = 0; sxp->ieee.mantissa0 = 0; @@ -536,9 +591,14 @@ PRIVATE inline void FFPU make_zero_negative(fpu_register & r) PRIVATE inline void FFPU make_inf_positive(fpu_register & r) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + sxp->ieee_nan.exponent = FP_DOUBLE_EXP_MAX; +#else fp_declare_init_shape(sxp, r, extended); - sxp->ieee_nan.negative = 0; sxp->ieee_nan.exponent = FP_EXTENDED_EXP_MAX; +#endif + sxp->ieee_nan.negative = 0; sxp->ieee_nan.mantissa0 = 0; sxp->ieee_nan.mantissa1 = 0; #ifdef USE_QUAD_DOUBLE @@ -549,9 +609,14 @@ PRIVATE inline void FFPU make_inf_positive(fpu_register & r) PRIVATE inline void FFPU make_inf_negative(fpu_register & r) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + sxp->ieee_nan.exponent = FP_DOUBLE_EXP_MAX; +#else fp_declare_init_shape(sxp, r, extended); - sxp->ieee_nan.negative = 1; sxp->ieee_nan.exponent = FP_EXTENDED_EXP_MAX; +#endif + sxp->ieee_nan.negative = 1; sxp->ieee_nan.mantissa0 = 0; sxp->ieee_nan.mantissa1 = 0; #ifdef USE_QUAD_DOUBLE @@ -560,54 +625,48 @@ PRIVATE inline void FFPU make_inf_negative(fpu_register & r) #endif } -PRIVATE inline void FFPU fast_scale(fpu_register & r, int add) -{ - fp_declare_init_shape(sxp, r, extended); - // TODO: overflow flags - int exp = sxp->ieee.exponent + add; - // FIXME: this test is not correct: see fpuop_fscale() - if (exp > FP_EXTENDED_EXP_BIAS) { - make_inf_positive(r); - } else if (exp < 0) { - // keep sign (+/- 0) - if (isneg(r)) - make_inf_negative(r); - else - make_inf_positive(r); -// p[FHI] &= 0x80000000; - } else { - sxp->ieee.exponent = exp; -// p[FHI] = (p[FHI] & 0x800FFFFF) | ((uae_u32)exp << 20); - } -} - PRIVATE inline fpu_register FFPU fast_fgetexp(fpu_register const & r) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + return (sxp->ieee.exponent - FP_DOUBLE_EXP_BIAS); +#else fp_declare_init_shape(sxp, r, extended); return (sxp->ieee.exponent - FP_EXTENDED_EXP_BIAS); +#endif } // Normalize to range 1..2 PRIVATE inline void FFPU fast_remove_exponent(fpu_register & r) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sxp, r, double); + sxp->ieee.exponent = FP_DOUBLE_EXP_BIAS; +#else fp_declare_init_shape(sxp, r, extended); sxp->ieee.exponent = FP_EXTENDED_EXP_BIAS; +#endif } // The sign of the quotient is the exclusive-OR of the sign bits // of the source and destination operands. PRIVATE inline uae_u32 FFPU get_quotient_sign(fpu_register const & ra, fpu_register const & rb) { +#ifndef USE_LONG_DOUBLE + fp_declare_init_shape(sap, ra, double); + fp_declare_init_shape(sbp, rb, double); +#else fp_declare_init_shape(sap, ra, extended); fp_declare_init_shape(sbp, rb, extended); - return (((sap->ieee.mantissa0 ^ sbp->ieee.mantissa0) & 0x80000000) ? 0x800000 : 0); +#endif + return ((sap->ieee.negative ^ sbp->ieee.negative) ? FPSR_QUOTIENT_SIGN : 0); } /* -------------------------------------------------------------------------- */ /* --- Math functions --- */ /* -------------------------------------------------------------------------- */ -#if FPU_USE_ISO_C99 +#if FPU_USE_ISO_C99 && USE_LONG_DOUBLE # define fp_log logl # define fp_log10 log10l # define fp_exp expl diff --git a/BasiliskII/src/uae_cpu/fpu/types.h b/BasiliskII/src/uae_cpu/fpu/types.h index 3e11e14e..1423a87c 100644 --- a/BasiliskII/src/uae_cpu/fpu/types.h +++ b/BasiliskII/src/uae_cpu/fpu/types.h @@ -31,7 +31,8 @@ #include "sysdeps.h" /* Default behavior is *not* to use long doubles */ -#define USE_LONG_DOUBLE 0 +#undef USE_LONG_DOUBLE +#undef USE_QUAD_DOUBLE /* -------------------------------------------------------------------------- */ /* --- Original UAE fpu core --- */ @@ -127,21 +128,20 @@ typedef long double uae_f64; #if SIZEOF_LONG_DOUBLE == 12 typedef long double uae_f96; typedef uae_f96 fpu_register; +#define USE_LONG_DOUBLE 1 #elif SIZEOF_LONG_DOUBLE == 16 typedef long double uae_f128; typedef uae_f128 fpu_register; +#define USE_LONG_DOUBLE 1 +#define USE_QUAD_DOUBLE 1 #else -#error "No float type bigger than 8 bytes, you lose." +typedef uae_f64 fpu_register; #endif -/* We *do* use long doubles for the IEEE-based FPE */ -#undef USE_LONG_DOUBLE -#define USE_LONG_DOUBLE 1 - /* We need all those floating-point types */ typedef fpu_register fpu_extended; -typedef uae_f64 fpu_double; -typedef uae_f32 fpu_single; +typedef uae_f64 fpu_double; +typedef uae_f32 fpu_single; #endif