* [PULL 06/14] target/mips: Convert Loongson DDIV.G opcodes to decodetree
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
@ 2024-11-04 10:52 ` Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 07/14] target/mips: Convert Loongson DIV.G " Philippe Mathieu-Daudé
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-11-04 10:52 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Richard Henderson,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
Introduce decode_loongson() to decode all Loongson vendor
specific opcodes. Start converting a single opcode: DDIV.G
(divide 64-bit signed integers).
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20241026175349.84523-5-philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/mips/tcg/translate.h | 1 +
target/mips/tcg/godson2.decode | 16 ++++++
target/mips/tcg/loong-ext.decode | 17 ++++++
target/mips/tcg/loong_translate.c | 86 +++++++++++++++++++++++++++++++
target/mips/tcg/translate.c | 26 ++--------
target/mips/tcg/meson.build | 3 ++
6 files changed, 126 insertions(+), 23 deletions(-)
create mode 100644 target/mips/tcg/godson2.decode
create mode 100644 target/mips/tcg/loong-ext.decode
create mode 100644 target/mips/tcg/loong_translate.c
diff --git a/target/mips/tcg/translate.h b/target/mips/tcg/translate.h
index ae6c25aa0c4..23a489c0f38 100644
--- a/target/mips/tcg/translate.h
+++ b/target/mips/tcg/translate.h
@@ -223,6 +223,7 @@ bool decode_64bit_enabled(DisasContext *ctx);
bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
+bool decode_ext_loongson(DisasContext *ctx, uint32_t insn);
#if defined(TARGET_MIPS64)
bool decode_ase_lcsr(DisasContext *ctx, uint32_t insn);
bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
diff --git a/target/mips/tcg/godson2.decode b/target/mips/tcg/godson2.decode
new file mode 100644
index 00000000000..47ea5a1c438
--- /dev/null
+++ b/target/mips/tcg/godson2.decode
@@ -0,0 +1,16 @@
+# Godson2 64-bit Integer instructions
+#
+# Copyright (C) 2021 Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+# Godson-2E Software Manual
+# (Document Number: godson2e-user-manual-V0.6)
+#
+
+&muldiv rs rt rd
+
+@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
+
+DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd
diff --git a/target/mips/tcg/loong-ext.decode b/target/mips/tcg/loong-ext.decode
new file mode 100644
index 00000000000..8b78ec48599
--- /dev/null
+++ b/target/mips/tcg/loong-ext.decode
@@ -0,0 +1,17 @@
+# Loongson 64-bit Extension instructions
+#
+# Copyright (C) 2021 Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# Reference:
+# STLS2F01 User Manual
+# Appendix A: new integer instructions
+# (Document Number: UM0447)
+#
+
+&muldiv rs rt rd !extern
+
+@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
+
+DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
diff --git a/target/mips/tcg/loong_translate.c b/target/mips/tcg/loong_translate.c
new file mode 100644
index 00000000000..55adc0f6fc4
--- /dev/null
+++ b/target/mips/tcg/loong_translate.c
@@ -0,0 +1,86 @@
+/*
+ * MIPS Loongson 64-bit translation routines
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ * Copyright (c) 2006 Marius Groeger (FPU operations)
+ * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
+ * Copyright (c) 2011 Richard Henderson <rth@twiddle.net>
+ * Copyright (c) 2021 Philippe Mathieu-Daudé
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "qemu/osdep.h"
+#include "translate.h"
+
+/* Include the auto-generated decoder. */
+#include "decode-godson2.c.inc"
+#include "decode-loong-ext.c.inc"
+
+/*
+ * Word or double-word Fixed-point instructions.
+ * ---------------------------------------------
+ *
+ * Fixed-point multiplies and divisions write only
+ * one result into general-purpose registers.
+ */
+
+static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, int rt)
+{
+ TCGv t0, t1;
+ TCGLabel *l1, *l2, *l3;
+
+ 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();
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ l3 = gen_new_label();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
+ tcg_gen_movi_tl(cpu_gpr[rd], 0);
+ tcg_gen_br(l3);
+ gen_set_label(l1);
+
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
+ tcg_gen_mov_tl(cpu_gpr[rd], t0);
+
+ tcg_gen_br(l3);
+ gen_set_label(l2);
+ tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
+ gen_set_label(l3);
+
+ return true;
+}
+
+static bool trans_DDIV_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_DIV_G(s, a->rd, a->rs, a->rt);
+}
+
+bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
+{
+ if (!decode_64bit_enabled(ctx)) {
+ return false;
+ }
+ if ((ctx->insn_flags & INSN_LOONGSON2E) && decode_godson2(ctx, ctx->opcode)) {
+ return true;
+ }
+ if ((ctx->insn_flags & ASE_LEXT) && decode_loong_ext(ctx, ctx->opcode)) {
+ return true;
+ }
+ return false;
+}
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 509488fdc7a..73445dd9074 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -333,7 +333,6 @@ enum {
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
- OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
@@ -375,7 +374,6 @@ enum {
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
- OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
@@ -3698,25 +3696,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
case OPC_DMULTU_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
break;
- case OPC_DDIV_G_2E:
- case OPC_DDIV_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l3);
- gen_set_label(l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
- tcg_gen_mov_tl(cpu_gpr[rd], t0);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
- gen_set_label(l3);
- }
- break;
case OPC_DDIVU_G_2E:
case OPC_DDIVU_G_2F:
{
@@ -13654,7 +13633,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_DMULT_G_2F:
case OPC_DMULTU_G_2F:
- case OPC_DDIV_G_2F:
case OPC_DDIVU_G_2F:
case OPC_DMOD_G_2F:
case OPC_DMODU_G_2F:
@@ -14061,7 +14039,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
}
break;
#if defined(TARGET_MIPS64)
- case OPC_DDIV_G_2E:
case OPC_DDIVU_G_2E:
case OPC_DMULT_G_2E:
case OPC_DMULTU_G_2E:
@@ -15262,6 +15239,9 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
return;
}
+ if (TARGET_LONG_BITS == 64 && decode_ext_loongson(ctx, ctx->opcode)) {
+ return;
+ }
#if defined(TARGET_MIPS64)
if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
return;
diff --git a/target/mips/tcg/meson.build b/target/mips/tcg/meson.build
index ea7fb582f2a..7b18e6c4c8b 100644
--- a/target/mips/tcg/meson.build
+++ b/target/mips/tcg/meson.build
@@ -5,6 +5,8 @@ gen = [
decodetree.process('vr54xx.decode', extra_args: '--decode=decode_ext_vr54xx'),
decodetree.process('octeon.decode', extra_args: '--decode=decode_ext_octeon'),
decodetree.process('lcsr.decode', extra_args: '--decode=decode_ase_lcsr'),
+ decodetree.process('godson2.decode', extra_args: ['--static-decode=decode_godson2']),
+ decodetree.process('loong-ext.decode', extra_args: ['--static-decode=decode_loong_ext']),
]
mips_ss.add(gen)
@@ -28,6 +30,7 @@ mips_ss.add(when: 'TARGET_MIPS64', if_true: files(
'tx79_translate.c',
'octeon_translate.c',
'lcsr_translate.c',
+ 'loong_translate.c',
), if_false: files(
'mxu_translate.c',
))
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 07/14] target/mips: Convert Loongson DIV.G opcodes to decodetree
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 06/14] target/mips: Convert Loongson DDIV.G opcodes to decodetree Philippe Mathieu-Daudé
@ 2024-11-04 10:52 ` Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 08/14] target/mips: Convert Loongson [D]DIVU.G " Philippe Mathieu-Daudé
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-11-04 10:52 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Richard Henderson,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
DIV.G and DDIV.G are very similar. Provide gen_lext_DIV_G() a
'is_double' argument so it can generate DIV.G (divide 32-bit
signed integers).
With this commit we explicit the template used to generate
opcode for 32/64-bit word variants. Next commits will be less
verbose by providing both variants at once.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20241026175349.84523-6-philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/mips/tcg/godson2.decode | 1 +
target/mips/tcg/loong-ext.decode | 1 +
target/mips/tcg/loong_translate.c | 28 ++++++++++++++++++++++------
target/mips/tcg/translate.c | 26 --------------------------
4 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/target/mips/tcg/godson2.decode b/target/mips/tcg/godson2.decode
index 47ea5a1c438..cbf24ed88da 100644
--- a/target/mips/tcg/godson2.decode
+++ b/target/mips/tcg/godson2.decode
@@ -13,4 +13,5 @@
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
+DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd
diff --git a/target/mips/tcg/loong-ext.decode b/target/mips/tcg/loong-ext.decode
index 8b78ec48599..9397606beb6 100644
--- a/target/mips/tcg/loong-ext.decode
+++ b/target/mips/tcg/loong-ext.decode
@@ -14,4 +14,5 @@
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
+DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd
DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
diff --git a/target/mips/tcg/loong_translate.c b/target/mips/tcg/loong_translate.c
index 55adc0f6fc4..cb42acbdca4 100644
--- a/target/mips/tcg/loong_translate.c
+++ b/target/mips/tcg/loong_translate.c
@@ -25,15 +25,18 @@
* one result into general-purpose registers.
*/
-static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, int rt)
+static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, int rt,
+ bool is_double)
{
TCGv t0, t1;
TCGLabel *l1, *l2, *l3;
- if (TARGET_LONG_BITS != 64) {
- return false;
+ if (is_double) {
+ if (TARGET_LONG_BITS != 64) {
+ return false;
+ }
+ check_mips_64(s);
}
- check_mips_64(s);
if (rd == 0) {
/* Treat as NOP. */
@@ -49,26 +52,39 @@ static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, int rt)
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
+ if (!is_double) {
+ tcg_gen_ext32s_tl(t0, t0);
+ tcg_gen_ext32s_tl(t1, t1);
+ }
tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
tcg_gen_movi_tl(cpu_gpr[rd], 0);
tcg_gen_br(l3);
gen_set_label(l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, is_double && TARGET_LONG_BITS == 64
+ ? LLONG_MIN : INT_MIN, l2);
tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
tcg_gen_mov_tl(cpu_gpr[rd], t0);
tcg_gen_br(l3);
gen_set_label(l2);
tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
+ if (!is_double) {
+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+ }
gen_set_label(l3);
return true;
}
+static bool trans_DIV_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_DIV_G(s, a->rd, a->rs, a->rt, false);
+}
+
static bool trans_DDIV_G(DisasContext *s, arg_muldiv *a)
{
- return gen_lext_DIV_G(s, a->rd, a->rs, a->rt);
+ return gen_lext_DIV_G(s, a->rd, a->rs, a->rt, true);
}
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 73445dd9074..1c38e893d31 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -332,7 +332,6 @@ enum {
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
- OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
@@ -370,7 +369,6 @@ enum {
/* Loongson 2E */
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
- OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
@@ -3613,28 +3611,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
break;
- case OPC_DIV_G_2E:
- case OPC_DIV_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- tcg_gen_ext32s_tl(t0, t0);
- tcg_gen_ext32s_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l3);
- gen_set_label(l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
- tcg_gen_mov_tl(cpu_gpr[rd], t0);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
- tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
- gen_set_label(l3);
- }
- break;
case OPC_DIVU_G_2E:
case OPC_DIVU_G_2F:
{
@@ -13598,7 +13574,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_MUL:
gen_arith(ctx, op1, rd, rs, rt);
break;
- case OPC_DIV_G_2F:
case OPC_DIVU_G_2F:
case OPC_MULT_G_2F:
case OPC_MULTU_G_2F:
@@ -13771,7 +13746,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) {
- case OPC_DIV_G_2E:
case OPC_DIVU_G_2E:
case OPC_MOD_G_2E:
case OPC_MODU_G_2E:
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 08/14] target/mips: Convert Loongson [D]DIVU.G opcodes to decodetree
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 06/14] target/mips: Convert Loongson DDIV.G opcodes to decodetree Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 07/14] target/mips: Convert Loongson DIV.G " Philippe Mathieu-Daudé
@ 2024-11-04 10:52 ` Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 09/14] target/mips: Convert Loongson [D]MOD[U].G " Philippe Mathieu-Daudé
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-11-04 10:52 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Richard Henderson,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
Convert DIVU.G (divide 32-bit unsigned integers) and DDIVU.G
(divide 64-bit unsigned integers) opcodes to decodetree.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20241026175349.84523-7-philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/mips/tcg/godson2.decode | 2 ++
target/mips/tcg/loong-ext.decode | 2 ++
target/mips/tcg/loong_translate.c | 54 +++++++++++++++++++++++++++++++
target/mips/tcg/translate.c | 37 ---------------------
4 files changed, 58 insertions(+), 37 deletions(-)
diff --git a/target/mips/tcg/godson2.decode b/target/mips/tcg/godson2.decode
index cbf24ed88da..581cb9c8608 100644
--- a/target/mips/tcg/godson2.decode
+++ b/target/mips/tcg/godson2.decode
@@ -14,4 +14,6 @@
@rs_rt_rd ...... rs:5 rt:5 rd:5 ..... ...... &muldiv
DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
+DIVU_G 011111 ..... ..... ..... 00000 011011 @rs_rt_rd
DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd
+DDIVU_G 011111 ..... ..... ..... 00000 011111 @rs_rt_rd
diff --git a/target/mips/tcg/loong-ext.decode b/target/mips/tcg/loong-ext.decode
index 9397606beb6..e222167af56 100644
--- a/target/mips/tcg/loong-ext.decode
+++ b/target/mips/tcg/loong-ext.decode
@@ -16,3 +16,5 @@
DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd
DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
+DIVU_G 011100 ..... ..... ..... 00000 010110 @rs_rt_rd
+DDIVU_G 011100 ..... ..... ..... 00000 010111 @rs_rt_rd
diff --git a/target/mips/tcg/loong_translate.c b/target/mips/tcg/loong_translate.c
index cb42acbdca4..2484b8a68df 100644
--- a/target/mips/tcg/loong_translate.c
+++ b/target/mips/tcg/loong_translate.c
@@ -87,6 +87,60 @@ static bool trans_DDIV_G(DisasContext *s, arg_muldiv *a)
return gen_lext_DIV_G(s, a->rd, a->rs, a->rt, true);
}
+static bool gen_lext_DIVU_G(DisasContext *s, int rd, int rs, int rt,
+ bool is_double)
+{
+ TCGv t0, t1;
+ TCGLabel *l1, *l2;
+
+ 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();
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ if (!is_double) {
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ }
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
+ tcg_gen_movi_tl(cpu_gpr[rd], 0);
+
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
+ if (!is_double) {
+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+ }
+ gen_set_label(l2);
+
+ return true;
+}
+
+static bool trans_DIVU_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_DIVU_G(s, a->rd, a->rs, a->rt, false);
+}
+
+static bool trans_DDIVU_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_DIVU_G(s, a->rd, a->rs, a->rt, true);
+}
+
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
{
if (!decode_64bit_enabled(ctx)) {
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 1c38e893d31..53bbbb761f8 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -332,8 +332,6 @@ enum {
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
- OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
- OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
@@ -369,10 +367,8 @@ enum {
/* Loongson 2E */
OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
- OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
- OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
@@ -3611,22 +3607,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
break;
- case OPC_DIVU_G_2E:
- case OPC_DIVU_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_ext32u_tl(t0, t0);
- tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
- tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
- gen_set_label(l2);
- }
- break;
case OPC_MOD_G_2E:
case OPC_MOD_G_2F:
{
@@ -3672,19 +3652,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
case OPC_DMULTU_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
break;
- case OPC_DDIVU_G_2E:
- case OPC_DDIVU_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
- gen_set_label(l2);
- }
- break;
case OPC_DMOD_G_2E:
case OPC_DMOD_G_2F:
{
@@ -13574,7 +13541,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
case OPC_MUL:
gen_arith(ctx, op1, rd, rs, rt);
break;
- case OPC_DIVU_G_2F:
case OPC_MULT_G_2F:
case OPC_MULTU_G_2F:
case OPC_MOD_G_2F:
@@ -13608,7 +13574,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_DMULT_G_2F:
case OPC_DMULTU_G_2F:
- case OPC_DDIVU_G_2F:
case OPC_DMOD_G_2F:
case OPC_DMODU_G_2F:
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
@@ -13746,7 +13711,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) {
- case OPC_DIVU_G_2E:
case OPC_MOD_G_2E:
case OPC_MODU_G_2E:
case OPC_MULT_G_2E:
@@ -14013,7 +13977,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
}
break;
#if defined(TARGET_MIPS64)
- case OPC_DDIVU_G_2E:
case OPC_DMULT_G_2E:
case OPC_DMULTU_G_2E:
case OPC_DMOD_G_2E:
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 09/14] target/mips: Convert Loongson [D]MOD[U].G opcodes to decodetree
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2024-11-04 10:52 ` [PULL 08/14] target/mips: Convert Loongson [D]DIVU.G " Philippe Mathieu-Daudé
@ 2024-11-04 10:52 ` Philippe Mathieu-Daudé
2024-11-04 10:52 ` [PULL 10/14] target/mips: Convert Loongson [D]MULT[U].G " Philippe Mathieu-Daudé
2024-11-05 15:47 ` [PULL 00/14] MIPS patches for 2024-11-04 Peter Maydell
5 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-11-04 10:52 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Richard Henderson,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
Convert the following opcodes to decodetree:
- MOD.G - mod 32-bit signed integers
- MODU.G - mod 32-bit unsigned integers
- DMOD.G - mod 64-bit signed integers
- DMODU.G - mod 64-bit unsigned integers
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <20241026175349.84523-8-philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
target/mips/tcg/godson2.decode | 5 ++
target/mips/tcg/loong-ext.decode | 5 ++
target/mips/tcg/loong_translate.c | 111 ++++++++++++++++++++++++++++++
target/mips/tcg/translate.c | 82 ----------------------
4 files changed, 121 insertions(+), 82 deletions(-)
diff --git a/target/mips/tcg/godson2.decode b/target/mips/tcg/godson2.decode
index 581cb9c8608..c03c8b717d9 100644
--- a/target/mips/tcg/godson2.decode
+++ b/target/mips/tcg/godson2.decode
@@ -17,3 +17,8 @@ DIV_G 011111 ..... ..... ..... 00000 011010 @rs_rt_rd
DIVU_G 011111 ..... ..... ..... 00000 011011 @rs_rt_rd
DDIV_G 011111 ..... ..... ..... 00000 011110 @rs_rt_rd
DDIVU_G 011111 ..... ..... ..... 00000 011111 @rs_rt_rd
+
+MOD_G 011111 ..... ..... ..... 00000 100010 @rs_rt_rd
+MODU_G 011111 ..... ..... ..... 00000 100011 @rs_rt_rd
+DMOD_G 011111 ..... ..... ..... 00000 100110 @rs_rt_rd
+DMODU_G 011111 ..... ..... ..... 00000 100111 @rs_rt_rd
diff --git a/target/mips/tcg/loong-ext.decode b/target/mips/tcg/loong-ext.decode
index e222167af56..f0fd36c9218 100644
--- a/target/mips/tcg/loong-ext.decode
+++ b/target/mips/tcg/loong-ext.decode
@@ -18,3 +18,8 @@ DIV_G 011100 ..... ..... ..... 00000 010100 @rs_rt_rd
DDIV_G 011100 ..... ..... ..... 00000 010101 @rs_rt_rd
DIVU_G 011100 ..... ..... ..... 00000 010110 @rs_rt_rd
DDIVU_G 011100 ..... ..... ..... 00000 010111 @rs_rt_rd
+
+MOD_G 011100 ..... ..... ..... 00000 011100 @rs_rt_rd
+DMOD_G 011100 ..... ..... ..... 00000 011101 @rs_rt_rd
+MODU_G 011100 ..... ..... ..... 00000 011110 @rs_rt_rd
+DMODU_G 011100 ..... ..... ..... 00000 011111 @rs_rt_rd
diff --git a/target/mips/tcg/loong_translate.c b/target/mips/tcg/loong_translate.c
index 2484b8a68df..39afed7d5f8 100644
--- a/target/mips/tcg/loong_translate.c
+++ b/target/mips/tcg/loong_translate.c
@@ -141,6 +141,117 @@ static bool trans_DDIVU_G(DisasContext *s, arg_muldiv *a)
return gen_lext_DIVU_G(s, a->rd, a->rs, a->rt, true);
}
+static bool gen_lext_MOD_G(DisasContext *s, int rd, int rs, int rt,
+ bool is_double)
+{
+ TCGv t0, t1;
+ TCGLabel *l1, *l2, *l3;
+
+ 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();
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+ l3 = gen_new_label();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ if (!is_double) {
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ }
+ tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, is_double && TARGET_LONG_BITS == 64
+ ? LLONG_MIN : INT_MIN, l2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
+ gen_set_label(l1);
+ tcg_gen_movi_tl(cpu_gpr[rd], 0);
+ tcg_gen_br(l3);
+ gen_set_label(l2);
+ tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
+ if (!is_double) {
+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+ }
+ gen_set_label(l3);
+
+ return true;
+}
+
+static bool trans_MOD_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_MOD_G(s, a->rd, a->rs, a->rt, false);
+}
+
+static bool trans_DMOD_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_MOD_G(s, a->rd, a->rs, a->rt, true);
+}
+
+static bool gen_lext_MODU_G(DisasContext *s, int rd, int rs, int rt,
+ bool is_double)
+{
+ TCGv t0, t1;
+ TCGLabel *l1, *l2;
+
+ 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();
+ l1 = gen_new_label();
+ l2 = gen_new_label();
+
+ gen_load_gpr(t0, rs);
+ gen_load_gpr(t1, rt);
+
+ if (!is_double) {
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
+ }
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
+ tcg_gen_movi_tl(cpu_gpr[rd], 0);
+ tcg_gen_br(l2);
+ gen_set_label(l1);
+ tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
+ if (!is_double) {
+ tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
+ }
+ gen_set_label(l2);
+
+ return true;
+}
+
+static bool trans_MODU_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, false);
+}
+
+static bool trans_DMODU_G(DisasContext *s, arg_muldiv *a)
+{
+ return gen_lext_MODU_G(s, a->rd, a->rs, a->rt, true);
+}
+
bool decode_ext_loongson(DisasContext *ctx, uint32_t insn)
{
if (!decode_64bit_enabled(ctx)) {
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 53bbbb761f8..4abc30a6a5f 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -332,10 +332,6 @@ enum {
OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
- OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
- OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
- OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
- OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
/* Misc */
OPC_CLZ = 0x20 | OPC_SPECIAL2,
OPC_CLO = 0x21 | OPC_SPECIAL2,
@@ -369,10 +365,6 @@ enum {
OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
- OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
- OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
- OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
- OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
/* MIPS DSP Load */
OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
@@ -3607,42 +3599,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
break;
- case OPC_MOD_G_2E:
- case OPC_MOD_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- tcg_gen_ext32u_tl(t0, t0);
- tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
- tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
- gen_set_label(l3);
- }
- break;
- case OPC_MODU_G_2E:
- case OPC_MODU_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_ext32u_tl(t0, t0);
- tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
- tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
- gen_set_label(l2);
- }
- break;
#if defined(TARGET_MIPS64)
case OPC_DMULT_G_2E:
case OPC_DMULT_G_2F:
@@ -3652,36 +3608,6 @@ static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
case OPC_DMULTU_G_2F:
tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
break;
- case OPC_DMOD_G_2E:
- case OPC_DMOD_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
- gen_set_label(l3);
- }
- break;
- case OPC_DMODU_G_2E:
- case OPC_DMODU_G_2F:
- {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rd], 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
- gen_set_label(l2);
- }
- break;
#endif
}
}
@@ -13543,8 +13469,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_MULT_G_2F:
case OPC_MULTU_G_2F:
- case OPC_MOD_G_2F:
- case OPC_MODU_G_2F:
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
@@ -13574,8 +13498,6 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
break;
case OPC_DMULT_G_2F:
case OPC_DMULTU_G_2F:
- case OPC_DMOD_G_2F:
- case OPC_DMODU_G_2F:
check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
@@ -13711,8 +13633,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
op1 = MASK_SPECIAL3(ctx->opcode);
switch (op1) {
- case OPC_MOD_G_2E:
- case OPC_MODU_G_2E:
case OPC_MULT_G_2E:
case OPC_MULTU_G_2E:
/*
@@ -13979,8 +13899,6 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
#if defined(TARGET_MIPS64)
case OPC_DMULT_G_2E:
case OPC_DMULTU_G_2E:
- case OPC_DMOD_G_2E:
- case OPC_DMODU_G_2E:
check_insn(ctx, INSN_LOONGSON2E);
gen_loongson_integer(ctx, op1, rd, rs, rt);
break;
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PULL 10/14] target/mips: Convert Loongson [D]MULT[U].G opcodes to decodetree
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2024-11-04 10:52 ` [PULL 09/14] target/mips: Convert Loongson [D]MOD[U].G " Philippe Mathieu-Daudé
@ 2024-11-04 10:52 ` Philippe Mathieu-Daudé
2024-11-05 15:47 ` [PULL 00/14] MIPS patches for 2024-11-04 Peter Maydell
5 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-11-04 10:52 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Richard Henderson,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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>
---
target/mips/tcg/godson2.decode | 3 ++
target/mips/tcg/loong-ext.decode | 3 ++
target/mips/tcg/loong_translate.c | 41 +++++++++++++++++
target/mips/tcg/translate.c | 73 +------------------------------
4 files changed, 49 insertions(+), 71 deletions(-)
diff --git a/target/mips/tcg/godson2.decode b/target/mips/tcg/godson2.decode
index c03c8b717d9..25b396b6822 100644
--- a/target/mips/tcg/godson2.decode
+++ b/target/mips/tcg/godson2.decode
@@ -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
diff --git a/target/mips/tcg/loong-ext.decode b/target/mips/tcg/loong-ext.decode
index f0fd36c9218..b43979d0ef5 100644
--- a/target/mips/tcg/loong-ext.decode
+++ b/target/mips/tcg/loong-ext.decode
@@ -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
diff --git a/target/mips/tcg/loong_translate.c b/target/mips/tcg/loong_translate.c
index 39afed7d5f8..87e7122b9a1 100644
--- a/target/mips/tcg/loong_translate.c
+++ b/target/mips/tcg/loong_translate.c
@@ -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)) {
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 4abc30a6a5f..2d01f5c4a8b 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -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) {
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PULL 00/14] MIPS patches for 2024-11-04
2024-11-04 10:52 [PULL 00/14] MIPS patches for 2024-11-04 Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2024-11-04 10:52 ` [PULL 10/14] target/mips: Convert Loongson [D]MULT[U].G " Philippe Mathieu-Daudé
@ 2024-11-05 15:47 ` Peter Maydell
5 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2024-11-05 15:47 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: qemu-devel
On Mon, 4 Nov 2024 at 10:53, Philippe Mathieu-Daudé <philmd@linaro.org> wrote:
>
> The following changes since commit 92ec7805190313c9e628f8fc4eb4f932c15247bd:
>
> Merge tag 'pull-riscv-to-apply-20241031-1' of https://github.com/alistair23/qemu into staging (2024-10-31 16:34:25 +0000)
>
> are available in the Git repository at:
>
> https://github.com/philmd/qemu.git tags/mips-20241104
>
> for you to fetch changes up to a144a3baa61e3fca1a7946685128c349dd92c76f:
>
> target/mips: Remove unused CPUMIPSState::current_fpu field (2024-11-03 05:52:49 -0300)
>
> ----------------------------------------------------------------
> MIPS patches queue
>
> - Migrate missing CP0 TLB MemoryMapID register (Yongbok)
> - Enable MSA ASE for mips32r6-generic (Aleksandar)
> - Convert Loongson LEXT opcodes to decodetree (Philippe)
> - Introduce ase_3d_available and disas_mt_available helpers (Philippe)
>
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/9.2
for any user-visible changes.
-- PMM
^ permalink raw reply [flat|nested] 8+ messages in thread