1
0
Fork 0

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:
Sebastian Strohhäcker 2006-01-17 20:29:50 +00:00
parent c325a806e2
commit 931561bf3b
4 changed files with 72 additions and 17 deletions

View file

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

View file

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

View file

@ -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);
}

View file

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