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:
parent
020cafa58e
commit
ad6e1f194f
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user