X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2Fsh2%2Fcompiler.c;h=3a2b708c11c9491ada869fe2bc30d685b4408015;hb=6a5b1b362ecf78ce2925068a5d938d319ff583a3;hp=25ba9d2f90a044c33f2969de410125bfbb8a332c;hpb=61290a355398cc8f17b183700f637dc65a8b8ab4;p=picodrive.git diff --git a/cpu/sh2/compiler.c b/cpu/sh2/compiler.c index 25ba9d2..3a2b708 100644 --- a/cpu/sh2/compiler.c +++ b/cpu/sh2/compiler.c @@ -2590,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); @@ -2604,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); @@ -4062,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;