qemu-riscv
[Top][All Lists]
Advanced

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

[PATCH v2 20/27] target/riscv: addition of the 'd' insns for 128-bit mul


From: Frédéric Pétrot
Subject: [PATCH v2 20/27] target/riscv: addition of the 'd' insns for 128-bit mult/div/rem
Date: Wed, 6 Oct 2021 23:28:26 +0200

All mult/div/rem instructions that work on double integers (suffixed
'd') can be tcg-generated in a few micro-ops, they are added here.

Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org>
---
 target/riscv/insn32.decode              |   7 ++
 target/riscv/insn_trans/trans_rvm.c.inc | 112 +++++++++++++++++++++++-
 2 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index be8d6aa85f..380604acee 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -198,6 +198,13 @@ divuw    0000001 .....  ..... 101 ..... 0111011 @r
 remw     0000001 .....  ..... 110 ..... 0111011 @r
 remuw    0000001 .....  ..... 111 ..... 0111011 @r
 
+# *** RV128M Standard Extension (in addition to RV64M) ***
+muld     0000001 .....  ..... 000 ..... 1111011 @r
+divd     0000001 .....  ..... 100 ..... 1111011 @r
+divud    0000001 .....  ..... 101 ..... 1111011 @r
+remd     0000001 .....  ..... 110 ..... 1111011 @r
+remud    0000001 .....  ..... 111 ..... 1111011 @r
+
 # *** RV32A Standard Extension ***
 lr_w       00010 . . 00000 ..... 010 ..... 0101111 @atom_ld
 sc_w       00011 . . ..... ..... 010 ..... 0101111 @atom_st
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc 
b/target/riscv/insn_trans/trans_rvm.c.inc
index d61c79450c..9ed9ba0f0f 100644
--- a/target/riscv/insn_trans/trans_rvm.c.inc
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
@@ -390,13 +390,25 @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
                      tcg_gen_mul_tl, tcg_gen_mul_tl, gen_mulw_i128);
 }
 
+static void gen_divw_i128(TCGv rdl, TCGv rdh,
+                          TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_div(rdl, rs1l, rs2l);
+}
+
 static bool trans_divw(DisasContext *ctx, arg_divw *a)
 {
     REQUIRE_64_OR_128BIT(ctx);
     REQUIRE_EXT(ctx, RVM);
     ctx->w = true;
     return gen_arith(ctx, a, EXT_SIGN,
-                     gen_div, gen_div, NULL);
+                     gen_div, gen_div, gen_divw_i128);
+}
+
+static void gen_divuw_i128(TCGv rdl, TCGv rdh,
+                           TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_divu(rdl, rs1l, rs2l);
 }
 
 static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
@@ -405,7 +417,13 @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
     REQUIRE_EXT(ctx, RVM);
     ctx->w = true;
     return gen_arith(ctx, a, EXT_ZERO,
-                     gen_divu, gen_divu, NULL);
+                     gen_divu, gen_divu, gen_divuw_i128);
+}
+
+static void gen_remw_i128(TCGv rdl, TCGv rdh,
+                          TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_rem(rdl, rs1l, rs2l);
 }
 
 static bool trans_remw(DisasContext *ctx, arg_remw *a)
@@ -414,7 +432,13 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a)
     REQUIRE_EXT(ctx, RVM);
     ctx->w = true;
     return gen_arith(ctx, a, EXT_SIGN,
-                     gen_rem, gen_rem, NULL);
+                     gen_rem, gen_rem, gen_remw_i128);
+}
+
+static void gen_remuw_i128(TCGv rdl, TCGv rdh,
+                           TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_remu(rdl, rs1l, rs2l);
 }
 
 static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
@@ -423,5 +447,85 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
     REQUIRE_EXT(ctx, RVM);
     ctx->w = true;
     return gen_arith(ctx, a, EXT_ZERO,
-                     gen_remu, gen_remu, NULL);
+                     gen_remu, gen_remu, gen_remuw_i128);
+}
+
+static void gen_muld_i128(TCGv rdl, TCGv rdh,
+                          TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    tcg_gen_mul_tl(rdl, rs1l, rs2l);
+}
+
+static bool trans_muld(DisasContext *ctx, arg_muld *a)
+{
+    REQUIRE_128BIT(ctx);
+    REQUIRE_EXT(ctx, RVM);
+    ctx->d = true;
+
+    return gen_arith(ctx, a, EXT_SIGN,
+                     tcg_gen_mul_tl, tcg_gen_mul_tl, gen_muld_i128);
+}
+
+static void gen_divd_i128(TCGv rdl, TCGv rdh,
+                          TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_div(rdl, rs1l, rs2l);
+}
+
+static bool trans_divd(DisasContext *ctx, arg_divd *a)
+{
+    REQUIRE_128BIT(ctx);
+    REQUIRE_EXT(ctx, RVM);
+    ctx->d = true;
+
+    return gen_arith(ctx, a, EXT_SIGN,
+                     gen_div, gen_div, gen_divd_i128);
+}
+
+static void gen_divud_i128(TCGv rdl, TCGv rdh,
+                           TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_divu(rdl, rs1l, rs2l);
+}
+
+static bool trans_divud(DisasContext *ctx, arg_divud *a)
+{
+    REQUIRE_128BIT(ctx);
+    REQUIRE_EXT(ctx, RVM);
+    ctx->d = true;
+
+    return gen_arith(ctx, a, EXT_ZERO,
+                     gen_divu, gen_divu, gen_divud_i128);
+}
+
+static void gen_remd_i128(TCGv rdl, TCGv rdh,
+                          TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_rem(rdl, rs1l, rs2l);
+}
+
+static bool trans_remd(DisasContext *ctx, arg_remd *a)
+{
+    REQUIRE_128BIT(ctx);
+    REQUIRE_EXT(ctx, RVM);
+    ctx->d = true;
+
+    return gen_arith(ctx, a, EXT_SIGN,
+                     gen_rem, gen_rem, gen_remd_i128);
+}
+
+static void gen_remud_i128(TCGv rdl, TCGv rdh,
+                           TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+    gen_remu(rdl, rs1l, rs2l);
+}
+
+static bool trans_remud(DisasContext *ctx, arg_remud *a)
+{
+    REQUIRE_128BIT(ctx);
+    REQUIRE_EXT(ctx, RVM);
+    ctx->d = true;
+
+    return gen_arith(ctx, a, EXT_ZERO,
+                     gen_remu, gen_remu, gen_remud_i128);
 }
-- 
2.33.0




reply via email to

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