filename | src/sh4/sh4trans.c |
changeset | 577:a181aeacd6e8 |
prev | 571:9bc09948d0f2 |
next | 585:371342a39c09 |
author | nkeynes |
date | Mon Jan 14 10:23:49 2008 +0000 (16 years ago) |
branch | lxdream-mmu |
permissions | -rw-r--r-- |
last change | Remove asm file and convert to inline (easier to cope with platform conventions) Add breakpoint support Add MMU store-queue support |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4trans.c Thu Jan 10 08:28:37 2008 +00001.2 +++ b/src/sh4/sh4trans.c Mon Jan 14 10:23:49 2008 +00001.3 @@ -42,7 +42,19 @@1.4 }1.5 }1.7 - int jmp = setjmp(xlat_jmp_buf);1.8 + switch( setjmp(xlat_jmp_buf) ) {1.9 + case XLAT_EXIT_BREAKPOINT:1.10 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );1.11 + /* fallthrough */1.12 + case XLAT_EXIT_HALT:1.13 + if( sh4r.sh4_state != SH4_STATE_STANDBY ) {1.14 + TMU_run_slice( sh4r.slice_cycle );1.15 + SCIF_run_slice( sh4r.slice_cycle );1.16 + dreamcast_stop();1.17 + return sh4r.slice_cycle;1.18 + }1.19 + break;1.20 + }1.22 void * (*code)() = NULL;1.23 while( sh4r.slice_cycle < nanosecs ) {1.24 @@ -94,7 +106,7 @@1.25 {1.26 sh4addr_t pc = start;1.27 sh4addr_t lastpc = (pc&0xFFFFF000)+0x1000;1.28 - int done;1.29 + int done, i;1.30 xlat_cache_block_t block = xlat_start_block( start );1.31 xlat_output = (uint8_t *)block->code;1.32 xlat_recovery_posn = 0;1.33 @@ -102,6 +114,13 @@1.34 sh4_translate_begin_block(pc);1.36 do {1.37 + /* check for breakpoints at this pc */1.38 + for( i=0; i<sh4_breakpoint_count; i++ ) {1.39 + if( sh4_breakpoints[i].address == pc ) {1.40 + sh4_translate_emit_breakpoint(pc);1.41 + break;1.42 + }1.43 + }1.44 if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {1.45 uint8_t *oldstart = block->code;1.46 block = xlat_extend_block( xlat_output - oldstart + MAX_INSTRUCTION_SIZE );1.47 @@ -139,32 +158,6 @@1.48 }1.50 /**1.51 - * Translate a linear basic block to a temporary buffer, execute it, and return1.52 - * the result of the execution. The translation is discarded.1.53 - */1.54 -void *sh4_translate_and_run( sh4addr_t start )1.55 -{1.56 - unsigned char buf[65536];1.57 -1.58 - sh4addr_t pc = start;1.59 - int done;1.60 - xlat_output = buf;1.61 - uint8_t *eob = xlat_output + sizeof(buf);1.62 -1.63 - sh4_translate_begin_block(pc);1.64 -1.65 - while( (done = sh4_translate_instruction( pc )) == 0 ) {1.66 - assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );1.67 - pc += 2;1.68 - }1.69 - pc+=2;1.70 - sh4_translate_end_block(pc);1.71 -1.72 - void * (*code)() = (void *)buf;1.73 - return code();1.74 -}1.75 -1.76 -/**1.77 * "Execute" the supplied recovery record. Currently this only updates1.78 * sh4r.pc and sh4r.slice_cycle according to the currently executing1.79 * instruction. In future this may be more sophisticated (ie will1.80 @@ -179,10 +172,8 @@1.81 void sh4_translate_unwind_stack( gboolean abort_after, unwind_thunk_t thunk )1.82 {1.83 void *pc = xlat_get_native_pc();1.84 - if( pc == NULL ) {1.85 - // This should never happen - indicative of a bug somewhere.1.86 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");1.87 - }1.88 +1.89 + assert( pc != NULL );1.90 void *code = xlat_get_code( sh4r.pc );1.91 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);1.92 if( recover != NULL ) {1.93 @@ -193,9 +184,24 @@1.94 thunk();1.95 }1.96 // finally longjmp back into sh4_xlat_run_slice1.97 - longjmp(xlat_jmp_buf, 1);1.98 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);1.99 }1.101 +void sh4_translate_exit( int exit_code )1.102 +{1.103 + void *pc = xlat_get_native_pc();1.104 + assert(pc != NULL);1.105 +1.106 + void *code = xlat_get_code( sh4r.pc );1.107 + xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);1.108 + if( recover != NULL ) {1.109 + // Can be null if there is no recovery necessary1.110 + sh4_translate_run_recovery(recover);1.111 + }1.112 + // finally longjmp back into sh4_xlat_run_slice1.113 + longjmp(xlat_jmp_buf, exit_code);1.114 +}1.115 +1.116 /**1.117 * Exit the current block at the end of the current instruction, flush the1.118 * translation cache (completely) and return control to sh4_xlat_run_slice.1.119 @@ -210,17 +216,15 @@1.120 void sh4_translate_flush_cache()1.121 {1.122 void *pc = xlat_get_native_pc();1.123 - if( pc == NULL ) {1.124 - // This should never happen - indicative of a bug somewhere.1.125 - FATAL("Attempted to unwind stack, but translator is not running or stack is corrupt");1.126 - }1.127 + assert( pc != NULL );1.128 +1.129 void *code = xlat_get_code( sh4r.pc );1.130 xlat_recovery_record_t recover = xlat_get_recovery(code, pc, TRUE);1.131 if( recover != NULL ) {1.132 // Can be null if there is no recovery necessary1.133 sh4_translate_run_recovery(recover);1.134 xlat_flush_cache();1.135 - longjmp(xlat_jmp_buf, 1);1.136 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);1.137 } else {1.138 xlat_flush_cache();1.139 return;1.140 @@ -232,6 +236,10 @@1.141 void *result = NULL;1.143 if( !IS_IN_ICACHE(vma) ) {1.144 + if( vma > 0xFFFFFF00 ) {1.145 + // lxdream hook1.146 + return NULL;1.147 + }1.148 if( !mmu_update_icache(sh4r.pc) ) {1.149 // fault - off to the fault handler1.150 if( !mmu_update_icache(sh4r.pc) ) {
.