From 3b948f053fc588154d95228da8a6561c61c66104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 27 Dec 2018 19:00:44 +0100 Subject: [PATCH] target/mips: Support R5900 three-operand MADD and MADDU instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three-operand MADD and MADDU are specific to Sony R5900 core, and Toshiba TX19/TX39/TX79 cores as well. The "32-Bit TX System RISC TX39 Family Architecture manual" is available at https://wiki.qemu.org/File:DSAE0022432.pdf Reviewed-by: Aleksandar Markovic Signed-off-by: Aleksandar Markovic Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Fredrik Noring Tested-by: Fredrik Noring --- target/mips/translate.c | 58 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index c79f9886d9..0a49926d3e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -5033,8 +5033,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } /* - * These MULT and MULTU instructions implemented in for example the - * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * These MULT[U] and MADD[U] instructions implemented in for example + * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core * architectures are special three-operand variants with the syntax * * MULT[U][1] rd, rs, rt @@ -5043,6 +5043,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, * * (rd, LO, HI) <- rs * rt * + * and + * + * MADD[U] rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- (LO, HI) + rs * rt + * * where the low-order 32-bits of the result is placed into both the * GPR rd and the special register LO. The high-order 32-bits of the * result is placed into the special register HI. @@ -5099,8 +5107,48 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, tcg_temp_free_i32(t3); } break; + case MMI_OPC_MADD: + { + TCGv_i64 t2 = tcg_temp_new_i64(); + TCGv_i64 t3 = tcg_temp_new_i64(); + + tcg_gen_ext_tl_i64(t2, t0); + tcg_gen_ext_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + if (rd) { + gen_move_low32(cpu_gpr[rd], t2); + } + tcg_temp_free_i64(t2); + } + break; + case MMI_OPC_MADDU: + { + TCGv_i64 t2 = tcg_temp_new_i64(); + TCGv_i64 t3 = tcg_temp_new_i64(); + + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + tcg_gen_extu_tl_i64(t2, t0); + tcg_gen_extu_tl_i64(t3, t1); + tcg_gen_mul_i64(t2, t2, t3); + tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); + tcg_gen_add_i64(t2, t2, t3); + tcg_temp_free_i64(t3); + gen_move_low32(cpu_LO[acc], t2); + gen_move_high32(cpu_HI[acc], t2); + if (rd) { + gen_move_low32(cpu_gpr[rd], t2); + } + tcg_temp_free_i64(t2); + } + break; default: - MIPS_INVAL("mul TXx9"); + MIPS_INVAL("mul/madd TXx9"); generate_exception_end(ctx, EXCP_RI); goto out; } @@ -27320,6 +27368,8 @@ static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) break; case MMI_OPC_MULT1: case MMI_OPC_MULTU1: + case MMI_OPC_MADD: + case MMI_OPC_MADDU: gen_mul_txx9(ctx, opc, rd, rs, rt); break; case MMI_OPC_DIV1: @@ -27334,8 +27384,6 @@ static void decode_mmi(CPUMIPSState *env, DisasContext *ctx) case MMI_OPC_MFHI1: gen_HILO1_tx79(ctx, opc, rd); break; - case MMI_OPC_MADD: /* TODO: MMI_OPC_MADD */ - case MMI_OPC_MADDU: /* TODO: MMI_OPC_MADDU */ case MMI_OPC_PLZCW: /* TODO: MMI_OPC_PLZCW */ case MMI_OPC_MADD1: /* TODO: MMI_OPC_MADD1 */ case MMI_OPC_MADDU1: /* TODO: MMI_OPC_MADDU1 */