Re-added some x87 differences between the old and new recompilers, fixes #692.
This commit is contained in:
@@ -42,6 +42,7 @@ fpu_log(const char *fmt, ...)
|
||||
#define X87_TAG_INVALID 2
|
||||
#define X87_TAG_EMPTY 3
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
uint16_t x87_gettag()
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
@@ -78,6 +79,35 @@ 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
|
||||
|
@@ -30,10 +30,14 @@ void x87_settag(uint16_t new_tag);
|
||||
#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*/
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#define TAG_UINT64 (1 << 7)
|
||||
#else
|
||||
#define TAG_UINT64 (1 << 2)
|
||||
#endif
|
||||
|
||||
/*Old dynarec stuff.*/
|
||||
#define TAG_NOT_UINT64 0x7f
|
||||
#define TAG_NOT_UINT64 0xfb
|
||||
|
||||
#define X87_ROUNDING_NEAREST 0
|
||||
#define X87_ROUNDING_DOWN 1
|
||||
|
@@ -98,7 +98,11 @@ static __inline void x87_push(double i)
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = i;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline void x87_push_u64(uint64_t i)
|
||||
@@ -117,7 +121,11 @@ static __inline void x87_push_u64(uint64_t i)
|
||||
cpu_state.TOP=(cpu_state.TOP-1)&7;
|
||||
#endif
|
||||
cpu_state.ST[cpu_state.TOP&7] = td.d;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline double x87_pop()
|
||||
@@ -127,6 +135,7 @@ static __inline double x87_pop()
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.TOP++;
|
||||
#else
|
||||
cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64;
|
||||
cpu_state.TOP=(cpu_state.TOP+1)&7;
|
||||
#endif
|
||||
return t;
|
||||
@@ -263,13 +272,22 @@ 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))
|
||||
#else
|
||||
if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2))
|
||||
#endif
|
||||
{
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] = TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = (double)cpu_state.MM[reg].q;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[reg] &= ~TAG_UINT64;
|
||||
#endif
|
||||
cpu_state.ST[reg] = x87_ld80();
|
||||
}
|
||||
}
|
||||
@@ -426,6 +444,18 @@ typedef union
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID
|
||||
#else
|
||||
# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64
|
||||
# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64
|
||||
# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64
|
||||
#endif
|
||||
|
||||
#include "x87_ops_arith.h"
|
||||
#include "x87_ops_misc.h"
|
||||
#include "x87_ops_loadstore.h"
|
||||
|
@@ -11,7 +11,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
ST(0) += use_var; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -48,7 +48,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -60,7 +60,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -72,7 +72,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(11); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -84,7 +84,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -96,7 +96,7 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
}
|
||||
@@ -126,7 +126,7 @@ static int opFADD(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ static int opFADDr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ static int opFADDP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -233,7 +233,7 @@ static int opFDIV(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
@@ -242,7 +242,7 @@ static int opFDIVr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ static int opFDIVP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
@@ -262,7 +262,7 @@ static int opFDIVR(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
@@ -271,7 +271,7 @@ static int opFDIVRr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
}
|
||||
@@ -280,7 +280,7 @@ static int opFDIVRP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
return 0;
|
||||
@@ -291,7 +291,7 @@ static int opFMUL(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
@@ -300,7 +300,7 @@ static int opFMULr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ static int opFMULP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(16);
|
||||
return 0;
|
||||
@@ -320,7 +320,7 @@ static int opFSUB(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -329,7 +329,7 @@ static int opFSUBr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -338,7 +338,7 @@ static int opFSUBP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -349,7 +349,7 @@ static int opFSUBR(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -358,7 +358,7 @@ static int opFSUBRr(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
@@ -367,7 +367,7 @@ static int opFSUBRP(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
|
@@ -15,7 +15,6 @@
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
|
||||
static int opFILDiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int16_t temp;
|
||||
@@ -102,7 +101,7 @@ static int opFILDiq_a16(uint32_t fetchdat)
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
@@ -117,7 +116,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
|
@@ -51,7 +51,11 @@ static int opFINIT(uint32_t fetchdat)
|
||||
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
|
||||
cpu_state.npxs = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
*p = 0;
|
||||
#else
|
||||
*p = 0x0303030303030303ll;
|
||||
#endif
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
CLOCK_CYCLES(17);
|
||||
@@ -64,7 +68,11 @@ static int opFFREE(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY;
|
||||
#else
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
|
||||
#endif
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
@@ -141,10 +149,16 @@ static int FSTOR()
|
||||
/*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;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
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 == 0x0101010101010101ull))
|
||||
cpu_state.ismmx = 1;
|
||||
#else
|
||||
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))
|
||||
#endif
|
||||
cpu_state.ismmx = 1;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
return cpu_state.abrt;
|
||||
@@ -308,7 +322,11 @@ static int FSAVE()
|
||||
codegen_set_rounding_mode(X87_ROUNDING_NEAREST);
|
||||
cpu_state.npxs = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
*p = 0;
|
||||
#else
|
||||
*p = 0x0303030303030303ll;
|
||||
#endif
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
|
||||
@@ -398,7 +416,7 @@ static int opFCHS(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = -ST(0);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
@@ -408,7 +426,7 @@ static int opFABS(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = fabs(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
@@ -429,7 +447,11 @@ static int opFXAM(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3);
|
||||
#else
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
|
||||
#endif
|
||||
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 +518,7 @@ static int opFLDZ(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(0.0);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
@@ -506,7 +528,7 @@ static int opF2XM1(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = pow(2.0, ST(0)) - 1.0;
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(200);
|
||||
return 0;
|
||||
}
|
||||
@@ -516,7 +538,7 @@ static int opFYL2X(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
@@ -527,7 +549,7 @@ static int opFYL2XP1(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(1) = ST(1) * (log1p(ST(0)) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
@@ -538,7 +560,7 @@ static int opFPTAN(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = tan(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
x87_push(1.0);
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(235);
|
||||
@@ -550,7 +572,7 @@ static int opFPATAN(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(1) = atan2(ST(1), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID;
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
return 0;
|
||||
@@ -589,7 +611,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);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
@@ -605,7 +627,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);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
@@ -620,7 +642,7 @@ static int opFSQRT(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = sqrt(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(83);
|
||||
return 0;
|
||||
}
|
||||
@@ -633,7 +655,7 @@ static int opFSINCOS(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
td = ST(0);
|
||||
ST(0) = sin(td);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
x87_push(cos(td));
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(330);
|
||||
@@ -646,7 +668,7 @@ static int opFRNDINT(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = (double)x87_fround(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(21);
|
||||
return 0;
|
||||
}
|
||||
@@ -658,7 +680,7 @@ static int opFSCALE(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
temp64 = (int64_t)ST(1);
|
||||
ST(0) = ST(0) * pow(2.0, (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(30);
|
||||
return 0;
|
||||
}
|
||||
@@ -669,7 +691,7 @@ static int opFSIN(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = sin(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
@@ -680,7 +702,7 @@ static int opFCOS(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
ST(0) = cos(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP&7] = TAG_VALID;
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user