diff mbox series

[RFC,13/65] target/riscv: rvv-0.9: configure instructions

Message ID 20200710104920.13550-14-frank.chang@sifive.com (mailing list archive)
State New, archived
Headers show
Series target/riscv: support vector extension v0.9 | expand

Commit Message

Frank Chang July 10, 2020, 10:48 a.m. UTC
From: Frank Chang <frank.chang@sifive.com>

Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
 target/riscv/helper.h                   |  2 +-
 target/riscv/insn_trans/trans_rvv.inc.c | 52 ++++++++++++-------------
 target/riscv/vector_helper.c            | 38 ++++++++++++------
 3 files changed, 53 insertions(+), 39 deletions(-)

Comments

Richard Henderson July 10, 2020, 6:06 p.m. UTC | #1
On 7/10/20 3:48 AM, frank.chang@sifive.com wrote:
> -static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
> +static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)

Do not mix this change with anything else.

> +    rd = tcg_const_i32(a->rd);
> +    rs1 = tcg_const_i32(a->rs1);

Any time you put a register number into a tcg const, there's probably a better
way to do things.

> -    /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
> -    if (a->rs1 == 0) {
> -        /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> -        s1 = tcg_const_tl(RV_VLEN_MAX);
> -    } else {
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> -    }

E.g. this code should be kept, and add

    if (a->rd == 0 && a->rs1 == 0) {
        s1 = tcg_temp_new();
        tcg_gen_mov_tl(s1, cpu_vl);
    } else ...


> +    if ((sew > cpu->cfg.elen)
> +        || vill
> +        || vflmul < ((float)sew / cpu->cfg.elen)
> +        || (ediv != 0)
> +        || (reserved != 0)) {
>          /* only set vill bit. */
>          env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
> -        env->vl = 0;
> -        env->vstart = 0;
>          return 0;
>      }

You do need to check 0.7.1 so long as it's supported.


r~
Frank Chang July 13, 2020, 2:07 a.m. UTC | #2
On Sat, Jul 11, 2020 at 2:07 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 7/10/20 3:48 AM, frank.chang@sifive.com wrote:
> > -static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
> > +static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
>
> Do not mix this change with anything else.


OK~
---
Frank Chang


> > +    rd = tcg_const_i32(a->rd);
> > +    rs1 = tcg_const_i32(a->rs1);
>
> Any time you put a register number into a tcg const, there's probably a
> better
> way to do things.


> > -    /* Using x0 as the rs1 register specifier, encodes an infinite AVL
> */
> > -    if (a->rs1 == 0) {
> > -        /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> > -        s1 = tcg_const_tl(RV_VLEN_MAX);
> > -    } else {
> > -        s1 = tcg_temp_new();
> > -        gen_get_gpr(s1, a->rs1);
> > -    }
>
> E.g. this code should be kept, and add
>
>     if (a->rd == 0 && a->rs1 == 0) {
>         s1 = tcg_temp_new();
>         tcg_gen_mov_tl(s1, cpu_vl);
>     } else ...
>
OK~

>
> > +    if ((sew > cpu->cfg.elen)
> > +        || vill
> > +        || vflmul < ((float)sew / cpu->cfg.elen)
> > +        || (ediv != 0)
> > +        || (reserved != 0)) {
> >          /* only set vill bit. */
> >          env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
> > -        env->vl = 0;
> > -        env->vstart = 0;
> >          return 0;
> >      }
>
> You do need to check 0.7.1 so long as it's supported.
>
>
> r~
>

Will drop 0.7.1 support in my first patch to prevent the confusion.

Frank Chang
diff mbox series

Patch

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index acc298219d..5939897a82 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -83,7 +83,7 @@  DEF_HELPER_1(hyp_tlb_flush, void, env)
 #endif
 
 /* Vector functions */
-DEF_HELPER_3(vsetvl, tl, env, tl, tl)
+DEF_HELPER_5(vsetvl, tl, env, i32, i32, tl, tl)
 DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
index fc1908389e..da8e7598e9 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -72,33 +72,32 @@  static inline bool is_overlapped_widen(const int astart, int asize,
     }
 }
 
-static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
+static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
 {
+    TCGv_i32 rd, rs1;
     TCGv s1, s2, dst;
 
     REQUIRE_RVV;
-    if (!has_ext(ctx, RVV)) {
+    if (!has_ext(s, RVV)) {
         return false;
     }
 
+    rd = tcg_const_i32(a->rd);
+    rs1 = tcg_const_i32(a->rs1);
+    s1 = tcg_temp_new();
     s2 = tcg_temp_new();
     dst = tcg_temp_new();
 
-    /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-    if (a->rs1 == 0) {
-        /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
-    } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
-    }
+    gen_get_gpr(s1, a->rs1);
     gen_get_gpr(s2, a->rs2);
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_helper_vsetvl(dst, cpu_env, rd, rs1, s1, s2);
     gen_set_gpr(a->rd, dst);
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-    lookup_and_goto_ptr(ctx);
-    ctx->base.is_jmp = DISAS_NORETURN;
+    tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+    lookup_and_goto_ptr(s);
+    s->base.is_jmp = DISAS_NORETURN;
 
+    tcg_temp_free_i32(rd);
+    tcg_temp_free_i32(rs1);
     tcg_temp_free(s1);
     tcg_temp_free(s2);
     tcg_temp_free(dst);
@@ -106,31 +105,30 @@  static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
     return true;
 }
 
-static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
+static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a)
 {
+    TCGv_i32 rd, rs1;
     TCGv s1, s2, dst;
 
     REQUIRE_RVV;
-    if (!has_ext(ctx, RVV)) {
+    if (!has_ext(s, RVV)) {
         return false;
     }
 
+    rd = tcg_const_i32(a->rd);
+    rs1 = tcg_const_i32(a->rs1);
+    s1 = tcg_temp_new();
     s2 = tcg_const_tl(a->zimm);
     dst = tcg_temp_new();
 
-    /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-    if (a->rs1 == 0) {
-        /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
-    } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
-    }
-    gen_helper_vsetvl(dst, cpu_env, s1, s2);
+    gen_get_gpr(s1, a->rs1);
+    gen_helper_vsetvl(dst, cpu_env, rd, rs1, s1, s2);
     gen_set_gpr(a->rd, dst);
-    gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
-    ctx->base.is_jmp = DISAS_NORETURN;
+    gen_goto_tb(s, 0, s->pc_succ_insn);
+    s->base.is_jmp = DISAS_NORETURN;
 
+    tcg_temp_free_i32(rd);
+    tcg_temp_free_i32(rs1);
     tcg_temp_free(s1);
     tcg_temp_free(s2);
     tcg_temp_free(dst);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index db54288c08..1279ef4fb1 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -26,33 +26,49 @@ 
 #include "internals.h"
 #include <math.h>
 
-target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
-                            target_ulong s2)
+target_ulong HELPER(vsetvl)(CPURISCVState *env, uint32_t rd, uint32_t rs1,
+                            target_ulong s1, target_ulong s2)
 {
-    int vlmax, vl;
+    int vlmax;
+    int vl = 0;
+
     RISCVCPU *cpu = env_archcpu(env);
     uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
     uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
     bool vill = FIELD_EX64(s2, VTYPE, VILL);
+    vlmax = vext_get_vlmax(cpu, s2);
     target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
 
-    if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+    uint64_t lmul = (FIELD_EX64(s2, VTYPE, VFLMUL) << 2)
+        | FIELD_EX64(s2, VTYPE, VLMUL);
+    float vflmul = flmul_table[lmul];
+
+    if ((sew > cpu->cfg.elen)
+        || vill
+        || vflmul < ((float)sew / cpu->cfg.elen)
+        || (ediv != 0)
+        || (reserved != 0)) {
         /* only set vill bit. */
         env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
-        env->vl = 0;
-        env->vstart = 0;
         return 0;
     }
 
-    vlmax = vext_get_vlmax(cpu, s2);
-    if (s1 <= vlmax) {
-        vl = s1;
-    } else {
+    /* set vl */
+    if (rd == 0 && rs1 == 0) {
+        /* keep existing vl */
+        vl = env->vl > vlmax ? vlmax : env->vl;
+    } else if (rd != 0 && rs1 == 0) {
+        /* set vl to vlmax */
         vl = vlmax;
+    } else if (rs1 != 0) {
+        /* normal stripmining */
+        vl = s1 > vlmax ? vlmax : s1;
     }
-    env->vl = vl;
+
     env->vtype = s2;
     env->vstart = 0;
+    env->vl = vl;
+
     return vl;
 }