sh2, optimizations to innermost run loop
authorkub <derkub@gmail.com>
Wed, 22 Apr 2020 18:29:53 +0000 (20:29 +0200)
committerkub <derkub@gmail.com>
Wed, 22 Apr 2020 19:49:02 +0000 (21:49 +0200)
cpu/sh2/sh2.h
pico/32x/32x.c
pico/pico_int.h

index aabe45b..b0054c0 100644 (file)
@@ -75,6 +75,7 @@ typedef struct SH2_
        unsigned int    cycles_timeslice;\r
 \r
        struct SH2_     *other_sh2;\r
+       int             (*run)(struct SH2_ *, int);\r
 \r
        // we use 68k reference cycles for easier sync\r
        unsigned int    m68krcycles_done;\r
@@ -82,7 +83,7 @@ typedef struct SH2_
        unsigned int    mult_sh2_to_m68k;\r
 \r
        uint8_t         data_array[0x1000]; // cache (can be used as RAM)\r
-       uint32_t        peri_regs[0x200/4]; // periphereal regs\r
+       uint32_t        peri_regs[0x200/4]; // peripheral regs\r
 } SH2;\r
 \r
 #define CYCLE_MULT_SHIFT 10\r
@@ -103,17 +104,17 @@ void sh2_unpack(SH2 *sh2, const unsigned char *buff);
 int  sh2_execute_drc(SH2 *sh2c, int cycles);\r
 int  sh2_execute_interpreter(SH2 *sh2c, int cycles);\r
 \r
-static __inline int sh2_execute(SH2 *sh2, int cycles, int use_drc)\r
+static __inline void sh2_execute_prepare(SH2 *sh2, int use_drc)\r
+{\r
+  sh2->run = use_drc ? sh2_execute_drc : sh2_execute_interpreter;\r
+}\r
+\r
+static __inline int sh2_execute(SH2 *sh2, int cycles)\r
 {\r
   int ret;\r
 \r
   sh2->cycles_timeslice = cycles;\r
-#ifdef DRC_SH2\r
-  if (use_drc)\r
-    ret = sh2_execute_drc(sh2, cycles);\r
-  else\r
-#endif\r
-    ret = sh2_execute_interpreter(sh2, cycles);\r
+  ret = sh2->run(sh2, cycles);\r
 \r
   return sh2->cycles_timeslice - ret;\r
 }\r
index ddd03fa..3b88964 100644 (file)
@@ -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
index e4bd4c1..8a4aa30 100644 (file)
@@ -235,11 +235,10 @@ extern SH2 sh2s[2];
 # define sh2_pc(sh2) (sh2)->ppc\r
 #else\r
 # define sh2_end_run(sh2, after_) do { \\r
-  int left_ = (signed int)(sh2)->sr >> 12; \\r
-  if (left_ > (after_)) { \\r
-    (sh2)->cycles_timeslice -= left_ - (after_); \\r
-    (sh2)->sr &= 0xfff; \\r
-    (sh2)->sr |= (after_) << 12; \\r
+  int left_ = ((signed int)(sh2)->sr >> 12) - (after_); \\r
+  if (left_ > 0) { \\r
+    (sh2)->cycles_timeslice -= left_; \\r
+    (sh2)->sr -= (left_ << 12); \\r
   } \\r
 } while (0)\r
 # define sh2_cycles_left(sh2) ((signed int)(sh2)->sr >> 12)\r