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:
OBattler
2020-04-10 14:07:25 +02:00
parent a60634b3a1
commit f29f6de245
11 changed files with 166 additions and 323 deletions

View File

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

View File

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

View File

@@ -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]*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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