revision 941:c67574ed4355
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 941:c67574ed4355 |
parent | 940:81e0d3051d5f |
child | 942:05e5d6a62e67 |
author | nkeynes |
date | Sat Jan 03 08:55:15 2009 +0000 (15 years ago) |
branch | lxdream-mem |
Implement CORE_EXIT_EXCEPTION for use when direct frame messing about doesn't work
src/sh4/sh4.c | view | annotate | diff | log | ||
src/sh4/sh4trans.c | view | annotate | diff | log | ||
src/sh4/sh4trans.h | view | annotate | diff | log | ||
src/sh4/sh4x86.in | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4.c Sat Jan 03 07:30:26 2009 +00001.2 +++ b/src/sh4/sh4.c Sat Jan 03 08:55:15 2009 +00001.3 @@ -202,7 +202,11 @@1.4 if( sh4_running ) {1.5 #ifdef SH4_TRANSLATOR1.6 if( sh4_use_translator ) {1.7 - sh4_translate_exit_recover();1.8 + if( exit_code == CORE_EXIT_EXCEPTION ) {1.9 + sh4_translate_exception_exit_recover();1.10 + } else {1.11 + sh4_translate_exit_recover();1.12 + }1.13 }1.14 #endif1.15 // longjmp back into sh4_run_slice
2.1 --- a/src/sh4/sh4trans.c Sat Jan 03 07:30:26 2009 +00002.2 +++ b/src/sh4/sh4trans.c Sat Jan 03 08:55:15 2009 +00002.3 @@ -158,6 +158,16 @@2.4 sh4r.pc += (recovery->sh4_icount<<1);2.5 }2.7 +/**2.8 + * Same as sh4_translate_run_recovery, but is used to recover from a taken2.9 + * exception - that is, it fixes sh4r.spc rather than sh4r.pc2.10 + */2.11 +void sh4_translate_run_exception_recovery( xlat_recovery_record_t recovery )2.12 +{2.13 + sh4r.slice_cycle += (recovery->sh4_icount * sh4_cpu_period);2.14 + sh4r.spc += (recovery->sh4_icount<<1);2.15 +}2.16 +2.17 void sh4_translate_exit_recover( )2.18 {2.19 void *code = xlat_get_code_by_vma( sh4r.pc );2.20 @@ -175,6 +185,24 @@2.21 }2.22 }2.24 +void sh4_translate_exception_exit_recover( )2.25 +{2.26 + void *code = xlat_get_code_by_vma( sh4r.spc );2.27 + if( code != NULL ) {2.28 + uint32_t size = xlat_get_code_size( code );2.29 + void *pc = xlat_get_native_pc( code, size );2.30 + if( pc != NULL ) {2.31 + // could be null if we're not actually running inside the translator2.32 + xlat_recovery_record_t recover = xlat_get_pre_recovery(code, pc);2.33 + if( recover != NULL ) {2.34 + // Can be null if there is no recovery necessary2.35 + sh4_translate_run_exception_recovery(recover);2.36 + }2.37 + }2.38 + }2.39 +2.40 +}2.41 +2.42 void FASTCALL sh4_translate_breakpoint_hit(uint32_t pc)2.43 {2.44 if( sh4_starting && sh4r.slice_cycle == 0 && pc == sh4r.pc ) {
3.1 --- a/src/sh4/sh4trans.h Sat Jan 03 07:30:26 2009 +00003.2 +++ b/src/sh4/sh4trans.h Sat Jan 03 08:55:15 2009 +00003.3 @@ -113,6 +113,12 @@3.4 void sh4_translate_exit_recover( );3.6 /**3.7 + * Called when doing a break out of the translator following a taken exception -3.8 + * finalizes the system state up to the start of the current instruction.3.9 + */3.10 +void sh4_translate_exception_exit_recover( );3.11 +3.12 +/**3.13 * From within the translator, exit the current block at the end of the3.14 * current instruction, flush the translation cache (completely)3.15 * @return TRUE to perform a vm-exit/continue after the flush
4.1 --- a/src/sh4/sh4x86.in Sat Jan 03 07:30:26 2009 +00004.2 +++ b/src/sh4/sh4x86.in Sat Jan 03 08:55:15 2009 +00004.3 @@ -292,12 +292,18 @@4.4 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so4.5 * don't waste the cycles expecting them. Otherwise we need to save the exception pointer.4.6 */4.7 +4.8 +#ifdef HAVE_FRAME_ADDRESS4.9 #define _CALL_READ(addr_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \4.10 call_func1_r32disp8(R_ECX, MEM_REGION_PTR(fn), addr_reg); } else { \4.11 call_func1_r32disp8_exc(R_ECX, MEM_REGION_PTR(fn), addr_reg, pc); }4.12 #define _CALL_WRITE(addr_reg, val_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \4.13 call_func2_r32disp8(R_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg); } else { \4.14 - call_func2_r32disp8_exc(R_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg, pc); }4.15 + call_func2_r32disp8_exc(R_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg, pc); }4.16 +#else4.17 +#define _CALL_READ(addr_reg, fn) call_func1_r32disp8(R_ECX, MEM_REGION_PTR(fn), addr_reg)4.18 +#define _CALL_WRITE(addr_reg, val_reg, fn) call_func2_r32disp8(R_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg)4.19 +#endif4.21 #define MEM_READ_BYTE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_byte); MEM_RESULT(value_reg)4.22 #define MEM_READ_WORD( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_word); MEM_RESULT(value_reg)
.