diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 6450a943..f63d9158 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -247,8 +247,8 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) { { \ __asm__ volatile ( \ "fnsave %0 \n" \ + : "=m" (dyn_dh_fpu.state[0]) \ : \ - : "m" (dyn_dh_fpu.state[0]) \ : "memory" \ ); \ dyn_dh_fpu.state_used=false; \ @@ -303,7 +303,10 @@ run_block: } #endif if (!GETFLAG(TF)) { - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; + if (GETFLAG(IF) && PIC_IRQCheck) { + if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT + return CBRET_NONE; + } goto restart_core; } cpudecoder=CPU_Core_Dyn_X86_Trap_Run; @@ -450,8 +453,8 @@ void CPU_Core_Dyn_X86_Init(void) { "finit \n" "fsave %0 \n" "fstcw %1 \n" + : "=m" (dyn_dh_fpu.state[0]), "=m" (dyn_dh_fpu.host_cw) : - : "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw) : "memory" ); #endif @@ -468,8 +471,62 @@ void CPU_Core_Dyn_X86_Cache_Close(void) { cache_close(); } +void CPU_Core_Dyn_X86_Cache_Reset(void) { + cache_reset(); +} + void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) { dyn_dh_fpu.dh_fpu_enabled=dh_fpu; } +Bit32u fpu_state[32]; + +void CPU_Core_Dyn_X86_SaveDHFPUState(void) { + if (dyn_dh_fpu.dh_fpu_enabled) { + if (dyn_dh_fpu.state_used!=0) { +#if defined (_MSC_VER) + __asm { + __asm fsave fpu_state[0] + __asm finit + } +#else + __asm__ volatile ( + "fsave %0 \n" + "finit \n" + : "=m" (fpu_state[0]) + : + : "memory" + ); +#endif + } + } +} + +void CPU_Core_Dyn_X86_RestoreDHFPUState(void) { + if (dyn_dh_fpu.dh_fpu_enabled) { + if (dyn_dh_fpu.state_used!=0) { +#if defined (_MSC_VER) + __asm { + __asm frstor fpu_state[0] + } +#else + __asm__ volatile ( + "frstor %0 \n" + : + : "m" (fpu_state[0]) + : + ); +#endif + } + } +} + +#else + +void CPU_Core_Dyn_X86_SaveDHFPUState(void) { +} + +void CPU_Core_Dyn_X86_RestoreDHFPUState(void) { +} + #endif diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 6eeeeae7..2bda44cd 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -569,3 +569,75 @@ static void cache_close(void) { cache_code_link_blocks = NULL; cache_initialized = false; */ } + +static void cache_reset(void) { + if (cache_initialized) { + for (;;) { + if (cache.used_pages) { + CodePageHandler * cpage=cache.used_pages; + CodePageHandler * npage=cache.used_pages->next; + cpage->ClearRelease(); + delete cpage; + cache.used_pages=npage; + } else break; + } + + if (cache_blocks == NULL) { + cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock)); + if(!cache_blocks) E_Exit("Allocating cache_blocks has failed"); + } + memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS); + cache.block.free=&cache_blocks[0]; + for (Bits i=0;icache.start=&cache_code[0]; + block->cache.size=CACHE_TOTAL; + block->cache.next=0; //Last block in the list + + /* Setup the default blocks for block linkage returns */ + cache.pos=&cache_code_link_blocks[0]; + link_blocks[0].cache.start=cache.pos; + gen_return(BR_Link1); + cache.pos=&cache_code_link_blocks[32]; + link_blocks[1].cache.start=cache.pos; + gen_return(BR_Link2); + cache.free_pages=0; + cache.last_page=0; + cache.used_pages=0; + /* Setup the code pages */ + for (Bitu i=0;inext=cache.free_pages; + cache.free_pages=newpage; + } + } +}