Search
lxdream.org :: lxdream/src/sh4/sh4trans.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4trans.c
changeset 577:a181aeacd6e8
prev571:9bc09948d0f2
next585:371342a39c09
author nkeynes
date Mon Jan 14 10:23:49 2008 +0000 (16 years ago)
branchlxdream-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 +0000
1.2 +++ b/src/sh4/sh4trans.c Mon Jan 14 10:23:49 2008 +0000
1.3 @@ -42,7 +42,19 @@
1.4 }
1.5 }
1.6
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.21
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.35
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.49
1.50 /**
1.51 - * Translate a linear basic block to a temporary buffer, execute it, and return
1.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 updates
1.78 * sh4r.pc and sh4r.slice_cycle according to the currently executing
1.79 * instruction. In future this may be more sophisticated (ie will
1.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_slice
1.97 - longjmp(xlat_jmp_buf, 1);
1.98 + longjmp(xlat_jmp_buf, XLAT_EXIT_CONTINUE);
1.99 }
1.100
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 necessary
1.110 + sh4_translate_run_recovery(recover);
1.111 + }
1.112 + // finally longjmp back into sh4_xlat_run_slice
1.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 the
1.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 necessary
1.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.142
1.143 if( !IS_IN_ICACHE(vma) ) {
1.144 + if( vma > 0xFFFFFF00 ) {
1.145 + // lxdream hook
1.146 + return NULL;
1.147 + }
1.148 if( !mmu_update_icache(sh4r.pc) ) {
1.149 // fault - off to the fault handler
1.150 if( !mmu_update_icache(sh4r.pc) ) {
.