1
0
Fork 0

reduce size of exception-check code in the dynamic core

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2429
This commit is contained in:
Sebastian Strohhäcker 2006-01-13 17:29:11 +00:00
parent afb9e84c53
commit c325a806e2
2 changed files with 46 additions and 26 deletions

View file

@ -142,7 +142,10 @@ static INLINE void dyn_set_eip_last(void) {
}
static void DynRunException(void) {
static void 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;
CPU_Exception(cpu.exception.which,cpu.exception.error);
}
@ -151,13 +154,11 @@ static void dyn_check_bool_exception(DynReg * check) {
gen_dop_byte(DOP_OR,check,0,check,0);
branch=gen_create_branch(BR_Z);
dyn_savestate(&state);
dyn_flags_gen_to_host();
dyn_reduce_cycles();
dyn_set_eip_last();
if (!decode.cycles) decode.cycles++;
dyn_save_critical_regs();
gen_call_function((void *)&DynRunException,"");
dyn_flags_host_to_gen();
gen_return(BR_Normal);
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);
dyn_loadstate(&state);
gen_fill_branch(branch);
}
@ -167,13 +168,11 @@ static void dyn_check_bool_exception_al(void) {
cache_addw(0xc00a); // or al, al
branch=gen_create_branch(BR_Z);
dyn_savestate(&state);
dyn_flags_gen_to_host();
dyn_reduce_cycles();
dyn_set_eip_last();
if (!decode.cycles) decode.cycles++;
dyn_save_critical_regs();
gen_call_function((void *)&DynRunException,"");
dyn_flags_host_to_gen();
gen_return(BR_Normal);
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);
dyn_loadstate(&state);
gen_fill_branch(branch);
}
@ -1122,8 +1121,7 @@ static void dyn_ret_far(Bitu bytes) {
dyn_flags_gen_to_host();
dyn_save_critical_regs();
gen_call_function((void*)&CPU_RET,"%Id%Id%Drd",decode.big_op,bytes,DREG(TMPW));
dyn_flags_host_to_gen();
gen_return(BR_Normal);
gen_return_fast(BR_Normal);
dyn_closeblock();
}
@ -1136,8 +1134,7 @@ static void dyn_call_far_imm(void) {
dyn_flags_gen_to_host();
dyn_save_critical_regs();
gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW));
dyn_flags_host_to_gen();
gen_return(BR_Normal);
gen_return_fast(BR_Normal);
dyn_closeblock();
}
@ -1151,8 +1148,7 @@ static void dyn_jmp_far_imm(void) {
dyn_flags_gen_to_host();
dyn_save_critical_regs();
gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW));
dyn_flags_host_to_gen();
gen_return(BR_Normal);
gen_return_fast(BR_Normal);
dyn_closeblock();
}
@ -1163,8 +1159,7 @@ static void dyn_iret(void) {
dyn_set_eip_last_end(DREG(TMPW));
dyn_save_critical_regs();
gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW));
dyn_flags_host_to_gen();
gen_return(BR_Normal);
gen_return_fast(BR_Normal);
dyn_closeblock();
}
@ -1175,8 +1170,7 @@ static void dyn_interrupt(Bitu num) {
dyn_set_eip_last_end(DREG(TMPW));
dyn_save_critical_regs();
gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Drd",num,CPU_INT_SOFTWARE,DREG(TMPW));
dyn_flags_host_to_gen();
gen_return(BR_Normal);
gen_return_fast(BR_Normal);
dyn_closeblock();
}

View file

@ -591,6 +591,7 @@ static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg
static void gen_call_function(void * func,char * ops,...) {
Bits paramcount=0;
bool release_flags=false;
struct ParamInfo {
char * line;
Bitu value;
@ -663,6 +664,9 @@ static void gen_call_function(void * func,char * ops,...) {
retparam =&pinfo[pindex];
pinfo[pindex].line=scan;
break;
case 'F': /* Release flags from stack */
release_flags=true;
break;
default:
IllegalOption("gen_call_function unknown param");
}
@ -677,7 +681,10 @@ static void gen_call_function(void * func,char * ops,...) {
/* Restore the params of the stack */
if (paramcount) {
cache_addw(0xc483); //add ESP,imm byte
cache_addb(paramcount*4);
cache_addb(paramcount*4+(release_flags?4:0));
} else if (release_flags) {
cache_addw(0xc483); //add ESP,imm byte
cache_addb(4);
}
/* Save the return value in correct register */
if (retparam) {
@ -838,8 +845,27 @@ static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) {
static void gen_return(BlockReturn retcode) {
gen_protectflags();
cache_addb(0x59); //POP ECX, the flags
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
}
static void gen_return_fast(BlockReturn retcode,bool popflags=true) {
if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast");
cache_addw(0x0d8b); //MOV ECX, the flags
cache_addd((Bit32u)&cpu_regs.flags);
if (popflags) {
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);
}
cache_addb(0xc3); //RET
}