Search
lxdream.org :: lxdream :: r941:c67574ed4355
lxdream 0.9.1
released Jun 29
Download Now
changeset941:c67574ed4355 lxdream-mem
parent940:81e0d3051d5f
child942:05e5d6a62e67
authornkeynes
dateSat Jan 03 08:55:15 2009 +0000 (15 years ago)
branchlxdream-mem
Implement CORE_EXIT_EXCEPTION for use when direct frame messing about doesn't work
src/sh4/sh4.c
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.in
1.1 --- a/src/sh4/sh4.c Sat Jan 03 07:30:26 2009 +0000
1.2 +++ b/src/sh4/sh4.c Sat Jan 03 08:55:15 2009 +0000
1.3 @@ -202,7 +202,11 @@
1.4 if( sh4_running ) {
1.5 #ifdef SH4_TRANSLATOR
1.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 #endif
1.15 // longjmp back into sh4_run_slice
2.1 --- a/src/sh4/sh4trans.c Sat Jan 03 07:30:26 2009 +0000
2.2 +++ b/src/sh4/sh4trans.c Sat Jan 03 08:55:15 2009 +0000
2.3 @@ -158,6 +158,16 @@
2.4 sh4r.pc += (recovery->sh4_icount<<1);
2.5 }
2.6
2.7 +/**
2.8 + * Same as sh4_translate_run_recovery, but is used to recover from a taken
2.9 + * exception - that is, it fixes sh4r.spc rather than sh4r.pc
2.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.23
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 translator
2.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 necessary
2.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 +0000
3.2 +++ b/src/sh4/sh4trans.h Sat Jan 03 08:55:15 2009 +0000
3.3 @@ -113,6 +113,12 @@
3.4 void sh4_translate_exit_recover( );
3.5
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 the
3.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 +0000
4.2 +++ b/src/sh4/sh4x86.in Sat Jan 03 08:55:15 2009 +0000
4.3 @@ -292,12 +292,18 @@
4.4 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so
4.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_ADDRESS
4.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 +#else
4.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 +#endif
4.20
4.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)
.