utilize host fpu directly (dynamic core)
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2707
This commit is contained in:
parent
da0bb016c5
commit
3cb1e884bd
5 changed files with 199 additions and 59 deletions
|
@ -43,6 +43,7 @@
|
|||
#include "debug.h"
|
||||
#include "paging.h"
|
||||
#include "inout.h"
|
||||
#include "fpu.h"
|
||||
|
||||
#define CACHE_MAXSIZE (4096*2)
|
||||
#define CACHE_PAGES (128*8)
|
||||
|
@ -163,6 +164,15 @@ static struct {
|
|||
Bitu callback,readdata;
|
||||
} core_dyn;
|
||||
|
||||
struct {
|
||||
Bit32u state[32];
|
||||
FPU_P_Reg temp,temp2;
|
||||
Bit32u dh_fpu_enabled;
|
||||
Bit32u state_used;
|
||||
Bit32u cw,host_cw;
|
||||
Bit8u temp_state[128];
|
||||
} dyn_dh_fpu;
|
||||
|
||||
|
||||
#include "core_dyn_x86/risc_x86.h"
|
||||
|
||||
|
@ -219,6 +229,30 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) {
|
|||
|
||||
#include "core_dyn_x86/decoder.h"
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
#define DH_FPU_SAVE_REINIT \
|
||||
{ \
|
||||
__asm { \
|
||||
__asm fnsave dyn_dh_fpu.state[0] \
|
||||
} \
|
||||
dyn_dh_fpu.state_used=false; \
|
||||
dyn_dh_fpu.state[0]|=0x3f; \
|
||||
}
|
||||
#else
|
||||
#define DH_FPU_SAVE_REINIT \
|
||||
{ \
|
||||
__asm__ volatile ( \
|
||||
"fnsave (%0) \n" \
|
||||
: \
|
||||
: "m" (dyn_dh_fpu.state[0]) \
|
||||
: "memory" \
|
||||
); \
|
||||
dyn_dh_fpu.state_used=false; \
|
||||
dyn_dh_fpu.state[0]|=0x3f; \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Bits CPU_Core_Dyn_X86_Run(void) {
|
||||
/* Determine the linear address of CS:EIP */
|
||||
restart_core:
|
||||
|
@ -232,7 +266,10 @@ restart_core:
|
|||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
goto restart_core;
|
||||
}
|
||||
if (!chandler) return CPU_Core_Normal_Run();
|
||||
if (!chandler) {
|
||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
||||
return CPU_Core_Normal_Run();
|
||||
}
|
||||
/* Find correct Dynamic Block to run */
|
||||
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
|
||||
if (!block) {
|
||||
|
@ -244,10 +281,15 @@ run_block:
|
|||
switch (ret) {
|
||||
case BR_Iret:
|
||||
#if C_HEAVY_DEBUG
|
||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
||||
if (DEBUG_HeavyIsBreakpoint()) {
|
||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
||||
return debugCallback;
|
||||
}
|
||||
#endif
|
||||
if (!GETFLAG(TF)) goto restart_core;
|
||||
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
|
||||
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
|
||||
DH_FPU_SAVE_REINIT
|
||||
return CBRET_NONE;
|
||||
case BR_Normal:
|
||||
/* Maybe check if we staying in the same page? */
|
||||
|
@ -259,8 +301,12 @@ run_block:
|
|||
#if C_HEAVY_DEBUG
|
||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
||||
#endif
|
||||
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
|
||||
DH_FPU_SAVE_REINIT
|
||||
return CBRET_NONE;
|
||||
case BR_CallBack:
|
||||
if (!dyn_dh_fpu.state_used) return core_dyn.callback;
|
||||
DH_FPU_SAVE_REINIT
|
||||
return core_dyn.callback;
|
||||
case BR_SMCBlock:
|
||||
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
|
||||
|
@ -269,11 +315,13 @@ run_block:
|
|||
case BR_Opcode:
|
||||
CPU_CycleLeft+=CPU_Cycles;
|
||||
CPU_Cycles=1;
|
||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
||||
return CPU_Core_Normal_Run();
|
||||
#if (C_DEBUG)
|
||||
case BR_OpcodeFull:
|
||||
CPU_CycleLeft+=CPU_Cycles;
|
||||
CPU_Cycles=1;
|
||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
||||
return CPU_Core_Full_Run();
|
||||
#endif
|
||||
case BR_Link1:
|
||||
|
@ -291,6 +339,7 @@ run_block:
|
|||
}
|
||||
goto restart_core;
|
||||
}
|
||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
|
@ -366,6 +415,28 @@ void CPU_Core_Dyn_X86_Init(void) {
|
|||
DynRegs[G_EXIT].flags=DYNFLG_HAS16;
|
||||
/* Init the generator */
|
||||
gen_init();
|
||||
|
||||
/* Init the fpu state */
|
||||
dyn_dh_fpu.dh_fpu_enabled=true;
|
||||
dyn_dh_fpu.state_used=false;
|
||||
dyn_dh_fpu.cw=0x37f;
|
||||
#if defined (_MSC_VER)
|
||||
__asm {
|
||||
__asm finit
|
||||
__asm fsave dyn_dh_fpu.state[0]
|
||||
__asm fstcw dyn_dh_fpu.host_cw
|
||||
}
|
||||
#else
|
||||
__asm__ volatile (
|
||||
"finit \n"
|
||||
"fsave (%0) \n"
|
||||
"fstcw (%1) \n"
|
||||
:
|
||||
: "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw)
|
||||
: "memory"
|
||||
);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -378,4 +449,8 @@ void CPU_Core_Dyn_X86_Cache_Close(void) {
|
|||
cache_close();
|
||||
}
|
||||
|
||||
void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) {
|
||||
dyn_dh_fpu.dh_fpu_enabled=dh_fpu;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \
|
||||
dyn_fpu.h
|
||||
dyn_fpu.h dyn_fpu_dh.h
|
|
@ -16,19 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define X86_DYNFPU
|
||||
|
||||
#include "fpu.h"
|
||||
#define DYN_FPU_ESC(code) { \
|
||||
dyn_get_modrm(); \
|
||||
if (decode.modrm.val >= 0xc0) { \
|
||||
gen_call_function((void*)&FPU_ESC ## code ## _Normal,"%Id",decode.modrm.val); \
|
||||
} else { \
|
||||
dyn_fill_ea(); \
|
||||
gen_call_function((void*)&FPU_ESC ## code ## _EA,"%Id%Dd",decode.modrm.val,DREG(EA)); \
|
||||
gen_releasereg(DREG(EA)); \
|
||||
} \
|
||||
}
|
||||
#define X86_DYNFPU_DH_ENABLED
|
||||
|
||||
enum REP_Type {
|
||||
REP_NONE=0,REP_NZ,REP_Z
|
||||
|
@ -152,7 +140,7 @@ static INLINE void dyn_set_eip_last(void) {
|
|||
}
|
||||
|
||||
|
||||
enum save_info_type {exception, cycle_check, normal};
|
||||
enum save_info_type {exception, cycle_check, normal, fpu_restore};
|
||||
|
||||
|
||||
static struct {
|
||||
|
@ -161,6 +149,7 @@ static struct {
|
|||
Bit8u * branch_pos;
|
||||
Bit32u eip_change;
|
||||
Bitu cycles;
|
||||
Bit8u * return_pos;
|
||||
} save_info[512];
|
||||
|
||||
Bitu used_save_info=0;
|
||||
|
@ -220,6 +209,21 @@ static void dyn_fill_blocks(void) {
|
|||
dyn_save_critical_regs();
|
||||
gen_return(BR_Cycles);
|
||||
break;
|
||||
case fpu_restore:
|
||||
dyn_loadstate(&save_info[sct].state);
|
||||
gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4);
|
||||
gen_sop_word(SOP_INC,true,DREG(TMPB));
|
||||
GenReg * gr1=FindDynReg(DREG(TMPB));
|
||||
cache_addb(0xdd); // FRSTOR fpu.state (fpu_restore)
|
||||
cache_addb(0x25);
|
||||
cache_addd((Bit32u)(&(dyn_dh_fpu.state[0])));
|
||||
cache_addb(0x89); // mov fpu.state_used,1
|
||||
cache_addb(0x05|(gr1->index<<3));
|
||||
cache_addd((Bit32u)(&(dyn_dh_fpu.state_used)));
|
||||
gen_releasereg(DREG(TMPB));
|
||||
dyn_synchstate(&save_info[sct].state);
|
||||
gen_create_jump(save_info[sct].return_pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
used_save_info=0;
|
||||
|
@ -1226,9 +1230,22 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef X86_DYNFPU
|
||||
#include "dyn_fpu.h"
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
#include "dyn_fpu_dh.h"
|
||||
#define dh_fpu_startup() { \
|
||||
fpu_used=true; \
|
||||
gen_protectflags(); \
|
||||
gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); \
|
||||
gen_dop_word_imm(DOP_CMP,true,DREG(TMPB),0); \
|
||||
gen_releasereg(DREG(TMPB)); \
|
||||
save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z); \
|
||||
dyn_savestate(&save_info[used_save_info].state); \
|
||||
save_info[used_save_info].return_pos=cache.pos; \
|
||||
save_info[used_save_info].type=fpu_restore; \
|
||||
used_save_info++; \
|
||||
}
|
||||
#endif
|
||||
#include "dyn_fpu.h"
|
||||
|
||||
static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) {
|
||||
Bits i;
|
||||
|
@ -1258,6 +1275,9 @@ static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bit
|
|||
used_save_info++;
|
||||
gen_releasereg(DREG(CYCLES));
|
||||
decode.cycles=0;
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
bool fpu_used=false;
|
||||
#endif
|
||||
while (max_opcodes--) {
|
||||
/* Init prefixes */
|
||||
decode.big_addr=cpu.code.big;
|
||||
|
@ -1467,8 +1487,8 @@ restart_prefix:
|
|||
case 0x8e:dyn_mov_seg_ev();break;
|
||||
/* POP Ev */
|
||||
case 0x8f:dyn_pop_ev();break;
|
||||
//NOP
|
||||
case 0x90:
|
||||
case 0x90: //NOP
|
||||
case 0x9b: //WAIT/FWAIT
|
||||
break;
|
||||
//XCHG ax,reg
|
||||
case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97:
|
||||
|
@ -1575,67 +1595,104 @@ restart_prefix:
|
|||
case 0xd3:dyn_grp2_ev(grp2_cl);break;
|
||||
//FPU
|
||||
#ifdef CPU_FPU
|
||||
#ifdef X86_DYNFPU
|
||||
case 0xd8:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc0();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc0();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc0();
|
||||
break;
|
||||
case 0xd9:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc1();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc1();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc1();
|
||||
break;
|
||||
case 0xda:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc2();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc2();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc2();
|
||||
break;
|
||||
case 0xdb:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc3();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc3();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc3();
|
||||
break;
|
||||
case 0xdc:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc4();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc4();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc4();
|
||||
break;
|
||||
case 0xdd:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc5();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc5();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc5();
|
||||
break;
|
||||
case 0xde:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc6();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc6();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc6();
|
||||
break;
|
||||
case 0xdf:
|
||||
#ifdef X86_DYNFPU_DH_ENABLED
|
||||
if (dyn_dh_fpu.dh_fpu_enabled) {
|
||||
if (fpu_used) dh_fpu_esc7();
|
||||
else {
|
||||
dh_fpu_startup();
|
||||
dh_fpu_esc7();
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
dyn_fpu_esc7();
|
||||
break;
|
||||
#else
|
||||
case 0xd8:
|
||||
DYN_FPU_ESC(0);
|
||||
break;
|
||||
case 0xd9:
|
||||
DYN_FPU_ESC(1);
|
||||
break;
|
||||
case 0xda:
|
||||
DYN_FPU_ESC(2);
|
||||
break;
|
||||
case 0xdb:
|
||||
DYN_FPU_ESC(3);
|
||||
break;
|
||||
case 0xdc:
|
||||
DYN_FPU_ESC(4);
|
||||
break;
|
||||
case 0xdd:
|
||||
DYN_FPU_ESC(5);
|
||||
break;
|
||||
case 0xde:
|
||||
DYN_FPU_ESC(6);
|
||||
break;
|
||||
case 0xdf:
|
||||
dyn_get_modrm();
|
||||
if (decode.modrm.val >= 0xc0) {
|
||||
if (decode.modrm.val == 0xe0) gen_releasereg(DREG(EAX)); /* FSTSW */
|
||||
gen_call_function((void*)&FPU_ESC7_Normal,"%Id",decode.modrm.val);
|
||||
} else {
|
||||
dyn_fill_ea();
|
||||
gen_call_function((void*)&FPU_ESC7_EA,"%Id%Dd",decode.modrm.val,DREG(EA));
|
||||
gen_releasereg(DREG(EA));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
//Loop's
|
||||
//Loops
|
||||
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;
|
||||
case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block;
|
||||
//IN AL/AX,imm
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: cpu.cpp,v 1.86 2006-10-04 19:24:52 c2woody Exp $ */
|
||||
/* $Id: cpu.cpp,v 1.87 2006-10-12 15:18:31 c2woody Exp $ */
|
||||
|
||||
#include <assert.h>
|
||||
#include "dosbox.h"
|
||||
|
@ -56,6 +56,7 @@ void CPU_Core_Simple_Init(void);
|
|||
void CPU_Core_Dyn_X86_Init(void);
|
||||
void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache);
|
||||
void CPU_Core_Dyn_X86_Cache_Close(void);
|
||||
void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu);
|
||||
|
||||
/* In debug mode exceptions are tested and dosbox exits when
|
||||
* a unhandled exception state is detected.
|
||||
|
@ -2060,6 +2061,10 @@ public:
|
|||
#if (C_DYNAMIC_X86)
|
||||
else if (!strcasecmp(core,"dynamic")) {
|
||||
cpudecoder=&CPU_Core_Dyn_X86_Run;
|
||||
CPU_Core_Dyn_X86_SetFPUMode(true);
|
||||
} else if (!strcasecmp(core,"dynamic_nodhfpu")) {
|
||||
cpudecoder=&CPU_Core_Dyn_X86_Run;
|
||||
CPU_Core_Dyn_X86_SetFPUMode(false);
|
||||
} else if (!strcasecmp(core,"auto")) {
|
||||
cpudecoder=&CPU_Core_Normal_Run;
|
||||
CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE;
|
||||
|
@ -2070,7 +2075,7 @@ public:
|
|||
}
|
||||
|
||||
#if (C_DYNAMIC_X86)
|
||||
CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic"));
|
||||
CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu"));
|
||||
#endif
|
||||
|
||||
if(CPU_CycleMax <= 0) CPU_CycleMax = 2500;
|
||||
|
|
|
@ -265,6 +265,9 @@
|
|||
<File
|
||||
RelativePath="..\src\cpu\core_dyn_x86\dyn_fpu.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\cpu\core_dyn_x86\dyn_fpu_dh.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\cpu\core_dyn_x86\helpers.h">
|
||||
</File>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue