sh2dasm: print addrs consistently with everything else
[picodrive.git] / cpu / sh2 / compiler.c
index bdf2cea..84b9736 100644 (file)
@@ -572,7 +572,7 @@ static void *dr_prepare_ext_branch(u32 pc, int is_slave, int tcache_id)
       break;
   cnt = i + 1;
   if (cnt >= block_link_pool_max_counts[tcache_id]) {
-    dbg(1, "bl overflow for tcache %d\n", tcache_id);
+    dbg(1, "bl overflow for tcache %d", tcache_id);
     return NULL;
   }
   bl += cnt;
@@ -994,6 +994,18 @@ static void rcache_unlock_all(void)
     reg_temp[i].flags &= ~HRF_LOCKED;
 }
 
+static inline u32 rcache_used_hreg_mask(void)
+{
+  u32 mask = 0;
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(reg_temp); i++)
+    if (reg_temp[i].type != HR_FREE)
+      mask |= 1 << reg_temp[i].hreg;
+
+  return mask;
+}
+
 static void rcache_clean(void)
 {
   int i;
@@ -1199,14 +1211,14 @@ static void emit_memhandler_write(int size, u32 pc)
   if (reg_map_g2h[SHR_SR] != -1)
     emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
 
+  rcache_clean();
+
   switch (size) {
   case 0: // 8
     // XXX: consider inlining sh2_drc_write8
-    rcache_clean();
     emith_call(sh2_drc_write8);
     break;
   case 1: // 16
-    rcache_clean();
     emith_call(sh2_drc_write16);
     break;
   case 2: // 32
@@ -1399,6 +1411,9 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
     memset(branch_target_ptr, 0, sizeof(branch_target_ptr[0]) * branch_target_count);
   }
 
+  // clear stale state after compile errors
+  rcache_invalidate();
+
   // -------------------------------------------------
   // 3rd pass: actual compilation
   pc = base_pc;
@@ -1477,16 +1492,18 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
       emit_move_r_imm32(SHR_PC, pc);
       sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
       FLUSH_CYCLES(sr);
-      // rcache_clean(); // FIXME
-      rcache_flush();
+      rcache_clean();
+
+      tmp = rcache_used_hreg_mask();
+      emith_save_caller_regs(tmp);
       emit_do_static_regs(1, 0);
       emith_pass_arg_r(0, CONTEXT_REG);
       emith_call(do_sh2_cmp);
+      emith_restore_caller_regs(tmp);
     }
 #endif
 
     pc += 2;
-    cycles += opd->cycles;
 
     if (skip_op > 0) {
       skip_op--;
@@ -2425,6 +2442,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
         // obtain new PC
         emit_memhandler_read_rr(SHR_PC, SHR_VBR, (op & 0xff) * 4, 2);
         // indirect jump -> back to dispatcher
+        rcache_flush();
         emith_jump(sh2_drc_dispatcher);
         goto end_op;
       case 0x0700: // MOVA @(disp,PC),R0    11000111dddddddd
@@ -2517,6 +2535,8 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
 end_op:
     rcache_unlock_all();
 
+    cycles += opd->cycles;
+
     if (op_flags[i+1] & OF_DELAY_OP) {
       do_host_disasm(tcache_id);
       continue;
@@ -2586,8 +2606,10 @@ end_op:
 
       if (cond != -1)
         emith_jump_cond_patchable(cond, target);
-      else
+      else {
         emith_jump_patchable(target);
+        rcache_invalidate();
+      }
 
       drcf.pending_branch_direct = 0;
     }
@@ -2950,7 +2972,20 @@ static void sh2_smc_rm_block(u32 a, u16 *drc_ram_blk, int tcache_id, u32 shift,
     entry = entry->next;
   }
 
-  // clear entry points
+  // update range to not clear still alive blocks
+  for (entry = *blist; entry != NULL; entry = entry->next) {
+    block = entry->block;
+    if (block->addr > a) {
+      if (to > block->addr)
+        to = block->addr;
+    }
+    else {
+      if (from < block->end_addr)
+        from = block->end_addr;
+    }
+  }
+
+  // clear code marks
   if (from < to) {
     u16 *p = drc_ram_blk + ((from & mask) >> shift);
     memset(p, 0, (to - from) >> (shift - 1));
@@ -3083,9 +3118,6 @@ int sh2_drc_init(SH2 *sh2)
     for (i = 1; i < ARRAY_SIZE(tcache_bases); i++)
       tcache_bases[i] = tcache_ptrs[i] = tcache_bases[i - 1] + tcache_sizes[i - 1];
 
-    // tmp
-    PicoOpt |= POPT_DIS_VDP_FIFO;
-
 #if (DRC_DEBUG & 4)
     for (i = 0; i < ARRAY_SIZE(block_tables); i++)
       tcache_dsm_ptrs[i] = tcache_bases[i];