From 2773ef7adf3171b171290ac07d3acef6ef34bd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Strohh=C3=A4cker?= Date: Sat, 21 Jul 2007 08:46:50 +0000 Subject: [PATCH] fix some register backsave (thanks crazyc for noting); skip addr reg saving if possible Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2929 --- src/cpu/core_dynrec/decoder_basic.h | 4 ++++ src/cpu/core_dynrec/decoder_opcodes.h | 3 ++- src/cpu/core_dynrec/dyn_fpu.h | 2 ++ src/cpu/core_dynrec/risc_x64.h | 7 ++++++- src/cpu/core_dynrec/risc_x86.h | 7 ++++++- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index d0cd4e2a..2ec74b85 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -1000,12 +1000,16 @@ static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { // save back the address register static void gen_protect_addr_reg(void) { +#ifdef DRC_PROTECT_ADDR_REG gen_mov_word_from_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +#endif } // restore the address register static void gen_restore_addr_reg(void) { +#ifdef DRC_PROTECT_ADDR_REG gen_mov_word_to_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); +#endif } // save back an arbitrary register diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 7ebe59a5..29ba55c9 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -814,7 +814,7 @@ static bool dyn_grp4_ev(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - if (decode.modrm.reg<2) gen_protect_addr_reg(); + if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); @@ -847,6 +847,7 @@ static bool dyn_grp4_ev(void) { case 0x3: // CALL Ep case 0x5: // JMP Ep if (!decode.big_op) gen_extend_word(false,FC_OP1); + if (decode.modrm.mod<3) gen_restore_addr_reg(); gen_protect_reg(FC_OP1); gen_add_imm(FC_ADDR,decode.big_op?4:2); dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); diff --git a/src/cpu/core_dynrec/dyn_fpu.h b/src/cpu/core_dynrec/dyn_fpu.h index 6d7ad518..8491da5d 100644 --- a/src/cpu/core_dynrec/dyn_fpu.h +++ b/src/cpu/core_dynrec/dyn_fpu.h @@ -149,8 +149,10 @@ static void dyn_fpu_esc1(){ gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); gen_add_imm(FC_OP1,decode.modrm.rm); gen_and_imm(FC_OP1,7); + gen_protect_reg(FC_OP1); gen_call_function_raw((void*)&FPU_PREP_PUSH); gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); + gen_restore_reg(FC_OP1); gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); break; case 0x01: /* FXCH STi */ diff --git a/src/cpu/core_dynrec/risc_x64.h b/src/cpu/core_dynrec/risc_x64.h index aa7bc2b9..b74ccce6 100644 --- a/src/cpu/core_dynrec/risc_x64.h +++ b/src/cpu/core_dynrec/risc_x64.h @@ -20,6 +20,9 @@ // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + // try to use non-flags generating functions if possible // #define DRC_FLAGS_INVALIDATION @@ -45,7 +48,9 @@ typedef Bit8u HostReg; // register that holds function return values #define FC_RETOP HOST_EAX -// register used for address calculations, +// register used for address calculations, if the ABI does not +// state that this register is preserved across function calls +// then define DRC_PROTECT_ADDR_REG above #define FC_ADDR HOST_EBX // register that holds the first parameter diff --git a/src/cpu/core_dynrec/risc_x86.h b/src/cpu/core_dynrec/risc_x86.h index 98dd3b60..4b5759e3 100644 --- a/src/cpu/core_dynrec/risc_x86.h +++ b/src/cpu/core_dynrec/risc_x86.h @@ -20,6 +20,9 @@ // some configuring defines that specify the capabilities of this architecture // or aspects of the recompiling +// protect FC_ADDR over function calls if necessaray +// #define DRC_PROTECT_ADDR_REG + // try to use non-flags generating functions if possible #define DRC_FLAGS_INVALIDATION @@ -52,7 +55,9 @@ enum HostReg { // register that holds function return values #define FC_RETOP HOST_EAX -// register used for address calculations, +// register used for address calculations, if the ABI does not +// state that this register is preserved across function calls +// then define DRC_PROTECT_ADDR_REG above #define FC_ADDR HOST_EBX // register that holds the first parameter