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
|
@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
|
||||||
|
@ -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
|
||||||
|
@ -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)) {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user