mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
32x: drc: emulate illegal insn
The X-Men proto debugger makes it worth it
This commit is contained in:
parent
f8675e282e
commit
001f73a0d6
1 changed files with 33 additions and 14 deletions
|
@ -1228,7 +1228,7 @@ static int emit_memhandler_read_rr(sh2_reg_e rd, sh2_reg_e rs, u32 offs, int siz
|
|||
return hr2;
|
||||
}
|
||||
|
||||
static void emit_memhandler_write(int size, u32 pc)
|
||||
static void emit_memhandler_write(int size)
|
||||
{
|
||||
int ctxr;
|
||||
host_arg2reg(ctxr, 2);
|
||||
|
@ -1718,7 +1718,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp2 = rcache_get_reg_arg(0, SHR_R0);
|
||||
tmp3 = rcache_get_reg(GET_Rn(), RC_GR_READ);
|
||||
emith_add_r_r(tmp2, tmp3);
|
||||
emit_memhandler_write(op & 3, pc);
|
||||
emit_memhandler_write(op & 3);
|
||||
goto end_op;
|
||||
case 0x07:
|
||||
// MUL.L Rm,Rn 0000nnnnmmmm0111
|
||||
|
@ -1837,7 +1837,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp2 = rcache_get_reg_arg(1, GET_Rm());
|
||||
if (op & 0x0f)
|
||||
emith_add_r_imm(tmp, (op & 0x0f) * 4);
|
||||
emit_memhandler_write(2, pc);
|
||||
emit_memhandler_write(2);
|
||||
goto end_op;
|
||||
|
||||
case 0x02:
|
||||
|
@ -1849,7 +1849,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
rcache_clean();
|
||||
rcache_get_reg_arg(0, GET_Rn());
|
||||
rcache_get_reg_arg(1, GET_Rm());
|
||||
emit_memhandler_write(op & 3, pc);
|
||||
emit_memhandler_write(op & 3);
|
||||
goto end_op;
|
||||
case 0x04: // MOV.B Rm,@-Rn 0010nnnnmmmm0100
|
||||
case 0x05: // MOV.W Rm,@-Rn 0010nnnnmmmm0101
|
||||
|
@ -1859,7 +1859,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
emith_sub_r_imm(tmp, (1 << (op & 3)));
|
||||
rcache_clean();
|
||||
rcache_get_reg_arg(0, GET_Rn());
|
||||
emit_memhandler_write(op & 3, pc);
|
||||
emit_memhandler_write(op & 3);
|
||||
goto end_op;
|
||||
case 0x07: // DIV0S Rm,Rn 0010nnnnmmmm0111
|
||||
sr = rcache_get_reg(SHR_SR, RC_GR_RMW);
|
||||
|
@ -2168,7 +2168,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp3 = rcache_get_reg_arg(1, tmp);
|
||||
if (tmp == SHR_SR)
|
||||
emith_clear_msb(tmp3, tmp3, 22); // reserved bits defined by ISA as 0
|
||||
emit_memhandler_write(2, pc);
|
||||
emit_memhandler_write(2);
|
||||
goto end_op;
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
|
@ -2308,7 +2308,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
emith_move_r_r(tmp2, tmp);
|
||||
rcache_free_tmp(tmp);
|
||||
rcache_get_reg_arg(0, GET_Rn());
|
||||
emit_memhandler_write(0, pc);
|
||||
emit_memhandler_write(0);
|
||||
break;
|
||||
default:
|
||||
goto default_;
|
||||
|
@ -2468,7 +2468,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp3 = (op & 0x100) >> 8;
|
||||
if (op & 0x0f)
|
||||
emith_add_r_imm(tmp, (op & 0x0f) << tmp3);
|
||||
emit_memhandler_write(tmp3, pc);
|
||||
emit_memhandler_write(tmp3);
|
||||
goto end_op;
|
||||
case 0x0400: // MOV.B @(disp,Rm),R0 10000100mmmmdddd
|
||||
case 0x0500: // MOV.W @(disp,Rm),R0 10000101mmmmdddd
|
||||
|
@ -2501,7 +2501,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp2 = rcache_get_reg_arg(1, SHR_R0);
|
||||
tmp3 = (op & 0x300) >> 8;
|
||||
emith_add_r_imm(tmp, (op & 0xff) << tmp3);
|
||||
emit_memhandler_write(tmp3, pc);
|
||||
emit_memhandler_write(tmp3);
|
||||
goto end_op;
|
||||
case 0x0400: // MOV.B @(disp,GBR),R0 11000100dddddddd
|
||||
case 0x0500: // MOV.W @(disp,GBR),R0 11000101dddddddd
|
||||
|
@ -2517,12 +2517,12 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
emith_add_r_imm(tmp, 4);
|
||||
tmp = rcache_get_reg_arg(1, SHR_SR);
|
||||
emith_clear_msb(tmp, tmp, 22);
|
||||
emit_memhandler_write(2, pc);
|
||||
emit_memhandler_write(2);
|
||||
// push PC
|
||||
rcache_get_reg_arg(0, SHR_SP);
|
||||
tmp = rcache_get_tmp_arg(1);
|
||||
emith_move_r_imm(tmp, pc);
|
||||
emit_memhandler_write(2, pc);
|
||||
emit_memhandler_write(2);
|
||||
// obtain new PC
|
||||
emit_memhandler_read_rr(SHR_PC, SHR_VBR, (op & 0xff) * 4, 2);
|
||||
// indirect jump -> back to dispatcher
|
||||
|
@ -2574,7 +2574,7 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
tmp3 = rcache_get_reg_arg(0, SHR_GBR);
|
||||
tmp4 = rcache_get_reg(SHR_R0, RC_GR_READ);
|
||||
emith_add_r_r(tmp3, tmp4);
|
||||
emit_memhandler_write(0, pc);
|
||||
emit_memhandler_write(0);
|
||||
goto end_op;
|
||||
}
|
||||
goto default_;
|
||||
|
@ -2587,8 +2587,27 @@ static void REGPARM(2) *sh2_translate(SH2 *sh2, int tcache_id)
|
|||
|
||||
default:
|
||||
default_:
|
||||
elprintf(EL_ANOMALY, "%csh2 drc: unhandled op %04x @ %08x",
|
||||
sh2->is_slave ? 's' : 'm', op, pc - 2);
|
||||
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);
|
||||
// push SR
|
||||
tmp = rcache_get_reg_arg(0, SHR_SP);
|
||||
emith_add_r_imm(tmp, 4);
|
||||
tmp = rcache_get_reg_arg(1, SHR_SR);
|
||||
emith_clear_msb(tmp, tmp, 22);
|
||||
emit_memhandler_write(2);
|
||||
// push PC
|
||||
rcache_get_reg_arg(0, SHR_SP);
|
||||
tmp = rcache_get_tmp_arg(1);
|
||||
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);
|
||||
// indirect jump -> back to dispatcher
|
||||
rcache_flush();
|
||||
emith_jump(sh2_drc_dispatcher);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue