qemu-riscv
[Top][All Lists]
Advanced

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

[PATCH v2 17/27] target/riscv: 128-bit double word integer arithmetic in


From: Frédéric Pétrot
Subject: [PATCH v2 17/27] target/riscv: 128-bit double word integer arithmetic instructions
Date: Wed, 6 Oct 2021 23:28:23 +0200

The ISA adds the addid, addd and subd instructions that work on 64-bit
while in 128-bit mode. Similarly to what is done for insns working on
32-bit (w suffix), we set a 'd' flag so that masking and sign extension
occurs as it should when using the registers' accessors.

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              |  4 ++
 target/riscv/translate.c                | 12 ++++--
 target/riscv/insn_trans/trans_rvi.c.inc | 50 +++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 79611cb65d..eea540cea9 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -167,6 +167,10 @@ sraw     0100000 .....  ..... 101 ..... 0111011 @r
 ldu      ............   ..... 111 ..... 0000011 @i
 lq       ............   ..... 010 ..... 0001111 @i
 sq       ............   ..... 100 ..... 0100011 @s
+addid    ............  .....  000 ..... 1011011 @i
+addd     0000000 ..... .....  000 ..... 1111011 @r
+subd     0100000 ..... .....  000 ..... 1111011 @r
+
 # *** RV32M Standard Extension ***
 mul      0000001 .....  ..... 000 ..... 0110011 @r
 mulh     0000001 .....  ..... 001 ..... 0110011 @r
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index b3f70bcde0..120841de48 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -68,6 +68,7 @@ typedef struct DisasContext {
        to reset this known value.  */
     int frm;
     bool w;
+    bool d;
     bool virt_enabled;
     bool ext_ifencei;
     bool hlsx;
@@ -264,7 +265,7 @@ static inline TCGv cpu_gprh_check(DisasContext *ctx, int 
reg_num)
 
 static TCGv get_gprh(DisasContext *ctx, int reg_num)
 {
-    if (reg_num == 0 || ctx->w) {
+    if (reg_num == 0 || ctx->w || ctx->d) {
         return ctx->zero;
     }
     return cpu_gprh_check(ctx, reg_num);
@@ -300,7 +301,7 @@ static void gen_set_gpr(DisasContext *ctx, int reg_num, 
TCGv t)
 static void gen_set_gprh(DisasContext *ctx, int reg_num, TCGv t)
 {
     if (reg_num != 0) {
-        if (ctx->w) {
+        if (ctx->w || ctx->d) {
             tcg_gen_sari_tl(cpu_gprh_check(ctx, reg_num), cpu_gpr[reg_num], 
63);
         } else {
             tcg_gen_mov_tl(cpu_gprh_check(ctx, reg_num), t);
@@ -699,7 +700,10 @@ static bool gen_shift(DisasContext *ctx, arg_r *a, 
DisasExtend ext,
              desth = tcg_temp_new(),
              shamt = tcg_temp_new();
 
-        tcg_gen_andi_tl(shamt, src2l, !ctx->w << 5 | 0x1f);
+        tcg_gen_andi_tl(shamt, src2l,
+                        (!(ctx->d ^ ctx->w) << 6)
+                        | ((ctx->d | !ctx->w) << 5)
+                        | 0x1f);
         fn128(destl, desth, src1l, src1h, shamt);
 
         gen_set_gpr(ctx, a->rd, destl);
@@ -804,6 +808,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
     ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
     ctx->cs = cs;
     ctx->w = false;
+    ctx->d = false;
     ctx->ntemp = 0;
     memset(ctx->temp, 0, sizeof(ctx->temp));
 
@@ -830,6 +835,7 @@ static void riscv_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
     decode_opc(env, ctx, opcode16);
     ctx->base.pc_next = ctx->pc_succ_insn;
     ctx->w = false;
+    ctx->d = false;
 
     for (int i = ctx->ntemp - 1; i >= 0; --i) {
         tcg_temp_free(ctx->temp[i]);
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 1373fe94b9..05e13bbc1d 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -476,6 +476,56 @@ static bool trans_sq(DisasContext *ctx, arg_sq *a)
     return gen_store(ctx, a, MO_TEO);
 }
 
+static bool trans_addd(DisasContext *ctx, arg_addd *a)
+{
+    REQUIRE_128BIT(ctx);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE),
+         src2 = get_gpr(ctx, a->rs2, EXT_NONE),
+         destl = dest_gpr(ctx, a->rd),
+         desth = dest_gprh(ctx, a->rd);
+
+    ctx->d = true;
+    tcg_gen_add_tl(destl, src1, src2);
+
+    gen_set_gpr(ctx, a->rd, destl);
+    gen_set_gprh(ctx, a->rd, desth);
+
+    return true;
+}
+
+static bool trans_addid(DisasContext *ctx, arg_addid *a)
+{
+    REQUIRE_128BIT(ctx);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE),
+         destl = dest_gpr(ctx, a->rd),
+         desth = dest_gprh(ctx, a->rd);
+
+    ctx->d = true;
+    tcg_gen_addi_tl(destl, src1, a->imm);
+
+    gen_set_gpr(ctx, a->rd, destl);
+    gen_set_gprh(ctx, a->rd, desth);
+
+    return true;
+}
+
+static bool trans_subd(DisasContext *ctx, arg_subd *a)
+{
+    REQUIRE_128BIT(ctx);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE),
+         src2 = get_gpr(ctx, a->rs2, EXT_NONE),
+         destl = dest_gpr(ctx, a->rd),
+         desth = dest_gprh(ctx, a->rd);
+
+    ctx->d = true;
+    tcg_gen_sub_tl(destl, src1, src2);
+
+    gen_set_gpr(ctx, a->rd, destl);
+    gen_set_gprh(ctx, a->rd, desth);
+
+    return true;
+}
+
 static void gen_addi2_i128(TCGv retl, TCGv reth,
                            TCGv srcl, TCGv srch, target_long imm)
 {
-- 
2.33.0




reply via email to

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