X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Fsh2%2Fcompiler.c;h=4403378e4b73c58d03e21586426e7043dc0ec38d;hb=e9a11abb3c8237286fd7b6c4b5048d9eec9b1a1b;hp=106fab50b2ae681ec640371a6a1414fdaf89675d;hpb=001f73a0d62cfaba80738c48b5deea27ab85dfc7;p=picodrive.git diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 106fab5..4403378 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -1017,7 +1017,7 @@ static void rcache_unlock_all(void) reg_temp[i].flags &= ~HRF_LOCKED; } -static inline u32 rcache_used_hreg_mask(void) +static u32 rcache_used_hreg_mask(void) { u32 mask = 0; int i; @@ -1110,8 +1110,11 @@ static void emit_or_t_if_eq(int srr) // reg cache must be clean before call static int emit_memhandler_read_(int size, int ram_check) { - int arg0, arg1; + int arg1; +#if 0 + int arg0; host_arg2reg(arg0, 0); +#endif rcache_clean(); @@ -2587,8 +2590,9 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) default: default_: - elprintf_sh2(sh2, EL_ANOMALY, - "drc: illegal op %04x @ %08x", op, pc - 2); + if (!(op_flags[i] & OF_B_IN_DS)) + elprintf_sh2(sh2, EL_ANOMALY, + "drc: illegal op %04x @ %08x", op, pc - 2); tmp = rcache_get_reg(SHR_SP, RC_GR_RMW); emith_sub_r_imm(tmp, 4*2); @@ -2601,10 +2605,16 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id) // push PC rcache_get_reg_arg(0, SHR_SP); tmp = rcache_get_tmp_arg(1); - emith_move_r_imm(tmp, pc - 2); + if (drcf.pending_branch_indirect) { + tmp2 = rcache_get_reg(SHR_PC, RC_GR_READ); + emith_move_r_r(tmp, tmp2); + } + else + emith_move_r_imm(tmp, pc - 2); emit_memhandler_write(2); // obtain new PC - emit_memhandler_read_rr(SHR_PC, SHR_VBR, 4 * 4, 2); + v = (op_flags[i] & OF_B_IN_DS) ? 6 : 4; + emit_memhandler_read_rr(SHR_PC, SHR_VBR, v * 4, 2); // indirect jump -> back to dispatcher rcache_flush(); emith_jump(sh2_drc_dispatcher); @@ -3108,12 +3118,10 @@ void sh2_drc_wcheck_da(unsigned int a, int val, int cpuid) 1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff); } -int sh2_execute(SH2 *sh2c, int cycles) +int sh2_execute_drc(SH2 *sh2c, int cycles) { int ret_cycles; - sh2c->cycles_timeslice = cycles; - // cycles are kept in SHR_SR unused bits (upper 20) // bit11 contains T saved for delay slot // others are usual SH2 flags @@ -3126,7 +3134,8 @@ int sh2_execute(SH2 *sh2c, int cycles) if (ret_cycles > 0) dbg(1, "warning: drc returned with cycles: %d", ret_cycles); - return sh2c->cycles_timeslice - ret_cycles; + sh2c->sr &= 0x3f3; + return ret_cycles; } #if (DRC_DEBUG & 2) @@ -3178,7 +3187,7 @@ void sh2_drc_flush_all(void) void sh2_drc_mem_setup(SH2 *sh2) { // fill the convenience pointers - sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m; + sh2->p_bios = sh2->is_slave ? Pico32xMem->sh2_rom_s.w : Pico32xMem->sh2_rom_m.w; sh2->p_da = sh2->data_array; sh2->p_sdram = Pico32xMem->sdram; sh2->p_rom = Pico.rom; @@ -3292,7 +3301,7 @@ static void *dr_get_pc_base(u32 pc, int is_slave) if ((pc & ~0x7ff) == 0) { // BIOS - ret = is_slave ? Pico32xMem->sh2_rom_s : Pico32xMem->sh2_rom_m; + ret = is_slave ? Pico32xMem->sh2_rom_s.w : Pico32xMem->sh2_rom_m.w; mask = 0x7ff; } else if ((pc & 0xfffff000) == 0xc0000000) { @@ -3307,7 +3316,8 @@ static void *dr_get_pc_base(u32 pc, int is_slave) } else if ((pc & 0xc6000000) == 0x02000000) { // ROM - ret = Pico.rom; + if ((pc & 0x3fffff) < Pico.romsize) + ret = Pico.rom; mask = 0x3fffff; } @@ -4059,6 +4069,22 @@ void scan_block(u32 base_pc, int is_slave, u8 *op_flags, u32 *end_pc_out, is_slave ? 's' : 'm', op, pc); break; } + + if (op_flags[i] & OF_DELAY_OP) { + switch (opd->op) { + case OP_BRANCH: + case OP_BRANCH_CT: + case OP_BRANCH_CF: + case OP_BRANCH_R: + case OP_BRANCH_RF: + elprintf(EL_ANOMALY, "%csh2 drc: branch in DS @ %08x", + is_slave ? 's' : 'm', pc); + opd->op = OP_UNHANDLED; + op_flags[i] |= OF_B_IN_DS; + next_is_delay = 0; + break; + } + } } i_end = i; end_pc = pc;