From: kub Date: Wed, 22 Apr 2020 18:29:53 +0000 (+0200) Subject: sh2, optimizations to innermost run loop X-Git-Tag: v2.00~749 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2eb213314aee4d6865cc0b171ebbee31ac66a4c8;p=picodrive.git sh2, optimizations to innermost run loop --- diff --git a/cpu/sh2/sh2.h b/cpu/sh2/sh2.h index aabe45be..b0054c05 100644 --- a/cpu/sh2/sh2.h +++ b/cpu/sh2/sh2.h @@ -75,6 +75,7 @@ typedef struct SH2_ unsigned int cycles_timeslice; struct SH2_ *other_sh2; + int (*run)(struct SH2_ *, int); // we use 68k reference cycles for easier sync unsigned int m68krcycles_done; @@ -82,7 +83,7 @@ typedef struct SH2_ unsigned int mult_sh2_to_m68k; uint8_t data_array[0x1000]; // cache (can be used as RAM) - uint32_t peri_regs[0x200/4]; // periphereal regs + uint32_t peri_regs[0x200/4]; // peripheral regs } SH2; #define CYCLE_MULT_SHIFT 10 @@ -103,17 +104,17 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff); int sh2_execute_drc(SH2 *sh2c, int cycles); int sh2_execute_interpreter(SH2 *sh2c, int cycles); -static __inline int sh2_execute(SH2 *sh2, int cycles, int use_drc) +static __inline void sh2_execute_prepare(SH2 *sh2, int use_drc) +{ + sh2->run = use_drc ? sh2_execute_drc : sh2_execute_interpreter; +} + +static __inline int sh2_execute(SH2 *sh2, int cycles) { int ret; sh2->cycles_timeslice = cycles; -#ifdef DRC_SH2 - if (use_drc) - ret = sh2_execute_drc(sh2, cycles); - else -#endif - ret = sh2_execute_interpreter(sh2, cycles); + ret = sh2->run(sh2, cycles); return sh2->cycles_timeslice - ret; } diff --git a/pico/32x/32x.c b/pico/32x/32x.c index ddd03fa8..3b889648 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -383,7 +383,7 @@ static void run_sh2(SH2 *sh2, unsigned int m68k_cycles) elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x", sh2->m68krcycles_done, cycles, sh2->pc); - done = sh2_execute(sh2, cycles, PicoIn.opt & POPT_EN_DRC); + done = sh2_execute(sh2, cycles); sh2->m68krcycles_done += C_SH2_TO_M68K(sh2, done); sh2->state &= ~SH2_STATE_RUN; @@ -499,12 +499,12 @@ void sync_sh2s_normal(unsigned int m68k_target) pprof_end(msh2); now = next; - if (!(msh2.state & SH2_IDLE_STATES)) { - if (CYCLES_GT(now, msh2.m68krcycles_done)) + if (CYCLES_GT(now, msh2.m68krcycles_done)) { + if (!(msh2.state & SH2_IDLE_STATES)) now = msh2.m68krcycles_done; } - if (!(ssh2.state & SH2_IDLE_STATES)) { - if (CYCLES_GT(now, ssh2.m68krcycles_done)) + if (CYCLES_GT(now, ssh2.m68krcycles_done)) { + if (!(ssh2.state & SH2_IDLE_STATES)) now = ssh2.m68krcycles_done; } if (CYCLES_GT(now, timer_cycles+STEP_N)) { @@ -571,6 +571,9 @@ void sync_sh2s_lockstep(unsigned int m68k_target) void PicoFrame32x(void) { + sh2_execute_prepare(&msh2, PicoIn.opt & POPT_EN_DRC); + sh2_execute_prepare(&ssh2, PicoIn.opt & POPT_EN_DRC); + Pico.m.scanline = 0; Pico32x.vdp_regs[0x0a/2] &= ~P32XV_VBLK; // get out of vblank diff --git a/pico/pico_int.h b/pico/pico_int.h index e4bd4c1e..8a4aa309 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -235,11 +235,10 @@ extern SH2 sh2s[2]; # define sh2_pc(sh2) (sh2)->ppc #else # define sh2_end_run(sh2, after_) do { \ - int left_ = (signed int)(sh2)->sr >> 12; \ - if (left_ > (after_)) { \ - (sh2)->cycles_timeslice -= left_ - (after_); \ - (sh2)->sr &= 0xfff; \ - (sh2)->sr |= (after_) << 12; \ + int left_ = ((signed int)(sh2)->sr >> 12) - (after_); \ + if (left_ > 0) { \ + (sh2)->cycles_timeslice -= left_; \ + (sh2)->sr -= (left_ << 12); \ } \ } while (0) # define sh2_cycles_left(sh2) ((signed int)(sh2)->sr >> 12)