move saving SH2 SR into memory access and do so only if needed
authorkub <derkub@gmail.com>
Wed, 27 Mar 2019 20:58:32 +0000 (21:58 +0100)
committerkub <derkub@gmail.com>
Tue, 30 Jul 2019 14:34:40 +0000 (16:34 +0200)
cpu/sh2/compiler.c
cpu/sh2/compiler.h
pico/32x/memory.c
pico/32x/sh2soc.c

index 3c82420..3c5ce5b 100644 (file)
@@ -1231,11 +1231,11 @@ static int emit_memhandler_read(int size)
 
   rcache_clean();
 
+#ifndef DCR_SR_REG
   // must writeback cycles for poll detection stuff
-  // FIXME: rm
   if (reg_map_g2h[SHR_SR] != -1)
     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
   arg1 = rcache_get_tmp_arg(1);
   emith_move_r_r_ptr(arg1, CONTEXT_REG);
   switch (size) {
@@ -1244,10 +1244,10 @@ static int emit_memhandler_read(int size)
   case 2:   emith_call(sh2_drc_read32);     break; // 32
   }
   rcache_invalidate();
-
+#ifndef DCR_SR_REG
   if (reg_map_g2h[SHR_SR] != -1)
     emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
   return rcache_get_tmp_ret();
 }
 
@@ -1255,10 +1255,10 @@ static int emit_memhandler_read(int size)
 static void emit_memhandler_write(int size)
 {
   int arg2;
-
+#ifndef DCR_SR_REG
   if (reg_map_g2h[SHR_SR] != -1)
     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
   rcache_clean();
 
   arg2 = rcache_get_tmp_arg(2);
@@ -1270,8 +1270,10 @@ static void emit_memhandler_write(int size)
   }
 
   rcache_invalidate();
+#ifndef DCR_SR_REG
   if (reg_map_g2h[SHR_SR] != -1)
     emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
+#endif
 }
 
 // rd = @(Rs,#offs)
index 61d8d2d..70fdbf4 100644 (file)
@@ -13,7 +13,7 @@ void sh2_drc_frame(void);
 #define sh2_drc_frame()
 #endif
 
-#define BLOCK_INSN_LIMIT 128
+#define BLOCK_INSN_LIMIT 1024
 
 /* op_flags */
 #define OF_DELAY_OP   (1 << 0)
@@ -25,3 +25,29 @@ void sh2_drc_frame(void);
 void scan_block(unsigned int base_pc, int is_slave,
                unsigned char *op_flags, unsigned int *end_pc,
                unsigned int *end_literals);
+
+#if defined(DRC_SH2)
+// direct access to some host CPU registers used by the DRC
+// XXX MUST match definitions in cpu/sh2/compiler.c
+#if defined(_arm__)
+#define        DRC_SR_REG      r10
+#elif defined(__i386__)
+#define        DRC_SR_REG      edi
+#else
+#warning "direct DRC register access not available for this host"
+#endif
+
+#ifdef DCR_SR_REG
+#define        DRC_DECLARE_SR  register int sh2_sr asm(#DCR_SR_REG)
+#define DRC_SAVE_SR(sh2) \
+    if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_BUSY)) == SH2_STATE_RUN) \
+        sh2->sr = sh2_sr;
+#define DRC_RESTORE_SR(sh2) \
+    if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_BUSY)) == SH2_STATE_RUN) \
+        sh2_sr = sh2->sr;
+#else
+#define        DRC_DECLARE_SR
+#define DRC_SAVE_SR(sh2)
+#define DRC_RESTORE_SR(sh2)
+#endif
+#endif
index d399d75..f82b9f9 100644 (file)
@@ -40,7 +40,9 @@
  */
 #include "../pico_int.h"
 #include "../memory.h"
+
 #include "../../cpu/sh2/compiler.h"
+DRC_DECLARE_SR;
 
 static const char str_mars[] = "MARS";
 
@@ -1237,6 +1239,7 @@ static u32 sh2_read8_unmapped(u32 a, SH2 *sh2)
 static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
 {
   u32 d = 0;
+  DRC_SAVE_SR(sh2);
 
   sh2_burn_cycles(sh2, 1*2);
 
@@ -1252,18 +1255,19 @@ static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
     goto out_16to8;
   }
 
-  // TODO: mirroring?
-  if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
-    return Pico32xMem->sh2_rom_m.b[a ^ 1];
-  if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
-    return Pico32xMem->sh2_rom_s.b[a ^ 1];
-
   if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
     goto out_16to8;
   }
 
-  return sh2_read8_unmapped(a, sh2);
+  // TODO: mirroring?
+  if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
+    d = Pico32xMem->sh2_rom_m.b[a ^ 1];
+  else if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
+    d = Pico32xMem->sh2_rom_s.b[a ^ 1];
+  else
+    d = sh2_read8_unmapped(a, sh2);
+  goto out;
 
 out_16to8:
   if (a & 1)
@@ -1271,8 +1275,10 @@ out_16to8:
   else
     d >>= 8;
 
+out:
   elprintf_sh2(sh2, EL_32X, "r8  [%08x]       %02x @%06x",
     a, d, sh2_pc(sh2));
+  DRC_RESTORE_SR(sh2);
   return d;
 }
 
@@ -1299,13 +1305,14 @@ static u32 sh2_read16_unmapped(u32 a, SH2 *sh2)
 static u32 sh2_read16_cs0(u32 a, SH2 *sh2)
 {
   u32 d = 0;
+  DRC_SAVE_SR(sh2);
 
   sh2_burn_cycles(sh2, 1*2);
 
   if ((a & 0x3ffc0) == 0x4000) {
     d = p32x_sh2reg_read16(a, sh2);
     if (!(EL_LOGMASK & EL_PWM) && (a & 0x30) == 0x30) // hide PWM
-      return d;
+      goto out_noprint;
     goto out;
   }
 
@@ -1315,21 +1322,23 @@ static u32 sh2_read16_cs0(u32 a, SH2 *sh2)
     goto out;
   }
 
-  if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
-    return Pico32xMem->sh2_rom_m.w[a / 2];
-  if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
-    return Pico32xMem->sh2_rom_s.w[a / 2];
-
   if ((a & 0x3fe00) == 0x4200) {
     d = Pico32xMem->pal[(a & 0x1ff) / 2];
     goto out;
   }
 
-  return sh2_read16_unmapped(a, sh2);
+  if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
+    d = Pico32xMem->sh2_rom_m.w[a / 2];
+  else if (sh2->is_slave  && a < sizeof(Pico32xMem->sh2_rom_s))
+    d = Pico32xMem->sh2_rom_s.w[a / 2];
+  else
+    d = sh2_read16_unmapped(a, sh2);
 
 out:
   elprintf_sh2(sh2, EL_32X, "r16 [%08x]     %04x @%06x",
     a, d, sh2_pc(sh2));
+out_noprint:
+  DRC_RESTORE_SR(sh2);
   return d;
 }
 
@@ -1383,6 +1392,7 @@ static void REGPARM(3) sh2_write8_unmapped(u32 a, u32 d, SH2 *sh2)
 
 static void REGPARM(3) sh2_write8_cs0(u32 a, u32 d, SH2 *sh2)
 {
+  DRC_SAVE_SR(sh2);
   elprintf_sh2(sh2, EL_32X, "w8  [%08x]       %02x @%06x",
     a, d & 0xff, sh2_pc(sh2));
 
@@ -1390,16 +1400,24 @@ static void REGPARM(3) sh2_write8_cs0(u32 a, u32 d, SH2 *sh2)
     if ((a & 0x3fff0) == 0x4100) {
       sh2->poll_addr = 0;
       p32x_vdp_write8(a, d);
-      return;
+      goto out;
+    }
+
+    if ((a & 0x3fe00) == 0x4200) {
+      ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d;
+      Pico32x.dirty_pal = 1;
+      goto out;
     }
   }
 
   if ((a & 0x3ffc0) == 0x4000) {
     p32x_sh2reg_write8(a, d, sh2);
-    return;
+    goto out;
   }
 
   sh2_write8_unmapped(a, d, sh2);
+out:
+  DRC_RESTORE_SR(sh2);
 }
 
 static void REGPARM(3) sh2_write8_dram0(u32 a, u32 d, SH2 *sh2)
@@ -1426,8 +1444,11 @@ static void REGPARM(3) sh2_write8_sdram(u32 a, u32 d, SH2 *sh2)
 static void REGPARM(3) sh2_write8_sdram_wt(u32 a, u32 d, SH2 *sh2)
 {
   // xmen sync hack..
-  if (a < 0x26000200)
+  if (a < 0x26000200) {
+    DRC_SAVE_SR(sh2);
     sh2_end_run(sh2, 32);
+    DRC_RESTORE_SR(sh2);
+  }
 
   sh2_write8_sdram(a, d, sh2);
 }
@@ -1453,6 +1474,7 @@ static void REGPARM(3) sh2_write16_unmapped(u32 a, u32 d, SH2 *sh2)
 
 static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
 {
+  DRC_SAVE_SR(sh2);
   if (((EL_LOGMASK & EL_PWM) || (a & 0x30) != 0x30)) // hide PWM
     elprintf_sh2(sh2, EL_32X, "w16 [%08x]     %04x @%06x",
       a, d & 0xffff, sh2_pc(sh2));
@@ -1461,22 +1483,24 @@ static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
     if ((a & 0x3fff0) == 0x4100) {
       sh2->poll_addr = 0;
       p32x_vdp_write16(a, d, sh2);
-      return;
+      goto out;
     }
 
     if ((a & 0x3fe00) == 0x4200) {
       Pico32xMem->pal[(a & 0x1ff) / 2] = d;
       Pico32x.dirty_pal = 1;
-      return;
+      goto out;
     }
   }
 
   if ((a & 0x3ffc0) == 0x4000) {
     p32x_sh2reg_write16(a, d, sh2);
-    return;
+    goto out;
   }
 
   sh2_write16_unmapped(a, d, sh2);
+out:
+  DRC_RESTORE_SR(sh2);
 }
 
 static void REGPARM(3) sh2_write16_dram0(u32 a, u32 d, SH2 *sh2)
index 0f75d9b..f8e657f 100644 (file)
@@ -25,6 +25,9 @@
 #include "../pico_int.h"
 #include "../memory.h"
 
+#include "../../cpu/sh2/compiler.h"
+DRC_DECLARE_SR;
+
 // DMAC handling
 struct dma_chan {
   unsigned int sar, dar;  // src, dst addr
@@ -413,10 +416,12 @@ void REGPARM(3) sh2_peripheral_write32(u32 a, u32 d, SH2 *sh2)
     if (!(dmac->dmaor & DMA_DME))
       return;
 
+    DRC_SAVE_SR(sh2);
     if ((dmac->chan[0].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
       dmac_trigger(sh2, &dmac->chan[0]);
     if ((dmac->chan[1].chcr & (DMA_TE|DMA_DE)) == DMA_DE)
       dmac_trigger(sh2, &dmac->chan[1]);
+    DRC_RESTORE_SR(sh2);
   }
 }