Re: [PATCH 3/6] target/mips: Convert Loongson DIV.G opcodes to decodetree

2021-01-21 Thread Richard Henderson
On 1/12/21 11:55 AM, Philippe Mathieu-Daudé wrote:
> 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.
> 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/godson2.decode|  1 +
>  target/mips/loong-ext.decode  |  1 +
>  target/mips/loong_translate.c | 28 ++--
>  target/mips/translate.c   | 26 --
>  4 files changed, 24 insertions(+), 32 deletions(-)

With the double-extend pasto fixed,
Reviewed-by: Richard Henderson 

r~




Re: [PATCH 3/6] target/mips: Convert Loongson DIV.G opcodes to decodetree

2021-01-12 Thread Philippe Mathieu-Daudé
On Tue, Jan 12, 2021 at 10:55 PM Philippe Mathieu-Daudé  wrote:
>
> 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.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  target/mips/godson2.decode|  1 +
>  target/mips/loong-ext.decode  |  1 +
>  target/mips/loong_translate.c | 28 ++--
>  target/mips/translate.c   | 26 --
>  4 files changed, 24 insertions(+), 32 deletions(-)
...
> @@ -51,18 +54,26 @@ 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(t0, t0);

Oops copy/paste problem...

> +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);
...



[PATCH 3/6] target/mips: Convert Loongson DIV.G opcodes to decodetree

2021-01-12 Thread Philippe Mathieu-Daudé
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.

Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/godson2.decode|  1 +
 target/mips/loong-ext.decode  |  1 +
 target/mips/loong_translate.c | 28 ++--
 target/mips/translate.c   | 26 --
 4 files changed, 24 insertions(+), 32 deletions(-)

diff --git a/target/mips/godson2.decode b/target/mips/godson2.decode
index cbe22285740..b56a93a1999 100644
--- a/target/mips/godson2.decode
+++ b/target/mips/godson2.decode
@@ -13,4 +13,5 @@
 
 @rs_rt_rd   .. rs:5  rt:5  rd:5  . ..   
 
+DIV.G   01 . . . 0 011010   @rs_rt_rd
 DDIV.G  01 . . . 0 00   @rs_rt_rd
diff --git a/target/mips/loong-ext.decode b/target/mips/loong-ext.decode
index 557fe06c14a..331c2226ae3 100644
--- a/target/mips/loong-ext.decode
+++ b/target/mips/loong-ext.decode
@@ -14,4 +14,5 @@
 
 @rs_rt_rd   .. rs:5  rt:5  rd:5  . ..   
 
+DIV.G   011100 . . . 0 010100   @rs_rt_rd
 DDIV.G  011100 . . . 0 010101   @rs_rt_rd
diff --git a/target/mips/loong_translate.c b/target/mips/loong_translate.c
index c452472e7a7..634d4ba8031 100644
--- a/target/mips/loong_translate.c
+++ b/target/mips/loong_translate.c
@@ -27,15 +27,18 @@
  * 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. */
@@ -51,18 +54,26 @@ 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(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 ? -1LL << 63 : 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);
 
 tcg_temp_free(t0);
@@ -71,9 +82,14 @@ static bool gen_lext_DIV_G(DisasContext *s, int rd, int rs, 
int rt)
 return true;
 }
 
+static bool trans_DIV_G(DisasContext *s, arg_muldiv *a)
+{
+return gen_lext_DIV_G(s, a->rt, a->rs, a->rd, false);
+}
+
 static bool trans_DDIV_G(DisasContext *s, arg_muldiv *a)
 {
-return gen_lext_DIV_G(s, a->rt, a->rs, a->rd);
+return gen_lext_DIV_G(s, a->rt, a->rs, a->rd, true);
 }
 
 bool decode_loongson(DisasContext *ctx, uint32_t insn)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index c427ea98952..7cefff44d74 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -342,7 +342,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,
@@ -380,7 +379,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,
@@ -5023,28 +5021,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);
-