Fix "ieee" FPU core on big endian and without long double > double support

- Handle conversions to/from host double for m68k long doubles formats
- Make mathlib aware of sizeof(long double) == sizeof(double) arches
- Attempt to fix FSCALE implementation
This commit is contained in:
gbeauche 2002-09-15 18:21:13 +00:00
parent 57e73de5f6
commit e59e4904d3
3 changed files with 234 additions and 174 deletions

View File

@ -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;

View File

@ -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

View File

@ -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