revision 235:880bff11df92
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 235:880bff11df92 |
parent | 234:8759d0067e9d |
child | 236:581a9f8bf6a6 |
author | nkeynes |
date | Tue Dec 12 09:20:25 2006 +0000 (16 years ago) |
Add a couple of performance hacks:
1. Simplify sh4_run_slice for the usual case (no breakpoints)
2. Cache the last-read instruction page, massively speeding up instruction fetch
1. Simplify sh4_run_slice for the usual case (no breakpoints)
2. Cache the last-read instruction page, massively speeding up instruction fetch
![]() | src/sh4/sh4core.c | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4core.c Tue Dec 12 09:18:47 2006 +00001.2 +++ b/src/sh4/sh4core.c Tue Dec 12 09:20:25 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: sh4core.c,v 1.33 2006-09-26 11:09:13 nkeynes Exp $1.6 + * $Id: sh4core.c,v 1.34 2006-12-12 09:20:25 nkeynes Exp $1.7 *1.8 * SH4 emulation core, and parent module for all the SH4 peripheral1.9 * modules.1.10 @@ -95,6 +95,8 @@1.12 static struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];1.13 static int sh4_breakpoint_count = 0;1.14 +static uint16_t *sh4_icache = NULL;1.15 +static uint32_t sh4_icache_addr = 0;1.17 void sh4_set_breakpoint( uint32_t pc, int type )1.18 {1.19 @@ -142,22 +144,31 @@1.20 sh4r.sh4_state = SH4_STATE_RUNNING;;1.21 }1.23 - for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {1.24 - if( !sh4_execute_instruction() )1.25 - break;1.26 -#ifdef ENABLE_DEBUG_MODE1.27 - for( i=0; i<sh4_breakpoint_count; i++ ) {1.28 - if( sh4_breakpoints[i].address == sh4r.pc ) {1.29 + if( sh4_breakpoint_count == 0 ) {1.30 + for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {1.31 + if( !sh4_execute_instruction() ) {1.32 break;1.33 }1.34 }1.35 - if( i != sh4_breakpoint_count ) {1.36 - dreamcast_stop();1.37 - if( sh4_breakpoints[i].type == BREAK_ONESHOT )1.38 - sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );1.39 - break;1.40 + } else {1.41 +1.42 + for( sh4r.slice_cycle = 0; sh4r.slice_cycle < nanosecs; sh4r.slice_cycle += sh4_cpu_period ) {1.43 + if( !sh4_execute_instruction() )1.44 + break;1.45 +#ifdef ENABLE_DEBUG_MODE1.46 + for( i=0; i<sh4_breakpoint_count; i++ ) {1.47 + if( sh4_breakpoints[i].address == sh4r.pc ) {1.48 + break;1.49 + }1.50 + }1.51 + if( i != sh4_breakpoint_count ) {1.52 + dreamcast_stop();1.53 + if( sh4_breakpoints[i].type == BREAK_ONESHOT )1.54 + sh4_clear_breakpoint( sh4r.pc, BREAK_ONESHOT );1.55 + break;1.56 + }1.57 +#endif1.58 }1.59 -#endif1.60 }1.62 /* If we aborted early, but the cpu is still technically running,1.63 @@ -426,7 +437,24 @@1.64 sh4r.new_pc = sh4r.pc + 2;1.65 }1.66 CHECKRALIGN16(pc);1.67 - ir = MEM_READ_WORD(pc);1.68 +1.69 + /* Read instruction */1.70 + uint32_t pageaddr = pc >> 12;1.71 + if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {1.72 + ir = sh4_icache[(pc&0xFFF)>>1];1.73 + } else {1.74 + sh4_icache = (uint16_t *)mem_get_page(pc);1.75 + if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {1.76 + /* If someone's actually been so daft as to try to execute out of an IO1.77 + * region, fallback on the full-blown memory read1.78 + */1.79 + sh4_icache = NULL;1.80 + ir = MEM_READ_WORD(pc);1.81 + } else {1.82 + sh4_icache_addr = pageaddr;1.83 + ir = sh4_icache[(pc&0xFFF)>>1];1.84 + }1.85 + }1.86 sh4r.icount++;1.88 switch( (ir&0xF000)>>12 ) {
.