target/mips: Convert Loongson [D]MULT[U].G opcodes to decodetree

Convert the following opcodes to decodetree:

- MULT.G - multiply 32-bit signed integers
- MULTU.G - multiply 32-bit unsigned integers
- DMULT.G - multiply 64-bit signed integers
- DMULTU.G - multiply 64-bit unsigned integers

Now that all opcodes from the extension have been converted, we
can remove completely gen_loongson_integer() and its 2 calls in
decode_opc_special2_legacy() and decode_opc_special3_legacy().

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20241026175349.84523-9-philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
Philippe Mathieu-Daudé 2023-08-31 22:12:33 +02:00 committed by Philippe Mathieu-Daudé
parent 020cafa58e
commit ad6e1f194f
4 changed files with 49 additions and 71 deletions

View File

@ -13,6 +13,9 @@
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv @rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
MULTu_G 011111 ..... ..... ..... 00000 01100- @rs_rt_rd
DMULTu_G 011111 ..... ..... ..... 00000 01110- @rs_rt_rd
DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
DIVU_G 011111 ..... ..... ..... 00000 011011 @rs_rt_rd DIVU_G 011111 ..... ..... ..... 00000 011011 @rs_rt_rd
DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd

View File

@ -14,6 +14,9 @@
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv @rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
MULTu_G 011100 ..... ..... ..... 00000 0100-0 @rs_rt_rd
DMULTu_G 011100 ..... ..... ..... 00000 0100-1 @rs_rt_rd
DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd
DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
DIVU_G 011100 ..... ..... ..... 00000 010110 @rs_rt_rd DIVU_G 011100 ..... ..... ..... 00000 010110 @rs_rt_rd

View File

@ -252,6 +252,47 @@ static bool trans_DMODU_G(DisasContext *s, arg_muldiv *a)
return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, true); return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, true);
} }
static bool gen_lext_MULT_G(DisasContext *s, int rd, int rs, int rt,
bool is_double)
{
TCGv t0, t1;
if (is_double) {
if (TARGET_LONG_BITS != 64) {
return false;
}
check_mips_64(s);
}
if (rd == 0) {
/* Treat as NOP. */
return true;
}
t0 = tcg_temp_new();
t1 = tcg_temp_new();
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
if (!is_double) {
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
}
return true;
}
static bool trans_MULTu_G(DisasContext *s, arg_muldiv *a)
{
return gen_lext_MULT_G(s, a->rd, a->rs, a->rt, false);
}
static bool trans_DMULTu_G(DisasContext *s, arg_muldiv *a)
{
return gen_lext_MULT_G(s, a->rd, a->rs, a->rt, true);
}
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn) bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
{ {
if (!decode_64bit_enabled(ctx)) { if (!decode_64bit_enabled(ctx)) {

View File

@ -327,11 +327,6 @@ enum {
OPC_MUL = 0x02 | OPC_SPECIAL2, OPC_MUL = 0x02 | OPC_SPECIAL2,
OPC_MSUB = 0x04 | OPC_SPECIAL2, OPC_MSUB = 0x04 | OPC_SPECIAL2,
OPC_MSUBU = 0x05 | OPC_SPECIAL2, OPC_MSUBU = 0x05 | OPC_SPECIAL2,
/* Loongson 2F */
OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
/* Misc */ /* Misc */
OPC_CLZ = 0x20 | OPC_SPECIAL2, OPC_CLZ = 0x20 | OPC_SPECIAL2,
OPC_CLO = 0x21 | OPC_SPECIAL2, OPC_CLO = 0x21 | OPC_SPECIAL2,
@ -360,12 +355,6 @@ enum {
OPC_RDHWR = 0x3B | OPC_SPECIAL3, OPC_RDHWR = 0x3B | OPC_SPECIAL3,
OPC_GINV = 0x3D | OPC_SPECIAL3, OPC_GINV = 0x3D | OPC_SPECIAL3,
/* Loongson 2E */
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
/* MIPS DSP Load */ /* MIPS DSP Load */
OPC_LX_DSP = 0x0A | OPC_SPECIAL3, OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
/* MIPS DSP Arithmetic */ /* MIPS DSP Arithmetic */
@ -3572,46 +3561,6 @@ static void gen_cl(DisasContext *ctx, uint32_t opc,
} }
} }
/* Godson integer instructions */
static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
int rd, int rs, int rt)
{
TCGv t0, t1;
if (rd == 0) {
/* Treat as NOP. */
return;
}
t0 = tcg_temp_new();
t1 = tcg_temp_new();
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
switch (opc) {
case OPC_MULT_G_2E:
case OPC_MULT_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
break;
case OPC_MULTU_G_2E:
case OPC_MULTU_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
break;
#if defined(TARGET_MIPS64)
case OPC_DMULT_G_2E:
case OPC_DMULT_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
break;
case OPC_DMULTU_G_2E:
case OPC_DMULTU_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
break;
#endif
}
}
/* Loongson multimedia instructions */ /* Loongson multimedia instructions */
static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt) static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
{ {
@ -13467,11 +13416,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_MUL: case OPC_MUL:
gen_arith(ctx, op1, rd, rs, rt); gen_arith(ctx, op1, rd, rs, rt);
break; break;
case OPC_MULT_G_2F:
case OPC_MULTU_G_2F:
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
case OPC_CLO: case OPC_CLO:
case OPC_CLZ: case OPC_CLZ:
check_insn(ctx, ISA_MIPS_R1); check_insn(ctx, ISA_MIPS_R1);
@ -13496,11 +13440,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
check_mips_64(ctx); check_mips_64(ctx);
gen_cl(ctx, op1, rd, rs); gen_cl(ctx, op1, rd, rs);
break; break;
case OPC_DMULT_G_2F:
case OPC_DMULTU_G_2F:
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
#endif #endif
default: /* Invalid */ default: /* Invalid */
MIPS_INVAL("special2_legacy"); MIPS_INVAL("special2_legacy");
@ -13633,10 +13572,9 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
op1 = MASK_SPECIAL3(ctx->opcode); op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) { switch (op1) {
case OPC_MULT_G_2E: case OPC_MUL_PH_DSP:
case OPC_MULTU_G_2E:
/* /*
* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have * OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
* the same mask and op1. * the same mask and op1.
*/ */
if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) { if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MUL_PH_DSP)) {
@ -13667,8 +13605,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
gen_reserved_instruction(ctx); gen_reserved_instruction(ctx);
break; break;
} }
} else if (ctx->insn_flags & INSN_LOONGSON2E) {
gen_loongson_integer(ctx, op1, rd, rs, rt);
} else { } else {
gen_reserved_instruction(ctx); gen_reserved_instruction(ctx);
} }
@ -13897,11 +13833,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
} }
break; break;
#if defined(TARGET_MIPS64) #if defined(TARGET_MIPS64)
case OPC_DMULT_G_2E:
case OPC_DMULTU_G_2E:
check_insn(ctx, INSN_LOONGSON2E);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
case OPC_ABSQ_S_QH_DSP: case OPC_ABSQ_S_QH_DSP:
op2 = MASK_ABSQ_S_QH(ctx->opcode); op2 = MASK_ABSQ_S_QH(ctx->opcode);
switch (op2) { switch (op2) {