Merge pull request #809 from nerd73/master
Preliminary port of PCem's FPU timing emulation
This commit is contained in:
@@ -528,6 +528,9 @@ load_machine(void)
|
||||
cpu = config_get_int(cat, "cpu", 0);
|
||||
cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0);
|
||||
|
||||
p = (char *)config_get_string(cat, "fpu", "none");
|
||||
fpu_type = fpu_get_type(machine, cpu_manufacturer, cpu, p);
|
||||
|
||||
mem_size = config_get_int(cat, "mem_size", 4096);
|
||||
|
||||
#if 0
|
||||
@@ -541,8 +544,6 @@ load_machine(void)
|
||||
|
||||
cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0);
|
||||
|
||||
enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0);
|
||||
|
||||
p = config_get_string(cat, "time_sync", NULL);
|
||||
if (p != NULL) {
|
||||
if (!strcmp(p, "disabled"))
|
||||
|
||||
120
src/cpu/cpu.c
120
src/cpu/cpu.c
@@ -59,6 +59,7 @@
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen.h"
|
||||
#endif
|
||||
#include "x87_timings.h"
|
||||
|
||||
/*#define ENABLE_CPU_LOG 1*/
|
||||
|
||||
@@ -171,7 +172,7 @@ int is286,
|
||||
is_am486, is_pentium, is_k5, is_k6, is_p6;
|
||||
|
||||
int hasfpu;
|
||||
|
||||
int fpu_type;
|
||||
|
||||
uint64_t tsc = 0;
|
||||
msr_t msr;
|
||||
@@ -211,7 +212,6 @@ uint64_t ecx404_msr = 0;
|
||||
uint64_t ecx408_msr = 0;
|
||||
uint64_t ecx40c_msr = 0;
|
||||
uint64_t ecx410_msr = 0;
|
||||
|
||||
uint64_t ecx570_msr = 0;
|
||||
|
||||
uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */
|
||||
@@ -296,6 +296,54 @@ cpu_set_edx(void)
|
||||
EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset;
|
||||
}
|
||||
|
||||
int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name)
|
||||
{
|
||||
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int fpu_type = fpus[0].type;
|
||||
int c = 0;
|
||||
|
||||
while (fpus[c].internal_name)
|
||||
{
|
||||
if (!strcmp(internal_name, fpus[c].internal_name))
|
||||
fpu_type = fpus[c].type;
|
||||
c++;
|
||||
}
|
||||
|
||||
return fpu_type;
|
||||
}
|
||||
|
||||
const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type)
|
||||
{
|
||||
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
int c = 0;
|
||||
|
||||
while (fpus[c].internal_name)
|
||||
{
|
||||
if (fpus[c].type == type)
|
||||
return fpus[c].internal_name;
|
||||
c++;
|
||||
}
|
||||
|
||||
return fpus[0].internal_name;
|
||||
}
|
||||
|
||||
const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c)
|
||||
{
|
||||
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
|
||||
return fpus[c].name;
|
||||
}
|
||||
|
||||
int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c)
|
||||
{
|
||||
CPU *cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu];
|
||||
const FPU *fpus = cpu_s->fpus;
|
||||
|
||||
return fpus[c].type;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_set(void)
|
||||
@@ -343,7 +391,7 @@ cpu_set(void)
|
||||
(cpu_s->cpu_type == CPU_PENTIUM2D);
|
||||
/* The Samuel 2 datasheet claims it's Celeron-compatible. */
|
||||
is_p6 |= (cpu_s->cpu_type == CPU_CYRIX3S);
|
||||
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
hasfpu = (fpu_type != FPU_NONE);
|
||||
hascache = (cpu_s->cpu_type >= CPU_486SLC) || (cpu_s->cpu_type == CPU_IBM386SLC || cpu_s->cpu_type == CPU_IBM486SLC || cpu_s->cpu_type == CPU_IBM486BL);
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
|
||||
@@ -362,11 +410,7 @@ cpu_set(void)
|
||||
cpu_dmulti = cpu_s->multi;
|
||||
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
|
||||
|
||||
if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) ||
|
||||
(cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) ||
|
||||
(cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) {
|
||||
hasfpu = !!enable_external_fpu;
|
||||
}
|
||||
|
||||
|
||||
cpu_update_waitstates();
|
||||
|
||||
@@ -509,7 +553,7 @@ cpu_set(void)
|
||||
#else
|
||||
x86_setopcodes(ops_286, ops_286_0f);
|
||||
#endif
|
||||
if (enable_external_fpu)
|
||||
if (fpu_type == FPU_287)
|
||||
{
|
||||
#ifdef USE_DYNAREC
|
||||
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
|
||||
@@ -617,6 +661,39 @@ cpu_set(void)
|
||||
x86_setopcodes(ops_386, ops_486_0f);
|
||||
#endif
|
||||
case CPU_386DX:
|
||||
if (fpu_type == FPU_287) /*In case we get Deskpro 386 emulation*/
|
||||
{
|
||||
#ifdef USE_DYNAREC
|
||||
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
|
||||
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
|
||||
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
|
||||
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
|
||||
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
|
||||
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
|
||||
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
|
||||
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
|
||||
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
|
||||
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
|
||||
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
|
||||
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
|
||||
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
|
||||
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
|
||||
#endif
|
||||
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
|
||||
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
|
||||
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
|
||||
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
|
||||
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
|
||||
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
|
||||
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
|
||||
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
|
||||
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
|
||||
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
|
||||
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
|
||||
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
|
||||
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
|
||||
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
|
||||
}
|
||||
timing_rr = 2; /*register dest - register src*/
|
||||
timing_rm = 6; /*register dest - memory src*/
|
||||
timing_mr = 7; /*memory dest - register src*/
|
||||
@@ -1619,9 +1696,30 @@ cpu_set(void)
|
||||
default:
|
||||
fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type);
|
||||
}
|
||||
|
||||
|
||||
switch (fpu_type)
|
||||
{
|
||||
case FPU_NONE:
|
||||
break;
|
||||
|
||||
case FPU_8087:
|
||||
x87_timings = x87_timings_8087;
|
||||
break;
|
||||
|
||||
case FPU_287:
|
||||
x87_timings = x87_timings_287;
|
||||
break;
|
||||
|
||||
case FPU_287XL:
|
||||
case FPU_387:
|
||||
x87_timings = x87_timings_387;
|
||||
break;
|
||||
|
||||
default:
|
||||
x87_timings = x87_timings_486;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
cpu_current_pc(char *bufp)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,18 @@
|
||||
*/
|
||||
#ifndef EMU_CPU_H
|
||||
# define EMU_CPU_H
|
||||
|
||||
extern int fpu_type;
|
||||
|
||||
enum {
|
||||
FPU_NONE,
|
||||
FPU_8087,
|
||||
FPU_287,
|
||||
FPU_287XL,
|
||||
FPU_387,
|
||||
FPU_BUILTIN
|
||||
};
|
||||
|
||||
enum {
|
||||
CPU_8088, /* 808x class CPUs */
|
||||
CPU_8086,
|
||||
@@ -91,10 +103,16 @@ enum {
|
||||
#define CPU_REQUIRES_DYNAREC 2
|
||||
#define CPU_ALTERNATE_XTAL 4
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
const int type;
|
||||
} FPU;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int cpu_type;
|
||||
const FPU *fpus;
|
||||
int rspeed;
|
||||
double multi;
|
||||
uint32_t edx_reset;
|
||||
@@ -375,6 +393,7 @@ extern int cpu_16bitbus, cpu_64bitbus;
|
||||
extern int cpu_busspeed, cpu_pci_speed;
|
||||
extern int cpu_multi;
|
||||
extern double cpu_dmulti;
|
||||
extern double fpu_multi;
|
||||
extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
|
||||
penalties when crossing 8-byte boundaries*/
|
||||
|
||||
@@ -573,5 +592,9 @@ extern int sysexit(uint32_t fetchdat);
|
||||
extern int syscall(uint32_t fetchdat);
|
||||
extern int sysret(uint32_t fetchdat);
|
||||
|
||||
int fpu_get_type(int machine, int cpu_manufacturer, int cpu, const char *internal_name);
|
||||
const char *fpu_get_internal_name(int machine, int cpu_manufacturer, int cpu, int type);
|
||||
const char *fpu_get_name_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
int fpu_get_type_from_index(int machine, int cpu_manufacturer, int cpu, int c);
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
#include "x87_timings.h"
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define opFPU(name, optype, a_size, load_var, get, use_var) \
|
||||
#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \
|
||||
static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
{ \
|
||||
optype t; \
|
||||
@@ -12,7 +12,7 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -24,7 +24,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
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); \
|
||||
CLOCK_CYCLES(4); \
|
||||
CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -37,7 +37,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
x87_pop(); \
|
||||
CLOCK_CYCLES(4); \
|
||||
CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -49,7 +49,7 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -61,7 +61,7 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(73); \
|
||||
CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -73,7 +73,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(11); \
|
||||
CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -85,7 +85,7 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
|
||||
return 0; \
|
||||
} \
|
||||
static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
@@ -97,27 +97,27 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
FP_TAG_VALID; \
|
||||
CLOCK_CYCLES(8); \
|
||||
CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
opFPU(s, x87_ts, 16, t.i, geteal, t.s)
|
||||
opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32)
|
||||
#ifndef FPU_8087
|
||||
opFPU(s, x87_ts, 32, t.i, geteal, t.s)
|
||||
opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32)
|
||||
#endif
|
||||
opFPU(d, x87_td, 16, t.i, geteaq, t.d)
|
||||
opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64)
|
||||
#ifndef FPU_8087
|
||||
opFPU(d, x87_td, 32, t.i, geteaq, t.d)
|
||||
opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64)
|
||||
#endif
|
||||
|
||||
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t)
|
||||
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16)
|
||||
#ifndef FPU_8087
|
||||
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t)
|
||||
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16)
|
||||
#endif
|
||||
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t)
|
||||
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32)
|
||||
#ifndef FPU_8087
|
||||
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t)
|
||||
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ static int opFADD(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFADDr(uint32_t fetchdat)
|
||||
@@ -136,7 +136,7 @@ static int opFADDr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFADDP(uint32_t fetchdat)
|
||||
@@ -146,7 +146,7 @@ static int opFADDP(uint32_t fetchdat)
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ static int opFCOM(uint32_t fetchdat)
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fcom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ static int opFCOMP(uint32_t fetchdat)
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fcom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ static int opFCOMPP(uint32_t fetchdat)
|
||||
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fcom);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -199,7 +199,7 @@ static int opFUCOMPP(uint32_t fetchdat)
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
|
||||
x87_pop();
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(5);
|
||||
CLOCK_CYCLES(x87_timings.fucom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ static int opFCOMI(uint32_t fetchdat)
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fcom);
|
||||
return 0;
|
||||
}
|
||||
static int opFCOMIP(uint32_t fetchdat)
|
||||
@@ -223,7 +223,7 @@ static int opFCOMIP(uint32_t fetchdat)
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fcom);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -234,7 +234,7 @@ static int opFDIV(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVr(uint32_t fetchdat)
|
||||
@@ -243,7 +243,7 @@ static int opFDIVr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVP(uint32_t fetchdat)
|
||||
@@ -253,7 +253,7 @@ static int opFDIVP(uint32_t fetchdat)
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ static int opFDIVR(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVRr(uint32_t fetchdat)
|
||||
@@ -272,7 +272,7 @@ static int opFDIVRr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
static int opFDIVRP(uint32_t fetchdat)
|
||||
@@ -282,7 +282,7 @@ static int opFDIVRP(uint32_t fetchdat)
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(73);
|
||||
CLOCK_CYCLES(x87_timings.fdiv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ static int opFMUL(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(16);
|
||||
CLOCK_CYCLES(x87_timings.fmul);
|
||||
return 0;
|
||||
}
|
||||
static int opFMULr(uint32_t fetchdat)
|
||||
@@ -301,7 +301,7 @@ static int opFMULr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(16);
|
||||
CLOCK_CYCLES(x87_timings.fmul);
|
||||
return 0;
|
||||
}
|
||||
static int opFMULP(uint32_t fetchdat)
|
||||
@@ -311,7 +311,7 @@ static int opFMULP(uint32_t fetchdat)
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(16);
|
||||
CLOCK_CYCLES(x87_timings.fmul);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ static int opFSUB(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBr(uint32_t fetchdat)
|
||||
@@ -330,7 +330,7 @@ static int opFSUBr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBP(uint32_t fetchdat)
|
||||
@@ -340,7 +340,7 @@ static int opFSUBP(uint32_t fetchdat)
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ static int opFSUBR(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBRr(uint32_t fetchdat)
|
||||
@@ -359,7 +359,7 @@ static int opFSUBRr(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
static int opFSUBRP(uint32_t fetchdat)
|
||||
@@ -369,7 +369,7 @@ static int opFSUBRP(uint32_t fetchdat)
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
FP_TAG_VALID_F;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fadd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -380,7 +380,7 @@ static int opFUCOM(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fucom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -391,7 +391,7 @@ static int opFUCOMP(uint32_t fetchdat)
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fucom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ static int opFUCOMI(uint32_t fetchdat)
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fucom);
|
||||
return 0;
|
||||
}
|
||||
static int opFUCOMIP(uint32_t fetchdat)
|
||||
@@ -415,7 +415,7 @@ static int opFUCOMIP(uint32_t fetchdat)
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fucom);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ static int opFILDiw_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES(13);
|
||||
CLOCK_CYCLES(x87_timings.fild_16);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -35,7 +35,7 @@ static int opFILDiw_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES(13);
|
||||
CLOCK_CYCLES(x87_timings.fild_16);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -48,7 +48,7 @@ static int opFISTiw_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaw((int16_t)temp64);
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_16);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -60,7 +60,7 @@ static int opFISTiw_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaw((int16_t)temp64);
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_16);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
@@ -74,7 +74,7 @@ static int opFISTPiw_a16(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_16);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -87,7 +87,7 @@ static int opFISTPiw_a32(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaw((int16_t)temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_16);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -103,7 +103,7 @@ static int opFILDiq_a16(uint32_t fetchdat)
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
CLOCK_CYCLES(x87_timings.fild_64);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -118,7 +118,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
|
||||
cpu_state.MM[cpu_state.TOP&7].q = temp64;
|
||||
FP_TAG_DEFAULT;
|
||||
|
||||
CLOCK_CYCLES(10);
|
||||
CLOCK_CYCLES(x87_timings.fild_64);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -147,6 +147,7 @@ static int FBSTP_a16(uint32_t fetchdat)
|
||||
if (ST(0) < 0.0) tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(x87_timings.fbstp);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -174,6 +175,7 @@ static int FBSTP_a32(uint32_t fetchdat)
|
||||
if (ST(0) < 0.0) tempc |= 0x80;
|
||||
writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(x87_timings.fbstp);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -190,7 +192,7 @@ static int FISTPiq_a16(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_64);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -206,7 +208,7 @@ static int FISTPiq_a32(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteaq(temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(29);
|
||||
CLOCK_CYCLES(x87_timings.fist_64);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -219,7 +221,7 @@ static int opFILDil_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES(9);
|
||||
CLOCK_CYCLES(x87_timings.fild_32);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -231,7 +233,7 @@ static int opFILDil_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES(9);
|
||||
CLOCK_CYCLES(x87_timings.fild_32);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -244,7 +246,7 @@ static int opFISTil_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteal((int32_t)temp64);
|
||||
CLOCK_CYCLES(28);
|
||||
CLOCK_CYCLES(x87_timings.fist_32);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -256,7 +258,7 @@ static int opFISTil_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteal((int32_t)temp64);
|
||||
CLOCK_CYCLES(28);
|
||||
CLOCK_CYCLES(x87_timings.fist_32);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
@@ -270,7 +272,7 @@ static int opFISTPil_a16(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(28);
|
||||
CLOCK_CYCLES(x87_timings.fist_32);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -283,7 +285,7 @@ static int opFISTPil_a32(uint32_t fetchdat)
|
||||
temp64 = x87_fround(ST(0));
|
||||
seteal((int32_t)temp64); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(28);
|
||||
CLOCK_CYCLES(x87_timings.fist_32);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -296,7 +298,7 @@ static int opFLDe_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES(6);
|
||||
CLOCK_CYCLES(x87_timings.fld_80);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -308,7 +310,7 @@ static int opFLDe_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES(6);
|
||||
CLOCK_CYCLES(x87_timings.fld_80);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -320,7 +322,7 @@ static int opFSTPe_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(6);
|
||||
CLOCK_CYCLES(x87_timings.fld_80);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -331,7 +333,7 @@ static int opFSTPe_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(6);
|
||||
CLOCK_CYCLES(x87_timings.fld_80);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -344,7 +346,7 @@ static int opFLDd_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fld_64);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -356,7 +358,7 @@ static int opFLDd_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fld_64);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -369,7 +371,7 @@ static int opFSTd_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fst_64);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -381,7 +383,7 @@ static int opFSTd_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fst_64);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
@@ -395,7 +397,7 @@ static int opFSTPd_a16(uint32_t fetchdat)
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fst_64);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -408,7 +410,7 @@ static int opFSTPd_a32(uint32_t fetchdat)
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fst_64);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -421,7 +423,7 @@ static int opFLDs_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fld_32);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -433,7 +435,7 @@ static int opFLDs_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fld_32);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -446,7 +448,7 @@ static int opFSTs_a16(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES(7);
|
||||
CLOCK_CYCLES(x87_timings.fst_32);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -458,7 +460,7 @@ static int opFSTs_a32(uint32_t fetchdat)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES(7);
|
||||
CLOCK_CYCLES(x87_timings.fst_32);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
@@ -472,7 +474,7 @@ static int opFSTPs_a16(uint32_t fetchdat)
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(7);
|
||||
CLOCK_CYCLES(x87_timings.fst_32);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -485,7 +487,7 @@ static int opFSTPs_a32(uint32_t fetchdat)
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(7);
|
||||
CLOCK_CYCLES(x87_timings.fst_32);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@ static int opFSTSW_AX(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
AX = cpu_state.npxs;
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fstcw_sw);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -25,7 +25,7 @@ static int opFNOP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fnop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ static int opFCLEX(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxs &= 0xff00;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fnop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ static int opFINIT(uint32_t fetchdat)
|
||||
#endif
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
CLOCK_CYCLES(17);
|
||||
CLOCK_CYCLES(x87_timings.finit);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ static int opFFREE(uint32_t fetchdat)
|
||||
#else
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
|
||||
#endif
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.ffree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ static int opFFREEP(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.ffree);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ static int opFST(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(fetchdat & 7) = ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ static int opFSTP(uint32_t fetchdat)
|
||||
ST(fetchdat & 7) = ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ static int FSTOR()
|
||||
#endif
|
||||
cpu_state.ismmx = 1;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(x87_timings.frstor);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opFSTOR_a16(uint32_t fetchdat)
|
||||
@@ -330,7 +330,7 @@ static int FSAVE()
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
CLOCK_CYCLES(x87_timings.fsave);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opFSAVE_a16(uint32_t fetchdat)
|
||||
@@ -358,7 +358,7 @@ static int opFSTSW_a16(uint32_t fetchdat)
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fstcw_sw);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -368,7 +368,7 @@ static int opFSTSW_a32(uint32_t fetchdat)
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fstcw_sw);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
@@ -386,7 +386,7 @@ static int opFLD(uint32_t fetchdat)
|
||||
x87_push(ST(fetchdat&7));
|
||||
cpu_state.tag[cpu_state.TOP&7] = old_tag;
|
||||
cpu_state.MM[cpu_state.TOP&7].q = old_i64;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fld);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ static int opFXCH(uint32_t fetchdat)
|
||||
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);
|
||||
CLOCK_CYCLES(x87_timings.fxch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ static int opFCHS(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = -ST(0);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(6);
|
||||
CLOCK_CYCLES(x87_timings.fchs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ static int opFABS(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = fabs(ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fabs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -438,7 +438,7 @@ static int opFTST(uint32_t fetchdat)
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < 0.0) cpu_state.npxs |= C0;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.ftst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ static int opFXAM(uint32_t fetchdat)
|
||||
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else cpu_state.npxs |= C2;
|
||||
if (ST(0) < 0.0) cpu_state.npxs |= C1;
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fxam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -464,7 +464,7 @@ static int opFLD1(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(1.0);
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fld_z1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ static int opFLDL2T(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(3.3219280948873623);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fld_const);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ static int opFLDL2E(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(1.4426950408889634);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fld_const);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ static int opFLDPI(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(3.141592653589793);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fld_const);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ static int opFLDEG2(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push(0.3010299956639812);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fld_const);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ static int opFLDLN2(uint32_t fetchdat)
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
x87_push_u64(0x3fe62e42fefa39f0ull);
|
||||
CLOCK_CYCLES(8);
|
||||
CLOCK_CYCLES(x87_timings.fld_const);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -519,7 +519,7 @@ static int opFLDZ(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
x87_push(0.0);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fld_z1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ static int opF2XM1(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = pow(2.0, ST(0)) - 1.0;
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(200);
|
||||
CLOCK_CYCLES(x87_timings.f2xm1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ static int opFYL2X(uint32_t fetchdat)
|
||||
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
CLOCK_CYCLES(x87_timings.fyl2x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ static int opFYL2XP1(uint32_t fetchdat)
|
||||
ST(1) = ST(1) * (log1p(ST(0)) / log(2.0));
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
CLOCK_CYCLES(x87_timings.fyl2xp1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,7 +563,7 @@ static int opFPTAN(uint32_t fetchdat)
|
||||
FP_TAG_VALID;
|
||||
x87_push(1.0);
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(235);
|
||||
CLOCK_CYCLES(x87_timings.fptan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -574,7 +574,7 @@ static int opFPATAN(uint32_t fetchdat)
|
||||
ST(1) = atan2(ST(1), ST(0));
|
||||
FP_TAG_VALID_N;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(250);
|
||||
CLOCK_CYCLES(x87_timings.fpatan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -587,7 +587,7 @@ static int opFDECSTP(uint32_t fetchdat)
|
||||
#else
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
#endif
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fincdecstp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -600,7 +600,7 @@ static int opFINCSTP(uint32_t fetchdat)
|
||||
#else
|
||||
cpu_state.TOP = (cpu_state.TOP + 1) & 7;
|
||||
#endif
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fincdecstp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ static int opFPREM(uint32_t fetchdat)
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
if (temp64 & 1) cpu_state.npxs|=C1;
|
||||
CLOCK_CYCLES(100);
|
||||
CLOCK_CYCLES(x87_timings.fprem);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -632,7 +632,7 @@ static int opFPREM1(uint32_t fetchdat)
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
if (temp64 & 1) cpu_state.npxs|=C1;
|
||||
CLOCK_CYCLES(100);
|
||||
CLOCK_CYCLES(x87_timings.fprem1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -643,7 +643,7 @@ static int opFSQRT(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = sqrt(ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(83);
|
||||
CLOCK_CYCLES(x87_timings.fsqrt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ static int opFSINCOS(uint32_t fetchdat)
|
||||
FP_TAG_VALID;
|
||||
x87_push(cos(td));
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(330);
|
||||
CLOCK_CYCLES(x87_timings.fsincos);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -669,7 +669,7 @@ static int opFRNDINT(uint32_t fetchdat)
|
||||
cpu_state.pc++;
|
||||
ST(0) = (double)x87_fround(ST(0));
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(21);
|
||||
CLOCK_CYCLES(x87_timings.frndint);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ static int opFSCALE(uint32_t fetchdat)
|
||||
temp64 = (int64_t)ST(1);
|
||||
ST(0) = ST(0) * pow(2.0, (double)temp64);
|
||||
FP_TAG_VALID;
|
||||
CLOCK_CYCLES(30);
|
||||
CLOCK_CYCLES(x87_timings.fscale);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -693,7 +693,7 @@ static int opFSIN(uint32_t fetchdat)
|
||||
ST(0) = sin(ST(0));
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
CLOCK_CYCLES(x87_timings.fsin_cos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -704,7 +704,7 @@ static int opFCOS(uint32_t fetchdat)
|
||||
ST(0) = cos(ST(0));
|
||||
FP_TAG_VALID;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
CLOCK_CYCLES(x87_timings.fsin_cos);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -732,7 +732,7 @@ static int FLDENV()
|
||||
cpu_state.TOP = (cpu_state.npxs >> 11) & 7;
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(x87_timings.fldenv);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ static int opFLDCW_a16(uint32_t fetchdat)
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fldcw);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -779,7 +779,7 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3);
|
||||
CLOCK_CYCLES(4);
|
||||
CLOCK_CYCLES(x87_timings.fldcw);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -823,7 +823,7 @@ static int FSTENV()
|
||||
writememl(easeg,cpu_state.eaaddr+24,x87_op_seg);
|
||||
break;
|
||||
}
|
||||
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
|
||||
CLOCK_CYCLES(x87_timings.fstenv);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
@@ -852,7 +852,7 @@ static int opFSTCW_a16(uint32_t fetchdat)
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fstcw_sw);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
@@ -862,7 +862,7 @@ static int opFSTCW_a32(uint32_t fetchdat)
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
CLOCK_CYCLES(x87_timings.fstcw_sw);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
315
src/cpu/x87_timings.c
Normal file
315
src/cpu/x87_timings.c
Normal file
@@ -0,0 +1,315 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <86box/86box.h>
|
||||
#include "cpu.h"
|
||||
#include <86box/machine.h>
|
||||
#include "x87_timings.h"
|
||||
|
||||
x87_timings_t x87_timings;
|
||||
|
||||
const x87_timings_t x87_timings_8087 =
|
||||
{
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
.fabs = (10 + 17) / 2,
|
||||
.fadd = (70 + 100) / 2,
|
||||
.fadd_32 = (90 + 120) / 2,
|
||||
.fadd_64 = (95 + 125) / 2,
|
||||
.fbld = (290 + 310) / 2,
|
||||
.fbstp = (520 + 540) / 2,
|
||||
.fchs = (10 + 17) / 2,
|
||||
.fclex = (2 + 8) / 2,
|
||||
.fcom = (40 + 50) / 2,
|
||||
.fcom_32 = (60 + 70) / 2,
|
||||
.fcom_64 = (65 + 75) / 2,
|
||||
.fcos = 0, /*387+*/
|
||||
.fincdecstp = (6 + 12) / 2,
|
||||
.fdisi_eni = (6 + 12) / 2,
|
||||
.fdiv = (193 + 203) / 2,
|
||||
.fdiv_32 = (215 + 225) / 2,
|
||||
.fdiv_64 = (220 + 230) / 2,
|
||||
.ffree = (9 + 16) / 2,
|
||||
.fadd_i16 = (102 + 137) / 2,
|
||||
.fadd_i32 = (108 + 143) / 2,
|
||||
.fcom_i16 = (72 + 86) / 2,
|
||||
.fcom_i32 = (78 + 91) / 2,
|
||||
.fdiv_i16 = (224 + 238) / 2,
|
||||
.fdiv_i32 = (230 + 243) / 2,
|
||||
.fild_16 = (46 + 54) / 2,
|
||||
.fild_32 = (50 + 60) / 2,
|
||||
.fild_64 = (60 + 68) / 2,
|
||||
.fmul_i16 = (124 + 138) / 2,
|
||||
.fmul_i32 = (130 + 144) / 2,
|
||||
.finit = (2 + 8) / 2,
|
||||
.fist_16 = (80 + 90) / 2,
|
||||
.fist_32 = (82 + 92) / 2,
|
||||
.fist_64 = (94 + 105) / 2,
|
||||
.fld = (17 + 22) / 2,
|
||||
.fld_32 = (38 + 56) / 2,
|
||||
.fld_64 = (40 + 60) / 2,
|
||||
.fld_80 = (53 + 65) / 2,
|
||||
.fld_z1 = (11 + 21) / 2,
|
||||
.fld_const = (15 + 24) / 2,
|
||||
.fldcw = (7 + 14) / 2,
|
||||
.fldenv = (35 + 45) / 2,
|
||||
.fmul = (90 + 145) / 2,
|
||||
.fmul_32 = (110 + 125) / 2,
|
||||
.fmul_64 = (154 + 168) / 2,
|
||||
.fnop = (10 + 16) / 2,
|
||||
.fpatan = (250 + 800) / 2,
|
||||
.fprem = (15 + 190) / 2,
|
||||
.fprem1 = 0, /*387+*/
|
||||
.fptan = (30 + 540) / 2,
|
||||
.frndint = (16 + 50) / 2,
|
||||
.frstor = (197 + 207) / 2,
|
||||
.fsave = (197 + 207) / 2,
|
||||
.fscale = (32 + 38) / 2,
|
||||
.fsetpm = 0, /*287+*/
|
||||
.fsin_cos = 0, /*387+*/
|
||||
.fsincos = 0, /*387+*/
|
||||
.fsqrt = (180 + 186) / 2,
|
||||
.fst = (15 + 22) / 2,
|
||||
.fst_32 = (84 + 90) / 2,
|
||||
.fst_64 = (96 + 104) / 2,
|
||||
.fst_80 = (52 + 58) / 2,
|
||||
.fstcw_sw = (12 + 18) / 2,
|
||||
.fstenv = (40 + 50) / 2,
|
||||
.ftst = (38 + 48) / 2,
|
||||
.fucom = 0, /*387+*/
|
||||
.fwait = 4,
|
||||
.fxam = (12 + 23) / 2,
|
||||
.fxch = (10 + 15) / 2,
|
||||
.fxtract = (27 + 55) / 2,
|
||||
.fyl2x = (900 + 1100) / 2,
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
/*Mostly the same as 8087*/
|
||||
const x87_timings_t x87_timings_287 =
|
||||
{
|
||||
.f2xm1 = (310 + 630) / 2,
|
||||
.fabs = (10 + 17) / 2,
|
||||
.fadd = (70 + 100) / 2,
|
||||
.fadd_32 = (90 + 120) / 2,
|
||||
.fadd_64 = (95 + 125) / 2,
|
||||
.fbld = (290 + 310) / 2,
|
||||
.fbstp = (520 + 540) / 2,
|
||||
.fchs = (10 + 17) / 2,
|
||||
.fclex = (2 + 8) / 2,
|
||||
.fcom = (40 + 50) / 2,
|
||||
.fcom_32 = (60 + 70) / 2,
|
||||
.fcom_64 = (65 + 75) / 2,
|
||||
.fcos = 0, /*387+*/
|
||||
.fincdecstp = (6 + 12) / 2,
|
||||
.fdisi_eni = 2,
|
||||
.fdiv = (193 + 203) / 2,
|
||||
.fdiv_32 = (215 + 225) / 2,
|
||||
.fdiv_64 = (220 + 230) / 2,
|
||||
.ffree = (9 + 16) / 2,
|
||||
.fadd_i16 = (102 + 137) / 2,
|
||||
.fadd_i32 = (108 + 143) / 2,
|
||||
.fcom_i16 = (72 + 86) / 2,
|
||||
.fcom_i32 = (78 + 91) / 2,
|
||||
.fdiv_i16 = (224 + 238) / 2,
|
||||
.fdiv_i32 = (230 + 243) / 2,
|
||||
.fild_16 = (46 + 54) / 2,
|
||||
.fild_32 = (50 + 60) / 2,
|
||||
.fild_64 = (60 + 68) / 2,
|
||||
.fmul_i16 = (124 + 138) / 2,
|
||||
.fmul_i32 = (130 + 144) / 2,
|
||||
.finit = (2 + 8) / 2,
|
||||
.fist_16 = (80 + 90) / 2,
|
||||
.fist_32 = (82 + 92) / 2,
|
||||
.fist_64 = (94 + 105) / 2,
|
||||
.fld = (17 + 22) / 2,
|
||||
.fld_32 = (38 + 56) / 2,
|
||||
.fld_64 = (40 + 60) / 2,
|
||||
.fld_80 = (53 + 65) / 2,
|
||||
.fld_z1 = (11 + 21) / 2,
|
||||
.fld_const = (15 + 24) / 2,
|
||||
.fldcw = (7 + 14) / 2,
|
||||
.fldenv = (35 + 45) / 2,
|
||||
.fmul = (90 + 145) / 2,
|
||||
.fmul_32 = (110 + 125) / 2,
|
||||
.fmul_64 = (154 + 168) / 2,
|
||||
.fnop = (10 + 16) / 2,
|
||||
.fpatan = (250 + 800) / 2,
|
||||
.fprem = (15 + 190) / 2,
|
||||
.fprem1 = 0, /*387+*/
|
||||
.fptan = (30 + 540) / 2,
|
||||
.frndint = (16 + 50) / 2,
|
||||
.frstor = (197 + 207) / 2,
|
||||
.fsave = (197 + 207) / 2,
|
||||
.fscale = (32 + 38) / 2,
|
||||
.fsetpm = (2 + 8) / 2, /*287+*/
|
||||
.fsin_cos = 0, /*387+*/
|
||||
.fsincos = 0, /*387+*/
|
||||
.fsqrt = (180 + 186) / 2,
|
||||
.fst = (15 + 22) / 2,
|
||||
.fst_32 = (84 + 90) / 2,
|
||||
.fst_64 = (96 + 104) / 2,
|
||||
.fst_80 = (52 + 58) / 2,
|
||||
.fstcw_sw = (12 + 18) / 2,
|
||||
.fstenv = (40 + 50) / 2,
|
||||
.ftst = (38 + 48) / 2,
|
||||
.fucom = 0, /*387+*/
|
||||
.fwait = 3,
|
||||
.fxam = (12 + 23) / 2,
|
||||
.fxch = (10 + 15) / 2,
|
||||
.fxtract = (27 + 55) / 2,
|
||||
.fyl2x = (900 + 1100) / 2,
|
||||
.fyl2xp1 = (700 + 1000) / 2
|
||||
};
|
||||
|
||||
const x87_timings_t x87_timings_387 =
|
||||
{
|
||||
.f2xm1 = (211 + 476) / 2,
|
||||
.fabs = 22,
|
||||
.fadd = (23 + 34) / 2,
|
||||
.fadd_32 = (24 + 32) / 2,
|
||||
.fadd_64 = (29 + 37) / 2,
|
||||
.fbld = (266 + 275) / 2,
|
||||
.fbstp = (512 + 534) / 2,
|
||||
.fchs = (24 + 25) / 2,
|
||||
.fclex = 11,
|
||||
.fcom = 24,
|
||||
.fcom_32 = 26,
|
||||
.fcom_64 = 31,
|
||||
.fcos = (122 + 772) / 2,
|
||||
.fincdecstp = 22,
|
||||
.fdisi_eni = 2,
|
||||
.fdiv = (88 + 91) / 2,
|
||||
.fdiv_32 = 89,
|
||||
.fdiv_64 = 94,
|
||||
.ffree = 18,
|
||||
.fadd_i16 = (71 + 85) / 2,
|
||||
.fadd_i32 = (57 + 72) / 2,
|
||||
.fcom_i16 = (71 + 75) / 2,
|
||||
.fcom_i32 = (56 + 63) / 2,
|
||||
.fdiv_i16 = (136 + 140) / 2,
|
||||
.fdiv_i32 = (120 + 127) / 2,
|
||||
.fild_16 = (61 + 65) / 2,
|
||||
.fild_32 = (45 + 52) / 2,
|
||||
.fild_64 = (56 + 67) / 2,
|
||||
.fmul_i16 = (76 + 87) / 2,
|
||||
.fmul_i32 = (61 + 82) / 2,
|
||||
.finit = 33,
|
||||
.fist_16 = (82 + 95) / 2,
|
||||
.fist_32 = (79 + 93) / 2,
|
||||
.fist_64 = (80 + 97) / 2,
|
||||
.fld = 14,
|
||||
.fld_32 = 20,
|
||||
.fld_64 = 25,
|
||||
.fld_80 = 44,
|
||||
.fld_z1 = (20 + 24) / 2,
|
||||
.fld_const = 40,
|
||||
.fldcw = 19,
|
||||
.fldenv = 71,
|
||||
.fmul = (29 + 57) / 2,
|
||||
.fmul_32 = (27 + 35) / 2,
|
||||
.fmul_64 = (32 + 57) / 2,
|
||||
.fnop = 12,
|
||||
.fpatan = (314 + 487) / 2,
|
||||
.fprem = (74 + 155) / 2,
|
||||
.fprem1 = (95 + 185) / 2,
|
||||
.fptan = (191 + 497) / 2,
|
||||
.frndint = (66 + 80) / 2,
|
||||
.frstor = 308,
|
||||
.fsave = 375,
|
||||
.fscale = (67 + 86) / 2,
|
||||
.fsetpm = 12,
|
||||
.fsin_cos = (122 + 771) / 2,
|
||||
.fsincos = (194 + 809) / 2,
|
||||
.fsqrt = (122 + 129) / 2,
|
||||
.fst = 11,
|
||||
.fst_32 = 44,
|
||||
.fst_64 = 45,
|
||||
.fst_80 = 53,
|
||||
.fstcw_sw = 15,
|
||||
.fstenv = 103,
|
||||
.ftst = 28,
|
||||
.fucom = 24,
|
||||
.fwait = 6,
|
||||
.fxam = (30 + 38) / 2,
|
||||
.fxch = 18,
|
||||
.fxtract = (70 + 76) / 2,
|
||||
.fyl2x = (120 + 538) / 2,
|
||||
.fyl2xp1 = (257 + 547) / 2
|
||||
};
|
||||
|
||||
const x87_timings_t x87_timings_486 =
|
||||
{
|
||||
.f2xm1 = (140 + 270) / 2,
|
||||
.fabs = 3,
|
||||
.fadd = (8 + 20) / 2,
|
||||
.fadd_32 = (8 + 20) / 2,
|
||||
.fadd_64 = (8 + 20) / 2,
|
||||
.fbld = (70 + 103) / 2,
|
||||
.fbstp = (172 + 176) / 2,
|
||||
.fchs = 6,
|
||||
.fclex = 7,
|
||||
.fcom = 4,
|
||||
.fcom_32 = 4,
|
||||
.fcom_64 = 4,
|
||||
.fcos = (257 + 354) / 2,
|
||||
.fincdecstp = 3,
|
||||
.fdisi_eni = 3,
|
||||
.fdiv = 73,
|
||||
.fdiv_32 = 73,
|
||||
.fdiv_64 = 73,
|
||||
.ffree = 3,
|
||||
.fadd_i16 = (20 + 35) / 2,
|
||||
.fadd_i32 = (19 + 32) / 2,
|
||||
.fcom_i16 = (16 + 20) / 2,
|
||||
.fcom_i32 = (15 + 17) / 2,
|
||||
.fdiv_i16 = (85 + 89) / 2,
|
||||
.fdiv_i32 = (84 + 86) / 2,
|
||||
.fild_16 = (13 + 16) / 2,
|
||||
.fild_32 = (9 + 12) / 2,
|
||||
.fild_64 = (10 + 18) / 2,
|
||||
.fmul_i16 = (23 + 27) / 2,
|
||||
.fmul_i32 = (22 + 24) / 2,
|
||||
.finit = 17,
|
||||
.fist_16 = (29 + 34) / 2,
|
||||
.fist_32 = (28 + 34) / 2,
|
||||
.fist_64 = (29 + 34) / 2,
|
||||
.fld = 4,
|
||||
.fld_32 = 3,
|
||||
.fld_64 = 3,
|
||||
.fld_80 = 6,
|
||||
.fld_z1 = 4,
|
||||
.fld_const = 8,
|
||||
.fldcw = 4,
|
||||
.fldenv = 34,
|
||||
.fmul = 16,
|
||||
.fmul_32 = 11,
|
||||
.fmul_64 = 14,
|
||||
.fnop = 3,
|
||||
.fpatan = (218 + 303) / 2,
|
||||
.fprem = (70 + 138) / 2,
|
||||
.fprem1 = (72 + 167) / 2,
|
||||
.fptan = (200 + 273) / 2,
|
||||
.frndint = (21 + 30) / 2,
|
||||
.frstor = 120,
|
||||
.fsave = 143,
|
||||
.fscale = (30 + 32) / 2,
|
||||
.fsetpm = 3,
|
||||
.fsin_cos = (257 + 354) / 2,
|
||||
.fsincos = (292 + 365) / 2,
|
||||
.fsqrt = (83 + 87) / 2,
|
||||
.fst = 3,
|
||||
.fst_32 = 7,
|
||||
.fst_64 = 8,
|
||||
.fst_80 = 6,
|
||||
.fstcw_sw = 3,
|
||||
.fstenv = 56,
|
||||
.ftst = 4,
|
||||
.fucom = 4,
|
||||
.fwait = (1 + 3) / 2,
|
||||
.fxam = 8,
|
||||
.fxch = 4,
|
||||
.fxtract = (16 + 20) / 2,
|
||||
.fyl2x = (196 + 329) / 2,
|
||||
.fyl2xp1 = (171 + 326) / 2
|
||||
};
|
||||
56
src/cpu/x87_timings.h
Normal file
56
src/cpu/x87_timings.h
Normal file
@@ -0,0 +1,56 @@
|
||||
typedef struct
|
||||
{
|
||||
int f2xm1;
|
||||
int fabs;
|
||||
int fadd, fadd_32, fadd_64;
|
||||
int fbld;
|
||||
int fbstp;
|
||||
int fchs;
|
||||
int fclex;
|
||||
int fcom, fcom_32, fcom_64;
|
||||
int fcos;
|
||||
int fincdecstp;
|
||||
int fdisi_eni;
|
||||
int fdiv, fdiv_32, fdiv_64;
|
||||
int ffree;
|
||||
int fadd_i16, fadd_i32;
|
||||
int fcom_i16, fcom_i32;
|
||||
int fdiv_i16, fdiv_i32;
|
||||
int fild_16, fild_32, fild_64;
|
||||
int fmul_i16, fmul_i32;
|
||||
int finit;
|
||||
int fist_16, fist_32, fist_64;
|
||||
int fld, fld_32, fld_64, fld_80;
|
||||
int fld_z1, fld_const;
|
||||
int fldcw;
|
||||
int fldenv;
|
||||
int fmul, fmul_32, fmul_64;
|
||||
int fnop;
|
||||
int fpatan;
|
||||
int fprem, fprem1;
|
||||
int fptan;
|
||||
int frndint;
|
||||
int frstor;
|
||||
int fsave;
|
||||
int fscale;
|
||||
int fsetpm;
|
||||
int fsin_cos, fsincos;
|
||||
int fsqrt;
|
||||
int fst, fst_32, fst_64, fst_80;
|
||||
int fstcw_sw;
|
||||
int fstenv;
|
||||
int ftst;
|
||||
int fucom;
|
||||
int fwait;
|
||||
int fxam;
|
||||
int fxch;
|
||||
int fxtract;
|
||||
int fyl2x, fyl2xp1;
|
||||
} x87_timings_t;
|
||||
|
||||
extern const x87_timings_t x87_timings_8087;
|
||||
extern const x87_timings_t x87_timings_287;
|
||||
extern const x87_timings_t x87_timings_387;
|
||||
extern const x87_timings_t x87_timings_486;
|
||||
|
||||
extern x87_timings_t x87_timings;
|
||||
@@ -370,8 +370,6 @@ BEGIN
|
||||
12,12
|
||||
LTEXT "MB",IDT_1705,123,64,10,10
|
||||
LTEXT "Memory:",IDT_1706,7,64,30,10
|
||||
CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,7,81,113,10
|
||||
GROUPBOX "Time synchronization",IDC_TIME_SYNC,7,96,100,56
|
||||
CONTROL "Disabled",IDC_RADIO_TS_DISABLED,"Button",
|
||||
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,108,84,10
|
||||
|
||||
@@ -556,7 +556,7 @@ MEMOBJ := intel_flash.o mem.o rom.o spd.o sst_flash.o
|
||||
|
||||
CPUOBJ := cpu.o cpu_table.o \
|
||||
808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o $(CGTOBJ) \
|
||||
x86seg.o x87.o \
|
||||
x86seg.o x87.o x87_timings.o \
|
||||
$(DYNARECOBJ)
|
||||
|
||||
CHIPSETOBJ := acc2168.o acer_m3a.o cs8230.o ali1429.o headland.o \
|
||||
|
||||
Reference in New Issue
Block a user