diff --git a/src/cpu/codegen.c b/src/cpu/codegen.c index cd12b43bc..f633243ca 100644 --- a/src/cpu/codegen.c +++ b/src/cpu/codegen.c @@ -27,3 +27,10 @@ void codegen_timing_set(codegen_timing_t *timing) } int codegen_in_recompile; + +/* This is for compatibility with new x87 code. */ +void codegen_set_rounding_mode(int mode) +{ + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); +} diff --git a/src/cpu/codegen_ops_x86-64.h b/src/cpu/codegen_ops_x86-64.h index 6d1fc188c..178f0f868 100644 --- a/src/cpu/codegen_ops_x86-64.h +++ b/src/cpu/codegen_ops_x86-64.h @@ -4182,7 +4182,7 @@ static inline void FP_FCHS() addbyte(0x64); addbyte(0x05); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ addbyte(0x0f); addbyte(0x11); @@ -4435,7 +4435,7 @@ static inline void FP_OP_REG(int op, int dst, int src) addbyte(0x64); addbyte(0x05); addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); if (op == FPU_DIVR || op == FPU_SUBR) { addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ @@ -4528,7 +4528,7 @@ static inline void FP_OP_MEM(int op) addbyte(0x64); addbyte(0x05); addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); switch (op) { diff --git a/src/cpu/codegen_ops_x86.h b/src/cpu/codegen_ops_x86.h index 13ca37c4c..5dcfdef87 100644 --- a/src/cpu/codegen_ops_x86.h +++ b/src/cpu/codegen_ops_x86.h @@ -2686,7 +2686,7 @@ static inline void FP_OP_S(int op) addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xd8); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2710,7 +2710,7 @@ static inline void FP_OP_S(int op) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xd8); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2743,7 +2743,7 @@ static inline void FP_OP_D(int op) addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2783,7 +2783,7 @@ static inline void FP_OP_D(int op) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2813,7 +2813,7 @@ static inline void FP_OP_IW(int op) addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xde); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2837,7 +2837,7 @@ static inline void FP_OP_IW(int op) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xde); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2860,7 +2860,7 @@ static inline void FP_OP_IL(int op) addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xda); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2884,7 +2884,7 @@ static inline void FP_OP_IL(int op) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xda); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2912,7 +2912,7 @@ static inline void FP_OP_IQ(int op) addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -2940,7 +2940,7 @@ static inline void FP_OP_IQ(int op) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); @@ -3243,7 +3243,7 @@ static inline void FP_OP_REG(int op, int dst, int src) addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); @@ -3275,7 +3275,7 @@ static inline void FP_OP_REG(int op, int dst, int src) addbyte(0x64); addbyte(0x1d); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD ST[EAX*8]*/ addbyte(0x44 | op); addbyte(0xc5); @@ -3295,7 +3295,7 @@ static inline void FP_OP_REG(int op, int dst, int src) addbyte(0x64); addbyte(0x05); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdc); /*FADD ST[EBX*8]*/ addbyte(0x44 | op); addbyte(0xdd); @@ -3411,7 +3411,7 @@ static inline void FP_FCHS() addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); @@ -3430,7 +3430,7 @@ static inline void FP_FCHS() addbyte(0x64); addbyte(0x05); addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(~TAG_UINT64); + addbyte(TAG_NOT_UINT64); addbyte(0xd9); /*FCHS*/ addbyte(0xe0); addbyte(0xdd); /*FSTP ST[EAX*8]*/ diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index 91e3b9655..037c377a6 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -1497,7 +1497,7 @@ void codegen_block_start_recompile(codeblock_t *block) cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - block->TOP = cpu_state.TOP; + block->TOP = cpu_state.TOP & 7; block->was_recompiled = 1; codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); diff --git a/src/cpu_common/386_common.c b/src/cpu_common/386_common.c index 888d24fd5..f3ba15edb 100644 --- a/src/cpu_common/386_common.c +++ b/src/cpu_common/386_common.c @@ -1663,9 +1663,9 @@ syscall(uint32_t fetchdat) { uint16_t seg_data[4]; -// #ifdef ENABLE_386_COMMON_LOG - pclog("SYSCALL called\n"); -// #endif +#ifdef ENABLE_386_COMMON_LOG + x386_common_log("SYSCALL called\n"); +#endif if (!(cr0 & 1)) { x86gpf("SYSCALL: CPU not in protected mode", 0); @@ -1723,9 +1723,9 @@ sysret(uint32_t fetchdat) { uint16_t seg_data[4]; -// #ifdef ENABLE_386_COMMON_LOG - pclog("SYSRET called\n"); -// #endif +#ifdef ENABLE_386_COMMON_LOG + x386_common_log("SYSRET called\n"); +#endif if (!AMD_SYSRET_SB) { x86gpf("SYSRET: CS MSR is zero", 0); diff --git a/src/cpu_common/x87.c b/src/cpu_common/x87.c index 23bc3f74c..148172aab 100644 --- a/src/cpu_common/x87.c +++ b/src/cpu_common/x87.c @@ -37,7 +37,6 @@ fpu_log(const char *fmt, ...) #endif -#ifdef USE_NEW_DYNAREC #define X87_TAG_VALID 0 #define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 @@ -79,35 +78,6 @@ void x87_settag(uint16_t new_tag) cpu_state.tag[c] = TAG_VALID; } } -#else -uint16_t x87_gettag() -{ - uint16_t ret = 0; - int c; - - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else - ret |= (cpu_state.tag[c] << (c*2)); - } - - return ret; -} - -void x87_settag(uint16_t new_tag) -{ - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; -} -#endif #ifdef ENABLE_808X_LOG diff --git a/src/cpu_common/x87.h b/src/cpu_common/x87.h index cb7751fe6..3d240960b 100644 --- a/src/cpu_common/x87.h +++ b/src/cpu_common/x87.h @@ -6,53 +6,38 @@ uint32_t x87_pc_off,x87_op_off; uint16_t x87_pc_seg,x87_op_seg; -static inline void x87_set_mmx() +static __inline void x87_set_mmx() { -#ifdef USE_NEW_DYNAREC - cpu_state.TOP = 0; - *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; - cpu_state.ismmx = 1; -#else uint64_t *p; cpu_state.TOP = 0; p = (uint64_t *)cpu_state.tag; - *p = 0; + *p = 0x0101010101010101ull; cpu_state.ismmx = 1; -#endif } -static inline void x87_emms() +static __inline void x87_emms() { -#ifdef USE_NEW_DYNAREC - *(uint64_t *)cpu_state.tag = 0; - cpu_state.ismmx = 0; -#else uint64_t *p; p = (uint64_t *)cpu_state.tag; *p = 0; cpu_state.ismmx = 0; -#endif } uint16_t x87_gettag(); void x87_settag(uint16_t new_tag); -#ifdef USE_NEW_DYNAREC #define TAG_EMPTY 0 #define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #define TAG_UINT64 (1 << 7) +/*Old dynarec stuff.*/ +#define TAG_NOT_UINT64 0x7f + #define X87_ROUNDING_NEAREST 0 #define X87_ROUNDING_DOWN 1 #define X87_ROUNDING_UP 2 #define X87_ROUNDING_CHOP 3 void codegen_set_rounding_mode(int mode); -#else -#define TAG_EMPTY 3 -#define TAG_VALID (1 << 0) -/*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ -#define TAG_UINT64 (1 << 2) -#endif diff --git a/src/cpu_common/x87_ops.h b/src/cpu_common/x87_ops.h index b1975e2d6..ac304c190 100644 --- a/src/cpu_common/x87_ops.h +++ b/src/cpu_common/x87_ops.h @@ -8,7 +8,7 @@ * * x87 FPU instructions core. * - * + * Version: @(#)x87_ops.h 1.0.8 2019/06/11 * * Authors: Fred N. van Kempen, * Sarah Walker, @@ -25,7 +25,6 @@ #ifdef _MSC_VER # include #endif -// #include "x87_timings.h" #ifdef ENABLE_FPU_LOG extern void fpu_log(const char *fmt, ...); @@ -39,6 +38,11 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ #define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + #define STATUS_ZERODIVIDE 4 #ifdef FPU_8087 @@ -90,13 +94,11 @@ static __inline void x87_push(double i) { #ifdef USE_NEW_DYNAREC cpu_state.TOP--; - cpu_state.ST[cpu_state.TOP&7] = i; - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; #else cpu_state.TOP=(cpu_state.TOP-1)&7; - cpu_state.ST[cpu_state.TOP] = i; - cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; #endif + cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } static __inline void x87_push_u64(uint64_t i) @@ -111,60 +113,32 @@ static __inline void x87_push_u64(uint64_t i) #ifdef USE_NEW_DYNAREC cpu_state.TOP--; - cpu_state.ST[cpu_state.TOP&7] = td.d; - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; #else cpu_state.TOP=(cpu_state.TOP-1)&7; - cpu_state.ST[cpu_state.TOP] = td.d; - cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? 1 : 0; #endif + cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; } static __inline double x87_pop() { -#ifdef USE_NEW_DYNAREC double t = cpu_state.ST[cpu_state.TOP&7]; cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; +#ifdef USE_NEW_DYNAREC cpu_state.TOP++; - return t; #else - double t = cpu_state.ST[cpu_state.TOP]; - cpu_state.tag[cpu_state.TOP&7] = 3; cpu_state.TOP=(cpu_state.TOP+1)&7; - return t; #endif + return t; } -static int old_round = FE_TONEAREST; - -static __inline void x87_round_save(void) -{ - old_round = fegetround(); -} - -static __inline void x87_round_set(void) -{ - old_round = fegetround(); - - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); -} - -static __inline void x87_round_restore(void) -{ - fesetround(old_round); -} - -#ifdef PCEM_CODE static __inline int64_t x87_fround(double b) { -#ifdef PCEM_CODE int64_t a, c; -#endif switch ((cpu_state.npxc >> 10) & 3) { case 0: /*Nearest*/ -#ifdef PCEM_CODE a = (int64_t)floor(b); c = (int64_t)floor(b + 1.0); if ((b - a) < (c - b)) @@ -173,35 +147,16 @@ static __inline int64_t x87_fround(double b) return c; else return (a & 1) ? c : a; -#else - return (int64_t)round(b); -#endif case 1: /*Down*/ return (int64_t)floor(b); case 2: /*Up*/ return (int64_t)ceil(b); case 3: /*Chop*/ -#ifdef PCEM_CODE return (int64_t)b; -#else - return (int64_t)trunc(b); -#endif } - - return 0; -} -#else -static __inline int64_t x87_fround(double b) -{ - int64_t ret; - x87_round_set(); - ret = (int64_t) rint(b); - x87_round_restore(); - - return ret; + return 0LL; } -#endif #define BIAS80 16383 #define BIAS64 1023 @@ -212,7 +167,6 @@ static __inline double x87_ld80() int64_t exp64final; int64_t mant64; int64_t sign; - struct { int16_t begin; union @@ -221,7 +175,6 @@ static __inline double x87_ld80() uint64_t ll; } eind; } test; - test.eind.ll = readmeml(easeg,cpu_state.eaaddr); test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; test.begin = readmemw(easeg,cpu_state.eaaddr+8); @@ -310,7 +263,6 @@ static __inline void x87_ld_frstor(int reg) cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); -#ifdef USE_NEW_DYNAREC if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) { cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; @@ -320,15 +272,6 @@ static __inline void x87_ld_frstor(int reg) cpu_state.tag[reg] &= ~TAG_UINT64; cpu_state.ST[reg] = x87_ld80(); } -#else - if (cpu_state.MM_w4[reg] == 0x5555 && cpu_state.tag[reg] == 2) - { - cpu_state.tag[reg] = TAG_UINT64; - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } - else - cpu_state.ST[reg] = x87_ld80(); -#endif } static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) @@ -411,7 +354,7 @@ static __inline uint16_t x87_compare(double a, double b) static __inline uint16_t x87_ucompare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_AMD64 || defined __amd64__ +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__ uint32_t result; #ifndef _MSC_VER @@ -483,56 +426,6 @@ typedef union } while (0) #endif -#ifdef USE_NEW_DYNAREC -#define FP_CHECKTOP64 cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64 -#define FP_TAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; -#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; -#define FP_LSTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; -#define FP_LSQ() cpu_state.MM[cpu_state.TOP&7].q = temp64; -#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP&7].q; -#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; -#ifdef USE_NEW_DYNAREC -#define FP_NNPXC() codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); -#else -#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); -#endif -#define FP_TOP(x) (x & 7) -#define FP_DTAG 0ULL -#define FP_CTAG 0x0101010101010101ull -#define FP_EMPTY TAG_EMPTY -#ifdef USE_NEW_DYNAREC -#define FP_RNPXC() codegen_set_rounding_mode(X87_ROUNDING_NEAREST); -#else -#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); -#endif -#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; -#define FP_DECTOP() cpu_state.TOP--; -#define FP_INCTOP() cpu_state.TOP++; -#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) -#define FP_686 -#endif -#else -#define FP_CHECKTOP64 cpu_state.tag[cpu_state.TOP] & TAG_UINT64 -#define FP_TAG() cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; -#define FP_FTAG() cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64; -#define FP_LSTAG() cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; -#define FP_LSQ() cpu_state.MM[cpu_state.TOP].q = temp64; -#define FP_LSRETQ() temp64 = cpu_state.MM[cpu_state.TOP].q; -#define FP_NTAG() cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64; -#define FP_NNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); -#define FP_TOP(x) (x) -#define FP_DTAG 0x0303030303030303ll -#define FP_CTAG 0ULL -#define FP_EMPTY 3 -#define FP_RNPXC() cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); -#define FP_ZTAG() cpu_state.tag[cpu_state.TOP&7] = 1; -#define FP_DECTOP() cpu_state.TOP = (cpu_state.TOP - 1) & 7 -#define FP_INCTOP() cpu_state.TOP = (cpu_state.TOP + 1) & 7 -#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) -#define FP_686 -#endif -#endif - #include "x87_ops_arith.h" #include "x87_ops_misc.h" #include "x87_ops_loadstore.h" @@ -1171,7 +1064,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) const OpFn OP_TABLE(fpu_686_da_a16)[256] = { opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -1404,7 +1297,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) const OpFn OP_TABLE(fpu_686_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, @@ -1977,7 +1870,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; -#if defined(USE_NEW_DYNAREC) || (defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))) +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) const OpFn OP_TABLE(fpu_686_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, diff --git a/src/cpu_common/x87_ops_arith.h b/src/cpu_common/x87_ops_arith.h index e90761ca1..13427fbc6 100644 --- a/src/cpu_common/x87_ops_arith.h +++ b/src/cpu_common/x87_ops_arith.h @@ -4,12 +4,14 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ ST(0) += use_var; \ - x87_round_restore(); \ - FP_TAG(); \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(FE_TONEAREST); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -18,7 +20,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ @@ -30,7 +32,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ cpu_state.npxs &= ~(C0|C2|C3); \ cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ @@ -43,12 +45,10 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ x87_div(ST(0), ST(0), use_var); \ - x87_round_restore(); \ - FP_TAG(); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -57,12 +57,10 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ x87_div(ST(0), use_var, ST(0)); \ - x87_round_restore(); \ - FP_TAG(); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(73); \ return 0; \ } \ @@ -71,12 +69,10 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ ST(0) *= use_var; \ - x87_round_restore(); \ - FP_TAG(); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(11); \ return 0; \ } \ @@ -85,12 +81,10 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ ST(0) -= use_var; \ - x87_round_restore(); \ - FP_TAG(); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } \ @@ -99,12 +93,10 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ optype t; \ FP_ENTER(); \ fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ load_var = get(); if (cpu_state.abrt) return 1; \ - x87_round_set(); \ ST(0) = use_var - ST(0); \ - x87_round_restore(); \ - FP_TAG(); \ + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ CLOCK_CYCLES(8); \ return 0; \ } @@ -129,14 +121,12 @@ opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t) #endif - - static int opFADD(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) + ST(fetchdat & 7); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -145,7 +135,7 @@ static int opFADDr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -154,7 +144,7 @@ static int opFADDP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; @@ -213,7 +203,7 @@ static int opFUCOMPP(uint32_t fetchdat) return 0; } -#ifdef FP_686 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) static int opFCOMI(uint32_t fetchdat) { FP_ENTER(); @@ -245,7 +235,7 @@ static int opFDIV(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(0), ST(fetchdat & 7)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -254,7 +244,7 @@ static int opFDIVr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -263,7 +253,7 @@ static int opFDIVP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(73); return 0; @@ -274,7 +264,7 @@ static int opFDIVR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(0), ST(fetchdat&7), ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -283,7 +273,7 @@ static int opFDIVRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(73); return 0; } @@ -292,7 +282,7 @@ static int opFDIVRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(73); return 0; @@ -303,7 +293,7 @@ static int opFMUL(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) * ST(fetchdat & 7); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(16); return 0; } @@ -312,7 +302,7 @@ static int opFMULr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(16); return 0; } @@ -321,7 +311,7 @@ static int opFMULP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(16); return 0; @@ -332,7 +322,7 @@ static int opFSUB(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(0) - ST(fetchdat & 7); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -341,7 +331,7 @@ static int opFSUBr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -350,7 +340,7 @@ static int opFSUBP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; @@ -361,7 +351,7 @@ static int opFSUBR(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = ST(fetchdat & 7) - ST(0); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -370,7 +360,7 @@ static int opFSUBRr(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; CLOCK_CYCLES(8); return 0; } @@ -379,7 +369,7 @@ static int opFSUBRP(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_FTAG(); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(8); return 0; @@ -407,7 +397,7 @@ static int opFUCOMP(uint32_t fetchdat) return 0; } -#ifdef FP_686 +#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) static int opFUCOMI(uint32_t fetchdat) { FP_ENTER(); diff --git a/src/cpu_common/x87_ops_loadstore.h b/src/cpu_common/x87_ops_loadstore.h index a4fa12ec4..fa33171c8 100644 --- a/src/cpu_common/x87_ops_loadstore.h +++ b/src/cpu_common/x87_ops_loadstore.h @@ -8,7 +8,7 @@ * * x87 FPU instructions core. * - * + * Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11 * * Author: Sarah Walker, * Miran Grca, @@ -21,7 +21,7 @@ static int opFILDiw_a16(uint32_t fetchdat) int16_t temp; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); CLOCK_CYCLES(13); @@ -33,7 +33,7 @@ static int opFILDiw_a32(uint32_t fetchdat) int16_t temp; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); temp = geteaw(); if (cpu_state.abrt) return 1; x87_push((double)temp); CLOCK_CYCLES(13); @@ -98,11 +98,11 @@ static int opFILDiq_a16(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - FP_LSQ(); - FP_LSTAG(); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; @@ -113,11 +113,11 @@ static int opFILDiq_a32(uint32_t fetchdat) int64_t temp64; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); temp64 = geteaq(); if (cpu_state.abrt) return 1; x87_push((double)temp64); - FP_LSQ(); - FP_LSTAG(); + cpu_state.MM[cpu_state.TOP&7].q = temp64; + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64; CLOCK_CYCLES(10); return 0; @@ -185,8 +185,8 @@ static int FISTPiq_a16(uint32_t fetchdat) FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - if (FP_CHECKTOP64) - FP_LSRETQ() + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; @@ -201,8 +201,8 @@ static int FISTPiq_a32(uint32_t fetchdat) FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - if (FP_CHECKTOP64) - FP_LSRETQ() + if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP&7].q; else temp64 = x87_fround(ST(0)); seteaq(temp64); if (cpu_state.abrt) return 1; @@ -217,7 +217,7 @@ static int opFILDil_a16(uint32_t fetchdat) int32_t templ; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); CLOCK_CYCLES(9); @@ -229,7 +229,7 @@ static int opFILDil_a32(uint32_t fetchdat) int32_t templ; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); templ = geteal(); if (cpu_state.abrt) return 1; x87_push((double)templ); CLOCK_CYCLES(9); @@ -294,7 +294,7 @@ static int opFLDe_a16(uint32_t fetchdat) double t; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); t=x87_ld80(); if (cpu_state.abrt) return 1; x87_push(t); CLOCK_CYCLES(6); @@ -354,7 +354,7 @@ static int opFLDd_a32(uint32_t fetchdat) x87_td t; FP_ENTER(); fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); t.i = geteaq(); if (cpu_state.abrt) return 1; x87_push(t.d); CLOCK_CYCLES(3); @@ -419,7 +419,7 @@ static int opFLDs_a16(uint32_t fetchdat) x87_ts ts; FP_ENTER(); fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(cpu_state.ea_seg); ts.i = geteal(); if (cpu_state.abrt) return 1; x87_push((double)ts.s); CLOCK_CYCLES(3); diff --git a/src/cpu_common/x87_ops_misc.h b/src/cpu_common/x87_ops_misc.h index 406c6c86d..2145a245e 100644 --- a/src/cpu_common/x87_ops_misc.h +++ b/src/cpu_common/x87_ops_misc.h @@ -48,10 +48,10 @@ static int opFINIT(uint32_t fetchdat) #else cpu_state.npxc = 0x37F; #endif - FP_RNPXC(); + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = FP_DTAG; + *p = 0; cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); @@ -64,7 +64,7 @@ static int opFFREE(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; CLOCK_CYCLES(3); return 0; } @@ -73,7 +73,7 @@ static int opFFREEP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = FP_EMPTY; if (cpu_state.abrt) return 1; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; x87_pop(); CLOCK_CYCLES(3); return 0; @@ -112,7 +112,7 @@ static int FSTOR() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -121,7 +121,7 @@ static int FSTOR() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -140,10 +140,10 @@ static int FSTOR() cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ - p = (uint64_t *)cpu_state.tag; + p = (uint64_t *) cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == FP_CTAG)) + !cpu_state.TOP && (*p == 0x0101010101010101ull)) cpu_state.ismmx = 1; CLOCK_CYCLES((cr0 & 1) ? 34 : 44); @@ -173,7 +173,7 @@ static int FSAVE() uint64_t *p; FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (FP_TOP(cpu_state.TOP) << 11); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { @@ -305,10 +305,10 @@ static int FSAVE() } cpu_state.npxc = 0x37F; - FP_RNPXC(); + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); cpu_state.npxs = 0; p = (uint64_t *)cpu_state.tag; - *p = FP_DTAG; + *p = 0; cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -339,7 +339,7 @@ static int opFSTSW_a16(uint32_t fetchdat) FP_ENTER(); fetch_ea_16(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -349,7 +349,7 @@ static int opFSTSW_a32(uint32_t fetchdat) FP_ENTER(); fetch_ea_32(fetchdat); SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | (FP_TOP(cpu_state.TOP) << 11)); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); CLOCK_CYCLES(3); return cpu_state.abrt; } @@ -366,8 +366,8 @@ static int opFLD(uint32_t fetchdat) old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; x87_push(ST(fetchdat&7)); - cpu_state.tag[FP_TOP(cpu_state.TOP)] = old_tag; - cpu_state.MM[FP_TOP(cpu_state.TOP)].q = old_i64; + cpu_state.tag[cpu_state.TOP&7] = old_tag; + cpu_state.MM[cpu_state.TOP&7].q = old_i64; CLOCK_CYCLES(4); return 0; } @@ -382,11 +382,11 @@ static int opFXCH(uint32_t fetchdat) td = ST(0); ST(0) = ST(fetchdat&7); ST(fetchdat&7) = td; - old_tag = cpu_state.tag[FP_TOP(cpu_state.TOP)]; - cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_tag = cpu_state.tag[cpu_state.TOP&7]; + cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[FP_TOP(cpu_state.TOP)].q; - cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + old_i64 = cpu_state.MM[cpu_state.TOP&7].q; + cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; CLOCK_CYCLES(4); @@ -398,7 +398,7 @@ static int opFCHS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = -ST(0); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(6); return 0; } @@ -408,7 +408,7 @@ static int opFABS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = fabs(ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(3); return 0; } @@ -429,7 +429,7 @@ static int opFXAM(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; cpu_state.npxs &= ~(C0|C1|C2|C3); - if (cpu_state.tag[cpu_state.TOP&7] == FP_EMPTY) cpu_state.npxs |= (C0|C3); + if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3); else if (ST(0) == 0.0) cpu_state.npxs |= C3; else cpu_state.npxs |= C2; if (ST(0) < 0.0) cpu_state.npxs |= C1; @@ -496,7 +496,7 @@ static int opFLDZ(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; x87_push(0.0); - FP_ZTAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(4); return 0; } @@ -506,7 +506,7 @@ static int opF2XM1(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = pow(2.0, ST(0)) - 1.0; - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(200); return 0; } @@ -516,7 +516,7 @@ static int opFYL2X(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - FP_NTAG(); + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -526,8 +526,8 @@ static int opFYL2XP1(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0)); - FP_NTAG(); + ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -538,7 +538,7 @@ static int opFPTAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = tan(ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(1.0); cpu_state.npxs &= ~C2; CLOCK_CYCLES(235); @@ -550,7 +550,7 @@ static int opFPATAN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(1) = atan2(ST(1), ST(0)); - FP_NTAG(); + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; x87_pop(); CLOCK_CYCLES(250); return 0; @@ -560,7 +560,11 @@ static int opFDECSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - FP_DECTOP(); +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; +#else + cpu_state.TOP = (cpu_state.TOP - 1) & 7; +#endif CLOCK_CYCLES(4); return 0; } @@ -569,7 +573,11 @@ static int opFINCSTP(uint32_t fetchdat) { FP_ENTER(); cpu_state.pc++; - FP_INCTOP(); +#ifdef USE_NEW_DYNAREC + cpu_state.TOP++; +#else + cpu_state.TOP = (cpu_state.TOP + 1) & 7; +#endif CLOCK_CYCLES(4); return 0; } @@ -581,7 +589,7 @@ static int opFPREM(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -597,7 +605,7 @@ static int opFPREM1(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)(ST(0) / ST(1)); ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~(C0|C1|C2|C3); if (temp64 & 4) cpu_state.npxs|=C0; if (temp64 & 2) cpu_state.npxs|=C3; @@ -612,7 +620,7 @@ static int opFSQRT(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sqrt(ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(83); return 0; } @@ -625,7 +633,7 @@ static int opFSINCOS(uint32_t fetchdat) cpu_state.pc++; td = ST(0); ST(0) = sin(td); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; x87_push(cos(td)); cpu_state.npxs &= ~C2; CLOCK_CYCLES(330); @@ -635,18 +643,10 @@ static int opFSINCOS(uint32_t fetchdat) static int opFRNDINT(uint32_t fetchdat) { - double rounded; FP_ENTER(); cpu_state.pc++; - rounded = (double) x87_fround(ST(0)); -#ifndef PCEM_CODE - if (rounded > ST(0)) - cpu_state.npxs |= C1; - else - cpu_state.npxs &= ~C1; -#endif - ST(0) = rounded; - FP_TAG(); + ST(0) = (double)x87_fround(ST(0)); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(21); return 0; } @@ -658,7 +658,7 @@ static int opFSCALE(uint32_t fetchdat) cpu_state.pc++; temp64 = (int64_t)ST(1); ST(0) = ST(0) * pow(2.0, (double)temp64); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; CLOCK_CYCLES(30); return 0; } @@ -669,7 +669,7 @@ static int opFSIN(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = sin(ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -680,7 +680,7 @@ static int opFCOS(uint32_t fetchdat) FP_ENTER(); cpu_state.pc++; ST(0) = cos(ST(0)); - FP_TAG(); + cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; cpu_state.npxs &= ~C2; CLOCK_CYCLES(300); return 0; @@ -696,7 +696,7 @@ static int FLDENV() case 0x000: /*16-bit real mode*/ case 0x001: /*16-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -704,7 +704,7 @@ static int FLDENV() case 0x100: /*32-bit real mode*/ case 0x101: /*32-bit protected mode*/ cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); cpu_state.TOP = (cpu_state.npxs >> 11) & 7; @@ -742,7 +742,7 @@ static int opFLDCW_a16(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); CLOCK_CYCLES(4); return 0; } @@ -756,7 +756,7 @@ static int opFLDCW_a32(uint32_t fetchdat) tempw = geteaw(); if (cpu_state.abrt) return 1; cpu_state.npxc = tempw; - FP_NNPXC(); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); CLOCK_CYCLES(4); return 0; } @@ -845,8 +845,7 @@ static int opFSTCW_a32(uint32_t fetchdat) } #endif -#ifndef FPU_8087 -#ifdef FP_686 +#if !defined(FPU_8087) && defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686)) #define opFCMOV(condition) \ static int opFCMOV ## condition(uint32_t fetchdat) \ { \ @@ -854,8 +853,8 @@ static int opFSTCW_a32(uint32_t fetchdat) cpu_state.pc++; \ if (cond_ ## condition) \ { \ - cpu_state.tag[FP_TOP(cpu_state.TOP)] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[FP_TOP(cpu_state.TOP)].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ ST(0) = ST(fetchdat & 7); \ } \ CLOCK_CYCLES(4); \ @@ -874,4 +873,3 @@ opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) #endif -#endif