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
MULTu_G 011111 ..... ..... ..... 00000 01100- @rs_rt_rd
DMULTu_G 011111 ..... ..... ..... 00000 01110- @rs_rt_rd
DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
DIVU_G 011111 ..... ..... ..... 00000 011011 @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
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
DDIV_G 011100 ..... ..... ..... 00000 010101 @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);
}
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)
{
if (!decode_64bit_enabled(ctx)) {

View File

@ -327,11 +327,6 @@ enum {
OPC_MUL = 0x02 | OPC_SPECIAL2,
OPC_MSUB = 0x04 | 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 */
OPC_CLZ = 0x20 | OPC_SPECIAL2,
OPC_CLO = 0x21 | OPC_SPECIAL2,
@ -360,12 +355,6 @@ enum {
OPC_RDHWR = 0x3B | 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 */
OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
/* 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 */
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:
gen_arith(ctx, op1, rd, rs, rt);
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_CLZ:
check_insn(ctx, ISA_MIPS_R1);
@ -13496,11 +13440,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
check_mips_64(ctx);
gen_cl(ctx, op1, rd, rs);
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
default: /* Invalid */
MIPS_INVAL("special2_legacy");
@ -13633,10 +13572,9 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) {
case OPC_MULT_G_2E:
case OPC_MULTU_G_2E:
case OPC_MUL_PH_DSP:
/*
* 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.
*/
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);
break;
}
} else if (ctx->insn_flags & INSN_LOONGSON2E) {
gen_loongson_integer(ctx, op1, rd, rs, rt);
} else {
gen_reserved_instruction(ctx);
}
@ -13897,11 +13833,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
}
break;
#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:
op2 = MASK_ABSQ_S_QH(ctx->opcode);
switch (op2) {