Use old x87 FPU stack on x86-64 too because we now use long doubles there for

better accuracy. Aka. prefer compatibility over speed.
This commit is contained in:
gbeauche 2002-11-16 15:28:25 +00:00
parent bc5d7f9490
commit 144e6f4e87
8 changed files with 31 additions and 16 deletions

View File

@ -31,6 +31,16 @@
#include "sysdeps.h"
#include "fpu/types.h"
/* Always use x87 FPU stack on IA-32. */
#if defined(X86_ASSEMBLY)
#define USE_X87_ASSEMBLY 1
#endif
/* Only use x87 FPU on x86-64 if long double precision is requested. */
#if defined(X86_64_ASSEMBLY) && USE_LONG_DOUBLE
#define USE_X87_ASSEMBLY 1
#endif
/* ========================================================================== */
/* ========================= FPU CONTEXT DEFINITION ========================= */
/* ========================================================================== */
@ -150,8 +160,8 @@ struct fpu_t {
/* ---------------------------------------------------------------------- */
#if defined(FPU_X86) \
|| (defined(FPU_UAE) && defined(X86_ASSEMBLY)) \
|| (defined(FPU_IEEE) && defined(X86_ASSEMBLY))
|| (defined(FPU_UAE) && defined(USE_X87_ASSEMBLY)) \
|| (defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY))
#define CW_RESET 0x0040 // initial CW value after RESET
#define CW_FINIT 0x037F // initial CW value after FINIT

View File

@ -50,13 +50,13 @@
/* -------------------------------------------------------------------------- */
/* Optimized i386 fpu core must use native exceptions */
#if defined(FPU_X86) && defined(X86_ASSEMBLY)
#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_EXCEPTIONS
# define FPU_USE_X86_EXCEPTIONS
#endif
/* Optimized i386 fpu core must use native accrued exceptions */
#if defined(FPU_X86) && defined(X86_ASSEMBLY)
#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_ACCRUED_EXCEPTIONS
# define FPU_USE_X86_ACCRUED_EXCEPTIONS
#endif

View File

@ -49,13 +49,13 @@
/* -------------------------------------------------------------------------- */
/* Optimized i386 fpu core must use native flags */
#if defined(FPU_X86) && defined(X86_ASSEMBLY)
#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_FLAGS
# define FPU_USE_X86_FLAGS
#endif
/* Old UAE FPU core can use native flags */
#if defined(FPU_UAE) && defined(X86_ASSEMBLY)
#if defined(FPU_UAE) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_FLAGS
# define FPU_USE_X86_FLAGS
#endif
@ -67,7 +67,7 @@
#endif
/* JIT Compilation for FPU only works with lazy evaluation of FPU flags */
#if defined(FPU_IEEE) && defined(X86_ASSEMBLY) && defined(USE_JIT_FPU)
#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY) && defined(USE_JIT_FPU)
# undef FPU_USE_GENERIC_FLAGS
# define FPU_USE_LAZY_FLAGS
#endif

View File

@ -2105,7 +2105,7 @@ PUBLIC void FFPU fpu_init (bool integral_68040)
#if defined(FPU_USE_X86_ROUNDING)
// Initial state after boot, reset and frestore(null frame)
x86_control_word = CW_INITIAL;
#elif defined(__i386__) && defined(X86_ASSEMBLY)
#elif defined(USE_X87_ASSEMBLY)
volatile unsigned short int cw;
__asm__ __volatile__("fnstcw %0" : "=m" (cw));
cw &= ~0x0300; cw |= 0x0300; // CW_PC_EXTENDED

View File

@ -38,7 +38,7 @@
#undef FPU
#define FPU fpu.
#if defined(FPU_IEEE) && defined(X86_ASSEMBLY)
#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
PRIVATE fpu_extended fp_do_pow(fpu_extended x, fpu_extended y)
{

View File

@ -785,7 +785,7 @@ PRIVATE inline uae_u32 FFPU get_quotient_sign(fpu_register const & ra, fpu_regis
# define fp_ceil ceil
#endif
#if defined(FPU_IEEE) && defined(X86_ASSEMBLY)
#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
// Assembly optimized support functions. Taken from glibc 2.2.2
#undef fp_log
@ -1105,7 +1105,7 @@ DEFINE_ROUND_FUNC(zero, 0xc00)
DEFINE_ROUND_FUNC(nearest, 0x000)
#endif /* X86_ASSEMBLY */
#endif /* USE_X87_ASSEMBLY */
#ifndef fp_round_to_minus_infinity
#define fp_round_to_minus_infinity(x) fp_floor(x)

View File

@ -50,26 +50,26 @@
/* -------------------------------------------------------------------------- */
/* Optimized i386 fpu core must use native rounding mode */
#if defined(FPU_X86) && defined(X86_ASSEMBLY)
#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_ROUNDING_MODE
# define FPU_USE_X86_ROUNDING_MODE
#endif
/* Optimized i386 fpu core must use native rounding precision */
#if defined(FPU_X86) && defined(X86_ASSEMBLY)
#if defined(FPU_X86) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_ROUNDING_PRECISION
# define FPU_USE_X86_ROUNDING_PRECISION
#endif
#if 0 // gb-- FIXME: that doesn't work
/* IEEE-based fpu core can have native rounding mode on i386 */
#if defined(FPU_IEEE) && defined(X86_ASSEMBLY)
#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_ROUNDING_MODE
# define FPU_USE_X86_ROUNDING_MODE
#endif
/* IEEE-based fpu core can have native rounding precision on i386 */
#if defined(FPU_IEEE) && defined(X86_ASSEMBLY)
#if defined(FPU_IEEE) && defined(USE_X87_ASSEMBLY)
# undef FPU_USE_GENERIC_ROUNDING_PRECISION
# define FPU_USE_X86_ROUNDING_PRECISION
#endif

View File

@ -133,7 +133,12 @@ typedef long double uae_f64;
typedef long double uae_f96;
typedef uae_f96 fpu_register;
#define USE_LONG_DOUBLE 1
#elif (SIZEOF_LONG_DOUBLE == 16) && 0
#elif SIZEOF_LONG_DOUBLE == 16 && defined(__x86_64__)
/* Long doubles on x86-64 are really held in old x87 FPU stack. */
typedef long double uae_f128;
typedef uae_f128 fpu_register;
#define USE_LONG_DOUBLE 1
#elif 0
/* Disable for now and probably for good as (i) the emulator
implementation is not correct, (ii) I don't know of any CPU which
handles this kind of format *natively* with conformance to IEEE. */