diff mbox series

[RFC,v3,12/71] target/riscv: rvv-1.0: add fractional LMUL

Message ID 20200806104709.13235-13-frank.chang@sifive.com (mailing list archive)
State New, archived
Headers show
Series target/riscv: support vector extension v1.0 | expand

Commit Message

Frank Chang Aug. 6, 2020, 10:46 a.m. UTC
From: Frank Chang <frank.chang@sifive.com>

Introduce the concepts of fractional LMUL for RVV 1.0.
In RVV 1.0, LMUL bits are contiguous in vtype register.

Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
 target/riscv/cpu.h                      | 15 ++++++++-------
 target/riscv/insn_trans/trans_rvv.inc.c |  9 ++++++---
 target/riscv/translate.c                |  3 +++
 target/riscv/vector_helper.c            | 17 +++++++++++++++--
 4 files changed, 32 insertions(+), 12 deletions(-)

Comments

Richard Henderson Aug. 6, 2020, 6:36 p.m. UTC | #1
On 8/6/20 3:46 AM, frank.chang@sifive.com wrote:
> +    float flmul;

int8_t?  It seems weird that the translator wouldn't also use...

> +/*
> + * Encode LMUL to lmul as following:
> + *     LMUL    vlmul    lmul
> + *      1       000       0
> + *      2       001       1
> + *      4       010       2
> + *      8       011       3
> + *      -       100       -
> + *     1/8      101      -3
> + *     1/4      110      -2
> + *     1/2      111      -1
> + */
> +static inline int32_t vext_lmul(uint32_t desc)
>  {
> -    return FIELD_EX32(simd_data(desc), VDATA, LMUL);
> +    uint32_t lmul = FIELD_EX32(simd_data(desc), VDATA, LMUL);
> +    return (int8_t)(lmul << 5) >> 5;
>  }

... this encoding?

Oh, and sextract32(lmul, 0, 3) instead of those shifts.


r~
Frank Chang Aug. 14, 2020, 3:12 a.m. UTC | #2
On Fri, Aug 7, 2020 at 2:36 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 8/6/20 3:46 AM, frank.chang@sifive.com wrote:
> > +    float flmul;
>
> int8_t?  It seems weird that the translator wouldn't also use...
>

It was kept for vector check functions.
However, I've removed float flmul and changed my
vector check functions to something like:

> static bool vext_check_sss(DisasContext *s, int vd, int vs1,
>                            int vs2, int vm, bool is_vs1)
> {
>     bool ret = require_vm(vm, vd);
>     if (s->lmul > 0) {
>         ret &= require_align(vd, 1 << s->lmul) &&
>                require_align(vs2, 1 << s->lmul);
>         if (is_vs1) {
>             ret &= require_align(vs1, 1 << s->lmul);
>         }
>     }
>     return ret;
> }

which use shifts to check the alignment/noover of vector registers.

The parameters passed to require_align() and require_noover()
are also changed to const uint8_t type so that the shifted value can be
wrapped within 8-bits.

int8_t lmul in DisasContext is also encoded:
ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);


> > +/*
> > + * Encode LMUL to lmul as following:
> > + *     LMUL    vlmul    lmul
> > + *      1       000       0
> > + *      2       001       1
> > + *      4       010       2
> > + *      8       011       3
> > + *      -       100       -
> > + *     1/8      101      -3
> > + *     1/4      110      -2
> > + *     1/2      111      -1
> > + */
> > +static inline int32_t vext_lmul(uint32_t desc)
> >  {
> > -    return FIELD_EX32(simd_data(desc), VDATA, LMUL);
> > +    uint32_t lmul = FIELD_EX32(simd_data(desc), VDATA, LMUL);
> > +    return (int8_t)(lmul << 5) >> 5;
> >  }
>
> ... this encoding?
>
> Oh, and sextract32(lmul, 0, 3) instead of those shifts.
>

OK~


>
>
> r~
>

Thanks
Frank Chang
diff mbox series

Patch

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 08d2c10a024..d0f9a76ca01 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -94,10 +94,10 @@  typedef struct CPURISCVState CPURISCVState;
 
 #define RV_VLEN_MAX 256
 
-FIELD(VTYPE, VLMUL, 0, 2)
-FIELD(VTYPE, VSEW, 2, 3)
-FIELD(VTYPE, VEDIV, 5, 2)
-FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
+FIELD(VTYPE, VLMUL, 0, 3)
+FIELD(VTYPE, VSEW, 3, 3)
+FIELD(VTYPE, VEDIV, 8, 2)
+FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
@@ -368,9 +368,10 @@  typedef RISCVCPU ArchCPU;
 #include "exec/cpu-all.h"
 
 FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
-FIELD(TB_FLAGS, LMUL, 3, 2)
-FIELD(TB_FLAGS, SEW, 5, 3)
-FIELD(TB_FLAGS, VILL, 8, 1)
+FIELD(TB_FLAGS, LMUL, 3, 3)
+FIELD(TB_FLAGS, SEW, 6, 3)
+/* Skip MSTATUS_VS (0x600) fields */
+FIELD(TB_FLAGS, VILL, 11, 1)
 
 /*
  * A simplification for VLMAX
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
index b529474403e..75aab0a50f9 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -1653,7 +1653,8 @@  static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
                              vreg_ofs(s, a->rs1),
                              MAXSZ(s), MAXSZ(s));
         } else {
-            uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+            uint32_t data = 0;
+            data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
             static gen_helper_gvec_2_ptr * const fns[4] = {
                 gen_helper_vmv_v_v_b, gen_helper_vmv_v_v_h,
                 gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
@@ -1691,7 +1692,8 @@  static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             TCGv_i32 desc ;
             TCGv_i64 s1_i64 = tcg_temp_new_i64();
             TCGv_ptr dest = tcg_temp_new_ptr();
-            uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+            uint32_t data = 0;
+            data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
             static gen_helper_vmv_vx * const fns[4] = {
                 gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
                 gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
@@ -1729,7 +1731,8 @@  static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
             TCGv_i32 desc;
             TCGv_i64 s1;
             TCGv_ptr dest;
-            uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
+            uint32_t data = 0;
+            data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
             static gen_helper_vmv_vx * const fns[4] = {
                 gen_helper_vmv_v_x_b, gen_helper_vmv_v_x_h,
                 gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7b6088677d4..24026f901d1 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -60,6 +60,7 @@  typedef struct DisasContext {
     /* vector extension */
     bool vill;
     uint8_t lmul;
+    float flmul;
     uint8_t sew;
     uint16_t vlen;
     bool vl_eq_vlmax;
@@ -852,6 +853,8 @@  static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
     ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
     ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
+    ctx->flmul = (ctx->lmul < 4) ?
+                    (1 << ctx->lmul) : 1.0f / (1 << (8 - ctx->lmul));
     ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 }
 
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f42346cb9ca..4a4c18b8a96 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -86,9 +86,22 @@  static inline uint32_t vext_vm(uint32_t desc)
     return FIELD_EX32(simd_data(desc), VDATA, VM);
 }
 
-static inline uint32_t vext_lmul(uint32_t desc)
+/*
+ * Encode LMUL to lmul as following:
+ *     LMUL    vlmul    lmul
+ *      1       000       0
+ *      2       001       1
+ *      4       010       2
+ *      8       011       3
+ *      -       100       -
+ *     1/8      101      -3
+ *     1/4      110      -2
+ *     1/2      111      -1
+ */
+static inline int32_t vext_lmul(uint32_t desc)
 {
-    return FIELD_EX32(simd_data(desc), VDATA, LMUL);
+    uint32_t lmul = FIELD_EX32(simd_data(desc), VDATA, LMUL);
+    return (int8_t)(lmul << 5) >> 5;
 }
 
 static uint32_t vext_wd(uint32_t desc)