filename | src/sh4/sh4trans.c |
changeset | 408:af496b734734 |
prev | 398:16b0856ea511 |
next | 410:5f8413358e7f |
author | nkeynes |
date | Fri Sep 28 07:27:20 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Change block signature to return pointer to next block (if known) Rewrite block-exit code |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4trans.c Wed Sep 19 12:09:33 2007 +00001.2 +++ b/src/sh4/sh4trans.c Fri Sep 28 07:27:20 2007 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: sh4trans.c,v 1.4 2007-09-19 12:09:33 nkeynes Exp $1.6 + * $Id: sh4trans.c,v 1.5 2007-09-28 07:27:20 nkeynes Exp $1.7 *1.8 * SH4 translation core module. This part handles the non-target-specific1.9 * section of the translation.1.10 @@ -37,38 +37,36 @@1.11 }1.12 }1.14 + void * (*code)() = NULL;1.15 while( sh4r.slice_cycle < nanosecs ) {1.16 - if( SH4_EVENT_PENDING() ) {1.17 + if( sh4r.event_pending <= sh4r.slice_cycle ) {1.18 if( sh4r.event_types & PENDING_EVENT ) {1.19 event_execute();1.20 }1.21 /* Eventq execute may (quite likely) deliver an immediate IRQ */1.22 if( sh4r.event_types & PENDING_IRQ ) {1.23 sh4_accept_interrupt();1.24 + code = NULL;1.25 }1.26 }1.27 +1.28 + if( code ) { // fast path1.29 + code = code();1.30 + } else {1.31 + if( sh4r.pc > 0xFFFFFF00 ) {1.32 + syscall_invoke( sh4r.pc );1.33 + sh4r.in_delay_slot = 0;1.34 + sh4r.pc = sh4r.pr;1.35 + }1.37 - if( sh4r.pc > 0xFFFFFF00 ) {1.38 - syscall_invoke( sh4r.pc );1.39 - sh4r.in_delay_slot = 0;1.40 - sh4r.pc = sh4r.pr;1.41 + code = xlat_get_code(sh4r.pc);1.42 + if( code == NULL ) {1.43 + code = sh4_translate_basic_block( sh4r.pc );1.44 + }1.45 + code = code();1.46 }1.47 -1.48 - gboolean (*code)() = xlat_get_code(sh4r.pc);1.49 - if( code == NULL ) {1.50 - code = sh4_translate_basic_block( sh4r.pc );1.51 - }1.52 - if( !code() )1.53 - break;1.54 }1.56 - /* If we aborted early, but the cpu is still technically running,1.57 - * we're doing a hard abort - cut the timeslice back to what we1.58 - * actually executed1.59 - */1.60 - if( sh4r.slice_cycle < nanosecs && sh4r.sh4_state == SH4_STATE_RUNNING ) {1.61 - nanosecs = sh4r.slice_cycle;1.62 - }1.63 if( sh4r.sh4_state != SH4_STATE_STANDBY ) {1.64 TMU_run_slice( nanosecs );1.65 SCIF_run_slice( nanosecs );1.66 @@ -87,23 +85,24 @@1.67 */1.68 void * sh4_translate_basic_block( sh4addr_t start )1.69 {1.70 - uint32_t pc = start;1.71 + sh4addr_t pc = start;1.72 int done;1.73 xlat_cache_block_t block = xlat_start_block( start );1.74 xlat_output = (uint8_t *)block->code;1.75 uint8_t *eob = xlat_output + block->size;1.76 - sh4_translate_begin_block();1.77 + sh4_translate_begin_block(pc);1.79 - while( (done = sh4_x86_translate_instruction( pc )) == 0 ) {1.80 + do {1.81 if( eob - xlat_output < MAX_INSTRUCTION_SIZE ) {1.82 uint8_t *oldstart = block->code;1.83 block = xlat_extend_block();1.84 xlat_output = block->code + (xlat_output - oldstart);1.85 eob = block->code + block->size;1.86 }1.87 + done = sh4_x86_translate_instruction( pc );1.88 pc += 2;1.89 - }1.90 - pc+=2;1.91 + } while( !done );1.92 + pc += (done - 2);1.93 sh4_translate_end_block(pc);1.94 xlat_commit_block( xlat_output - block->code, pc-start );1.95 return block->code;1.96 @@ -113,7 +112,7 @@1.97 * Translate a linear basic block to a temporary buffer, execute it, and return1.98 * the result of the execution. The translation is discarded.1.99 */1.100 -gboolean sh4_translate_and_run( sh4addr_t start )1.101 +void *sh4_translate_and_run( sh4addr_t start )1.102 {1.103 char buf[65536];1.105 @@ -122,7 +121,7 @@1.106 xlat_output = buf;1.107 uint8_t *eob = xlat_output + sizeof(buf);1.109 - sh4_translate_begin_block();1.110 + sh4_translate_begin_block(pc);1.112 while( (done = sh4_x86_translate_instruction( pc )) == 0 ) {1.113 assert( (eob - xlat_output) >= MAX_INSTRUCTION_SIZE );1.114 @@ -131,6 +130,6 @@1.115 pc+=2;1.116 sh4_translate_end_block(pc);1.118 - gboolean (*code)() = (void *)buf;1.119 + void * (*code)() = (void *)buf;1.120 return code();1.121 }
.