Redid the x87 merger, now the x87 interpreter is basically the same across both recompilers, and there's several newly introduced bugs less.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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]*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
*
|
||||
* Version: @(#)x87_ops.h 1.0.8 2019/06/11
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
@@ -25,7 +25,6 @@
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#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;
|
||||
return 0LL;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
#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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
*
|
||||
* Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user