mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-24 22:15:07 +00:00
target/mips: Fix decoding mechanism of R5900 DIV1 and DIVU1
DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic gen_muldiv. Backports commit c42171c3bfe6fdc94c183f664c4d6548f8c5488b from qemu
This commit is contained in:
parent
3d637206bd
commit
f23c6fd006
|
@ -4803,6 +4803,64 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
|
||||||
tcg_temp_free(tcg_ctx, t1);
|
tcg_temp_free(tcg_ctx, t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
TCGv t0, t1;
|
||||||
|
|
||||||
|
t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
t1 = tcg_temp_new(tcg_ctx);
|
||||||
|
|
||||||
|
gen_load_gpr(ctx, t0, rs);
|
||||||
|
gen_load_gpr(ctx, t1, rt);
|
||||||
|
|
||||||
|
switch (opc) {
|
||||||
|
case TX79_MMI_DIV1:
|
||||||
|
{
|
||||||
|
TCGv t2 = tcg_temp_new(tcg_ctx);
|
||||||
|
TCGv t3 = tcg_temp_new(tcg_ctx);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, t0, t0);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, t1, t1);
|
||||||
|
tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t2, t0, INT_MIN);
|
||||||
|
tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, -1);
|
||||||
|
tcg_gen_and_tl(tcg_ctx, t2, t2, t3);
|
||||||
|
tcg_gen_setcondi_tl(tcg_ctx, TCG_COND_EQ, t3, t1, 0);
|
||||||
|
tcg_gen_or_tl(tcg_ctx, t2, t2, t3);
|
||||||
|
tcg_gen_movi_tl(tcg_ctx, t3, 0);
|
||||||
|
tcg_gen_movcond_tl(tcg_ctx, TCG_COND_NE, t1, t2, t3, t2, t1);
|
||||||
|
tcg_gen_div_tl(tcg_ctx, tcg_ctx->cpu_LO[1], t0, t1);
|
||||||
|
tcg_gen_rem_tl(tcg_ctx, tcg_ctx->cpu_HI[1], t0, t1);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, tcg_ctx->cpu_LO[1], tcg_ctx->cpu_LO[1]);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, tcg_ctx->cpu_HI[1], tcg_ctx->cpu_HI[1]);
|
||||||
|
tcg_temp_free(tcg_ctx, t3);
|
||||||
|
tcg_temp_free(tcg_ctx, t2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TX79_MMI_DIVU1:
|
||||||
|
{
|
||||||
|
TCGv t2 = tcg_const_tl(tcg_ctx, 0);
|
||||||
|
TCGv t3 = tcg_const_tl(tcg_ctx, 1);
|
||||||
|
tcg_gen_ext32u_tl(tcg_ctx, t0, t0);
|
||||||
|
tcg_gen_ext32u_tl(tcg_ctx, t1, t1);
|
||||||
|
tcg_gen_movcond_tl(tcg_ctx, TCG_COND_EQ, t1, t1, t2, t3, t1);
|
||||||
|
tcg_gen_divu_tl(tcg_ctx, tcg_ctx->cpu_LO[1], t0, t1);
|
||||||
|
tcg_gen_remu_tl(tcg_ctx, tcg_ctx->cpu_HI[1], t0, t1);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, tcg_ctx->cpu_LO[1], tcg_ctx->cpu_LO[1]);
|
||||||
|
tcg_gen_ext32s_tl(tcg_ctx, tcg_ctx->cpu_HI[1], tcg_ctx->cpu_HI[1]);
|
||||||
|
tcg_temp_free(tcg_ctx, t3);
|
||||||
|
tcg_temp_free(tcg_ctx, t2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MIPS_INVAL("div1 TX79");
|
||||||
|
generate_exception_end(ctx, EXCP_RI);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t1);
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
|
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
|
||||||
int acc, int rs, int rt)
|
int acc, int rs, int rt)
|
||||||
{
|
{
|
||||||
|
@ -4818,14 +4876,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
|
||||||
gen_load_gpr(ctx, t1, rt);
|
gen_load_gpr(ctx, t1, rt);
|
||||||
|
|
||||||
if (acc != 0) {
|
if (acc != 0) {
|
||||||
if (!(ctx->insn_flags & INSN_R5900)) {
|
check_dsp(ctx);
|
||||||
check_dsp(ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case OPC_DIV:
|
case OPC_DIV:
|
||||||
case TX79_MMI_DIV1:
|
|
||||||
{
|
{
|
||||||
TCGv t2 = tcg_temp_new(tcg_ctx);
|
TCGv t2 = tcg_temp_new(tcg_ctx);
|
||||||
TCGv t3 = tcg_temp_new(tcg_ctx);
|
TCGv t3 = tcg_temp_new(tcg_ctx);
|
||||||
|
@ -4847,7 +4902,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPC_DIVU:
|
case OPC_DIVU:
|
||||||
case TX79_MMI_DIVU1:
|
|
||||||
{
|
{
|
||||||
TCGv t2 = tcg_const_tl(tcg_ctx, 0);
|
TCGv t2 = tcg_const_tl(tcg_ctx, 0);
|
||||||
TCGv t3 = tcg_const_tl(tcg_ctx, 1);
|
TCGv t3 = tcg_const_tl(tcg_ctx, 1);
|
||||||
|
@ -26686,7 +26740,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
|
||||||
break;
|
break;
|
||||||
case TX79_MMI_DIV1:
|
case TX79_MMI_DIV1:
|
||||||
case TX79_MMI_DIVU1:
|
case TX79_MMI_DIVU1:
|
||||||
gen_muldiv(ctx, opc, 1, rs, rt);
|
gen_div1_tx79(ctx, opc, rs, rt);
|
||||||
break;
|
break;
|
||||||
case TX79_MMI_MTLO1:
|
case TX79_MMI_MTLO1:
|
||||||
case TX79_MMI_MTHI1:
|
case TX79_MMI_MTHI1:
|
||||||
|
|
Loading…
Reference in a new issue