1
0
Fork 0

small recompiler fixes (missing host fpu usage check; assembler output update) and enhancements

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3752
This commit is contained in:
Sebastian Strohhäcker 2011-09-07 18:43:03 +00:00
parent 6dfe1d9dcf
commit eb395f5add
2 changed files with 132 additions and 3 deletions

View file

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

View file

@ -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;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].link[0].to=(CacheBlock *)1;
cache_blocks[i].link[1].to=(CacheBlock *)1;
cache_blocks[i].cache.next=&cache_blocks[i+1];
}
if (cache_code_start_ptr==NULL) {
#if defined (WIN32)
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!cache_code_start_ptr)
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#else
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#endif
if (!cache_code_start_ptr) E_Exit("Allocating dynamic core cache memory failed");
cache_code=(Bit8u*)(((int)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
cache_code_link_blocks=cache_code;
cache_code+=PAGESIZE_TEMP;
#if (C_HAVE_MPROTECT)
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
LOG_MSG("Setting excute permission on the code cache has failed!");
#endif
}
CacheBlock * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.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;i<CACHE_PAGES;i++) {
CodePageHandler * newpage=new CodePageHandler();
newpage->next=cache.free_pages;
cache.free_pages=newpage;
}
}
}