handle modification of the running dynamic core code block
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2430
This commit is contained in:
parent
c325a806e2
commit
931561bf3b
4 changed files with 72 additions and 17 deletions
|
@ -46,15 +46,15 @@
|
|||
#include "inout.h"
|
||||
|
||||
#ifdef CHECKED_MEMORY_ACCESS
|
||||
#define CACHE_TOTAL (1024*1024)
|
||||
#define CACHE_MAXSIZE (4096*3)
|
||||
#define CACHE_PAGES (128*2)
|
||||
#define CACHE_MAXSIZE (4096*2)
|
||||
#else
|
||||
#define CACHE_TOTAL (512*1024)
|
||||
#define CACHE_PAGES (128)
|
||||
#define CACHE_MAXSIZE (4096)
|
||||
#endif
|
||||
#define CACHE_TOTAL (CACHE_PAGES*4096)
|
||||
#define CACHE_BLOCKS (32*1024)
|
||||
#define CACHE_ALIGN (16)
|
||||
#define CACHE_PAGES (128)
|
||||
#define DYN_HASH_SHIFT (4)
|
||||
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
|
||||
#define DYN_LINKS (16)
|
||||
|
@ -119,8 +119,12 @@ enum BlockReturn {
|
|||
BR_OpcodeFull,
|
||||
#endif
|
||||
BR_CallBack,
|
||||
BR_SMCBlock
|
||||
};
|
||||
|
||||
#define SMC_CURRENT_BLOCK 0xffff
|
||||
|
||||
|
||||
#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support
|
||||
#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support
|
||||
#define DYNFLG_LOAD 0x4 //Load value when accessed
|
||||
|
@ -252,6 +256,10 @@ run_block:
|
|||
return CBRET_NONE;
|
||||
case BR_CallBack:
|
||||
return core_dyn.callback;
|
||||
case BR_SMCBlock:
|
||||
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
|
||||
cpu.exception.which=0;
|
||||
// fallthrough, let the normal core handle the block-modifying instruction
|
||||
case BR_Opcode:
|
||||
CPU_CycleLeft+=CPU_Cycles;
|
||||
CPU_Cycles=1;
|
||||
|
|
|
@ -66,21 +66,27 @@ public:
|
|||
memset(&hash_map,0,sizeof(hash_map));
|
||||
memset(&write_map,0,sizeof(write_map));
|
||||
}
|
||||
void InvalidateRange(Bitu start,Bitu end) {
|
||||
bool InvalidateRange(Bitu start,Bitu end) {
|
||||
Bits index=1+(start>>DYN_HASH_SHIFT);
|
||||
bool is_current_block=false;
|
||||
Bit32u ip_point=SegPhys(cs)+reg_eip;
|
||||
ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff);
|
||||
while (index>=0) {
|
||||
Bitu map=0;
|
||||
for (Bitu count=start;count<=end;count++) map+=write_map[count];
|
||||
if (!map) return;
|
||||
if (!map) return is_current_block;
|
||||
CacheBlock * block=hash_map[index];
|
||||
while (block) {
|
||||
CacheBlock * nextblock=block->hash.next;
|
||||
if (start<=block->page.end && end>=block->page.start)
|
||||
if (start<=block->page.end && end>=block->page.start) {
|
||||
if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true;
|
||||
block->Clear();
|
||||
}
|
||||
block=nextblock;
|
||||
}
|
||||
index--;
|
||||
}
|
||||
return is_current_block;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val){
|
||||
addr&=4095;
|
||||
|
@ -109,6 +115,45 @@ public:
|
|||
if (!active_count) Release();
|
||||
} else InvalidateRange(addr,addr+3);
|
||||
}
|
||||
bool writeb_checked(PhysPt addr,Bitu val) {
|
||||
addr&=4095;
|
||||
host_writeb(hostmem+addr,val);
|
||||
if (!*(Bit8u*)&write_map[addr]) {
|
||||
if (active_blocks) return false;
|
||||
active_count--;
|
||||
if (!active_count) Release();
|
||||
} else if (InvalidateRange(addr,addr)) {
|
||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool writew_checked(PhysPt addr,Bitu val) {
|
||||
addr&=4095;
|
||||
host_writew(hostmem+addr,val);
|
||||
if (!*(Bit16u*)&write_map[addr]) {
|
||||
if (active_blocks) return false;
|
||||
active_count--;
|
||||
if (!active_count) Release();
|
||||
} else if (InvalidateRange(addr,addr+1)) {
|
||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool writed_checked(PhysPt addr,Bitu val) {
|
||||
addr&=4095;
|
||||
host_writed(hostmem+addr,val);
|
||||
if (!*(Bit32u*)&write_map[addr]) {
|
||||
if (active_blocks) return false;
|
||||
active_count--;
|
||||
if (!active_count) Release();
|
||||
} else if (InvalidateRange(addr,addr+3)) {
|
||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void AddCacheBlock(CacheBlock * block) {
|
||||
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
|
||||
block->hash.next=hash_map[index];
|
||||
|
|
|
@ -142,11 +142,13 @@ static INLINE void dyn_set_eip_last(void) {
|
|||
}
|
||||
|
||||
|
||||
static void DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) {
|
||||
static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) {
|
||||
reg_flags=(dflags&FMASK_TEST) | (reg_flags&(~FMASK_TEST));
|
||||
reg_eip+=eip_add;
|
||||
CPU_Cycles-=cycle_sub;
|
||||
if (cpu.exception.which==SMC_CURRENT_BLOCK) return BR_SMCBlock;
|
||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
||||
return BR_Normal;
|
||||
}
|
||||
|
||||
static void dyn_check_bool_exception(DynReg * check) {
|
||||
|
@ -158,7 +160,7 @@ static void dyn_check_bool_exception(DynReg * check) {
|
|||
dyn_save_critical_regs();
|
||||
if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles);
|
||||
else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles);
|
||||
gen_return_fast(BR_Normal,false);
|
||||
gen_return_fast(BR_Normal,true);
|
||||
dyn_loadstate(&state);
|
||||
gen_fill_branch(branch);
|
||||
}
|
||||
|
@ -172,7 +174,7 @@ static void dyn_check_bool_exception_al(void) {
|
|||
dyn_save_critical_regs();
|
||||
if (cpu.code.big) gen_call_function((void *)&DynRunException,"%Id%Id%F",decode.op_start-decode.code_start,decode.cycles);
|
||||
else gen_call_function((void *)&DynRunException,"%Iw%Id%F",(decode.op_start-decode.code_start)&0xffff,decode.cycles);
|
||||
gen_return_fast(BR_Normal,false);
|
||||
gen_return_fast(BR_Normal,true);
|
||||
dyn_loadstate(&state);
|
||||
gen_fill_branch(branch);
|
||||
}
|
||||
|
|
|
@ -853,18 +853,18 @@ static void gen_return(BlockReturn retcode) {
|
|||
cache_addb(0xc3); //RET
|
||||
}
|
||||
|
||||
static void gen_return_fast(BlockReturn retcode,bool popflags=true) {
|
||||
static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) {
|
||||
if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast");
|
||||
cache_addw(0x0d8b); //MOV ECX, the flags
|
||||
cache_addd((Bit32u)&cpu_regs.flags);
|
||||
if (popflags) {
|
||||
if (!ret_exception) {
|
||||
cache_addw(0xc483); //ADD ESP,4
|
||||
cache_addb(0x4);
|
||||
}
|
||||
if (retcode==0) cache_addw(0xc033); //MOV EAX, 0
|
||||
else {
|
||||
cache_addb(0xb8); //MOV EAX, retcode
|
||||
cache_addd(retcode);
|
||||
if (retcode==0) cache_addw(0xc033); //MOV EAX, 0
|
||||
else {
|
||||
cache_addb(0xb8); //MOV EAX, retcode
|
||||
cache_addd(retcode);
|
||||
}
|
||||
}
|
||||
cache_addb(0xc3); //RET
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue