DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic
gen_muldiv.
Signed-off-by: Fredrik Noring <noring@nocrew.org>
---
target/mips/translate.c | 65 +++++++++++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index f3993cf7d7..6e5a8a2565 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -4759,6 +4759,63 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
tcg_temp_free(t1);
}
+static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
+{
+ TCGv t0, t1;
+
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ switch (opc) {
+ case TX79_MMI_DIV1:
+ {
+ TCGv t2 = tcg_temp_new();
+ TCGv t3 = tcg_temp_new();
+ tcg_gen_ext32s_tl(t0, t0);
+ tcg_gen_ext32s_tl(t1, t1);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
+ tcg_gen_and_tl(t2, t2, t3);
+ tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
+ tcg_gen_or_tl(t2, t2, t3);
+ tcg_gen_movi_tl(t3, 0);
+ tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
+ tcg_gen_div_tl(cpu_LO[1], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[1], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
+ tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
+ }
+ break;
+ case TX79_MMI_DIVU1:
+ {
+ TCGv t2 = tcg_const_tl(0);
+ TCGv t3 = tcg_const_tl(1);
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
+ tcg_gen_divu_tl(cpu_LO[1], t0, t1);
+ tcg_gen_remu_tl(cpu_HI[1], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
+ tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
+ tcg_temp_free(t3);
+ tcg_temp_free(t2);
+ }
+ break;
+ default:
+ MIPS_INVAL("div1 TX79");
+ generate_exception_end(ctx, EXCP_RI);
+ goto out;
+ }
+ out:
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+}
+
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
int acc, int rs, int rt)
{
@@ -4771,14 +4828,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
gen_load_gpr(t1, rt);
if (acc != 0) {
- if (!(ctx->insn_flags & INSN_R5900)) {
- check_dsp(ctx);
- }
+ check_dsp(ctx);
}
switch (opc) {
case OPC_DIV:
- case TX79_MMI_DIV1:
{
TCGv t2 = tcg_temp_new();
TCGv t3 = tcg_temp_new();
@@ -4800,7 +4854,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
}
break;
case OPC_DIVU:
- case TX79_MMI_DIVU1:
{
TCGv t2 = tcg_const_tl(0);
TCGv t3 = tcg_const_tl(1);
@@ -26541,7 +26594,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
break;
case TX79_MMI_DIV1:
case TX79_MMI_DIVU1:
- gen_muldiv(ctx, opc, 1, rs, rt);
+ gen_div1_tx79(ctx, opc, rs, rt);
break;
case TX79_MMI_MTLO1:
case TX79_MMI_MTHI1:
--
2.18.1
On 2/11/18 17:08, Fredrik Noring wrote:
> DIV1 and DIVU1 are generated in gen_div1_tx79 instead of the generic
> gen_muldiv.
>
Fixes: be9c42c90d1 (R5900-specific opcodes overlap with generic opcodes)
> Signed-off-by: Fredrik Noring <noring@nocrew.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/mips/translate.c | 65 +++++++++++++++++++++++++++++++++++++----
> 1 file changed, 59 insertions(+), 6 deletions(-)
>
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index f3993cf7d7..6e5a8a2565 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -4759,6 +4759,63 @@ static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
> tcg_temp_free(t1);
> }
>
> +static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
> +{
> + TCGv t0, t1;
> +
> + t0 = tcg_temp_new();
> + t1 = tcg_temp_new();
> +
> + gen_load_gpr(t0, rs);
> + gen_load_gpr(t1, rt);
> +
> + switch (opc) {
> + case TX79_MMI_DIV1:
> + {
> + TCGv t2 = tcg_temp_new();
> + TCGv t3 = tcg_temp_new();
> + tcg_gen_ext32s_tl(t0, t0);
> + tcg_gen_ext32s_tl(t1, t1);
> + tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
> + tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
> + tcg_gen_and_tl(t2, t2, t3);
> + tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
> + tcg_gen_or_tl(t2, t2, t3);
> + tcg_gen_movi_tl(t3, 0);
> + tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
> + tcg_gen_div_tl(cpu_LO[1], t0, t1);
> + tcg_gen_rem_tl(cpu_HI[1], t0, t1);
> + tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
> + tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
> + tcg_temp_free(t3);
> + tcg_temp_free(t2);
> + }
> + break;
> + case TX79_MMI_DIVU1:
> + {
> + TCGv t2 = tcg_const_tl(0);
> + TCGv t3 = tcg_const_tl(1);
> + tcg_gen_ext32u_tl(t0, t0);
> + tcg_gen_ext32u_tl(t1, t1);
> + tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
> + tcg_gen_divu_tl(cpu_LO[1], t0, t1);
> + tcg_gen_remu_tl(cpu_HI[1], t0, t1);
> + tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
> + tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
> + tcg_temp_free(t3);
> + tcg_temp_free(t2);
> + }
> + break;
> + default:
> + MIPS_INVAL("div1 TX79");
> + generate_exception_end(ctx, EXCP_RI);
> + goto out;
> + }
> + out:
> + tcg_temp_free(t0);
> + tcg_temp_free(t1);
> +}
> +
> static void gen_muldiv(DisasContext *ctx, uint32_t opc,
> int acc, int rs, int rt)
> {
> @@ -4771,14 +4828,11 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
> gen_load_gpr(t1, rt);
>
> if (acc != 0) {
> - if (!(ctx->insn_flags & INSN_R5900)) {
> - check_dsp(ctx);
> - }
> + check_dsp(ctx);
> }
>
> switch (opc) {
> case OPC_DIV:
> - case TX79_MMI_DIV1:
> {
> TCGv t2 = tcg_temp_new();
> TCGv t3 = tcg_temp_new();
> @@ -4800,7 +4854,6 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc,
> }
> break;
> case OPC_DIVU:
> - case TX79_MMI_DIVU1:
> {
> TCGv t2 = tcg_const_tl(0);
> TCGv t3 = tcg_const_tl(1);
> @@ -26541,7 +26594,7 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx)
> break;
> case TX79_MMI_DIV1:
> case TX79_MMI_DIVU1:
> - gen_muldiv(ctx, opc, 1, rs, rt);
> + gen_div1_tx79(ctx, opc, rs, rt);
> break;
> case TX79_MMI_MTLO1:
> case TX79_MMI_MTHI1:
>
© 2016 - 2025 Red Hat, Inc.