qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 6/6] target/mips: Convert Loongson [D]MULT[U].G opcodes to de


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 make
no 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 bits
that are cleared.

I see.

There is no actual difference between MULT.G and MULTU.G, or DMULT.G and
DMULTU.G, because they don't record the most significant bits of the infinite
result 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 :>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]