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;
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;
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
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;
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--;
// 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
end_op:
rcache_unlock_all();
+ cycles += opd->cycles;
+
if (op_flags[i+1] & OF_DELAY_OP) {
do_host_disasm(tcache_id);
continue;
if (cond != -1)
emith_jump_cond_patchable(cond, target);
- else
+ else {
emith_jump_patchable(target);
+ rcache_invalidate();
+ }
drcf.pending_branch_direct = 0;
}
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));
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];