|
From: | Philippe Mathieu-Daudé |
Subject: | Re: [PATCH 6/6] target/mips: Convert Loongson [D]MULT[U].G opcodes to decodetree |
Date: | Thu, 31 Aug 2023 22:31:15 +0200 |
User-agent: | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.14.0 |
On 31/8/23 21:12, Philippe Mathieu-Daudé wrote:
On 21/1/21 21:06, Richard Henderson wrote:On 1/12/21 11:55 AM, Philippe Mathieu-Daudé wrote: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> --- target/mips/godson2.decode | 5 ++ target/mips/loong-ext.decode | 5 ++ target/mips/loong_translate.c | 58 ++++++++++++++++++++++ target/mips/translate.c | 92 +---------------------------------- 4 files changed, 70 insertions(+), 90 deletions(-)
+static bool gen_lext_MULT_G(DisasContext *s, int rd, int rs, int rt, + bool is_double, bool is_unsigned) +{ + 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); + + if (is_unsigned && !is_double) { + tcg_gen_ext32u_tl(t0, t0); + tcg_gen_ext32u_tl(t1, t1); + }While this is a faithful conversion of the existing code, these extensions makeno difference to the result. They are redundant with+ tcg_gen_mul_tl(cpu_gpr[rd], t0, t1); + if (!is_double) { + tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);this one, which discards any bit that might have been set by the input bitsthat are cleared.I see.There is no actual difference between MULT.G and MULTU.G, or DMULT.G andDMULTU.G, because they don't record the most significant bits of the infiniteresult in any way.Right.+static bool trans_MULT_G(DisasContext *s, arg_muldiv *a) +{ + return gen_lext_MULT_G(s, a->rt, a->rs, a->rd, false, false); +} + +static bool trans_MULTU_G(DisasContext *s, arg_muldiv *a) +{ + return gen_lext_MULT_G(s, a->rt, a->rs, a->rd, false, true); +} + +static bool trans_DMULT_G(DisasContext *s, arg_muldiv *a) +{ + return gen_lext_MULT_G(s, a->rt, a->rs, a->rd, true, false); +} + +static bool trans_DMULTU_G(DisasContext *s, arg_muldiv *a) +{ + return gen_lext_MULT_G(s, a->rt, a->rs, a->rd, true, true); +}So... if you want to clean this up afterward, or before is up to you.
"before" ended being way simpler :>
[Prev in Thread] | Current Thread | [Next in Thread] |