[PATCH v3 11/13] target/riscv: change vext_get_vlmax() arguments

Daniel Henrique Barboza posted 13 patches 10 months ago
[PATCH v3 11/13] target/riscv: change vext_get_vlmax() arguments
Posted by Daniel Henrique Barboza 10 months ago
We'll re-use the logic froim vext_get_vlmax() in 2 other occurrences in
the next patch, but first we need to make it independent of both 'cpu'
and 'vtype'. To do that, add 'vlenb', 'vsew' and 'lmul' as parameters
instead.

Adapt the two existing callers. In cpu_get_tb_cpu_state(), rename 'sew'
to 'vsew' to be less ambiguous about what we're encoding into *pflags.

In HELPER(vsetvl) the following changes were made:

- add a 'vsew' var to store vsew. Use it in the shift to get 'sew';
- the existing 'lmul' var was renamed to 'vlmul';
- add a new 'lmul' var to store 'lmul' encoded like DisasContext:lmul.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/cpu.h           |  7 +++----
 target/riscv/cpu_helper.c    | 11 +++++++----
 target/riscv/vector_helper.c | 16 ++++++++++------
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3af61e0f94..9dcbc0649a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -688,11 +688,10 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
  *               = 256 >> 7
  *               = 2
  */
-static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
+static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
+                                      int8_t lmul)
 {
-    uint8_t vsew = FIELD_EX64(vtype, VTYPE, VSEW);
-    int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
-    uint32_t vlen = cpu->cfg.vlenb << 3;
+    uint32_t vlen = vlenb << 3;
 
     /*
      * We need to use 'vlen' instead of 'vlenb' to
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c7cc7eb423..8da9104da4 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -81,13 +81,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
          * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
          * only when maxsz >= 8 bytes.
          */
-        uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
-        uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
-        uint32_t maxsz = vlmax << sew;
+
+        /* lmul encoded as in DisasContext::lmul */
+        int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
+        uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
+        uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
+        uint32_t maxsz = vlmax << vsew;
         bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
                            (maxsz >= 8);
         flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
-        flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
+        flags = FIELD_DP32(flags, TB_FLAGS, SEW, vsew);
         flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
                            FIELD_EX64(env->vtype, VTYPE, VLMUL));
         flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b13be1541a..718a0c711a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -35,16 +35,18 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
 {
     int vlmax, vl;
     RISCVCPU *cpu = env_archcpu(env);
-    uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
-    uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
+    uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
+    uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
+    uint16_t sew = 8 << vsew;
     uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
     int xlen = riscv_cpu_xlen(env);
     bool vill = (s2 >> (xlen - 1)) & 0x1;
     target_ulong reserved = s2 &
                             MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
                                             xlen - 1 - R_VTYPE_RESERVED_SHIFT);
+    int8_t lmul;
 
-    if (lmul & 4) {
+    if (vlmul & 4) {
         /*
          * Fractional LMUL, check:
          *
@@ -53,8 +55,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
          * (vlenb << 3) >> (8 - lmul) >= sew
          * vlenb >> (8 - 3 - lmul) >= sew
          */
-        if (lmul == 4 ||
-            cpu->cfg.vlenb >> (8 - 3 - lmul) < sew) {
+        if (vlmul == 4 ||
+            cpu->cfg.vlenb >> (8 - 3 - vlmul) < sew) {
             vill = true;
         }
     }
@@ -68,7 +70,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
         return 0;
     }
 
-    vlmax = vext_get_vlmax(cpu, s2);
+    /* lmul encoded as in DisasContext::lmul */
+    lmul = sextract32(FIELD_EX64(s2, VTYPE, VLMUL), 0, 3);
+    vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
     if (s1 <= vlmax) {
         vl = s1;
     } else {
-- 
2.43.0
Re: [PATCH v3 11/13] target/riscv: change vext_get_vlmax() arguments
Posted by Alistair Francis 9 months, 3 weeks ago
On Wed, Jan 17, 2024 at 7:02 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> We'll re-use the logic froim vext_get_vlmax() in 2 other occurrences in
> the next patch, but first we need to make it independent of both 'cpu'
> and 'vtype'. To do that, add 'vlenb', 'vsew' and 'lmul' as parameters
> instead.
>
> Adapt the two existing callers. In cpu_get_tb_cpu_state(), rename 'sew'
> to 'vsew' to be less ambiguous about what we're encoding into *pflags.
>
> In HELPER(vsetvl) the following changes were made:
>
> - add a 'vsew' var to store vsew. Use it in the shift to get 'sew';
> - the existing 'lmul' var was renamed to 'vlmul';
> - add a new 'lmul' var to store 'lmul' encoded like DisasContext:lmul.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/cpu.h           |  7 +++----
>  target/riscv/cpu_helper.c    | 11 +++++++----
>  target/riscv/vector_helper.c | 16 ++++++++++------
>  3 files changed, 20 insertions(+), 14 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3af61e0f94..9dcbc0649a 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -688,11 +688,10 @@ static inline RISCVMXL riscv_cpu_sxl(CPURISCVState *env)
>   *               = 256 >> 7
>   *               = 2
>   */
> -static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
> +static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
> +                                      int8_t lmul)
>  {
> -    uint8_t vsew = FIELD_EX64(vtype, VTYPE, VSEW);
> -    int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
> -    uint32_t vlen = cpu->cfg.vlenb << 3;
> +    uint32_t vlen = vlenb << 3;
>
>      /*
>       * We need to use 'vlen' instead of 'vlenb' to
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index c7cc7eb423..8da9104da4 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -81,13 +81,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
>           * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
>           * only when maxsz >= 8 bytes.
>           */
> -        uint32_t vlmax = vext_get_vlmax(cpu, env->vtype);
> -        uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> -        uint32_t maxsz = vlmax << sew;
> +
> +        /* lmul encoded as in DisasContext::lmul */
> +        int8_t lmul = sextract32(FIELD_EX64(env->vtype, VTYPE, VLMUL), 0, 3);
> +        uint32_t vsew = FIELD_EX64(env->vtype, VTYPE, VSEW);
> +        uint32_t vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
> +        uint32_t maxsz = vlmax << vsew;
>          bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
>                             (maxsz >= 8);
>          flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
> -        flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
> +        flags = FIELD_DP32(flags, TB_FLAGS, SEW, vsew);
>          flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
>                             FIELD_EX64(env->vtype, VTYPE, VLMUL));
>          flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index b13be1541a..718a0c711a 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -35,16 +35,18 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>  {
>      int vlmax, vl;
>      RISCVCPU *cpu = env_archcpu(env);
> -    uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
> -    uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
> +    uint64_t vlmul = FIELD_EX64(s2, VTYPE, VLMUL);
> +    uint8_t vsew = FIELD_EX64(s2, VTYPE, VSEW);
> +    uint16_t sew = 8 << vsew;
>      uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
>      int xlen = riscv_cpu_xlen(env);
>      bool vill = (s2 >> (xlen - 1)) & 0x1;
>      target_ulong reserved = s2 &
>                              MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
>                                              xlen - 1 - R_VTYPE_RESERVED_SHIFT);
> +    int8_t lmul;
>
> -    if (lmul & 4) {
> +    if (vlmul & 4) {
>          /*
>           * Fractional LMUL, check:
>           *
> @@ -53,8 +55,8 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>           * (vlenb << 3) >> (8 - lmul) >= sew
>           * vlenb >> (8 - 3 - lmul) >= sew
>           */
> -        if (lmul == 4 ||
> -            cpu->cfg.vlenb >> (8 - 3 - lmul) < sew) {
> +        if (vlmul == 4 ||
> +            cpu->cfg.vlenb >> (8 - 3 - vlmul) < sew) {
>              vill = true;
>          }
>      }
> @@ -68,7 +70,9 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
>          return 0;
>      }
>
> -    vlmax = vext_get_vlmax(cpu, s2);
> +    /* lmul encoded as in DisasContext::lmul */
> +    lmul = sextract32(FIELD_EX64(s2, VTYPE, VLMUL), 0, 3);
> +    vlmax = vext_get_vlmax(cpu->cfg.vlenb, vsew, lmul);
>      if (s1 <= vlmax) {
>          vl = s1;
>      } else {
> --
> 2.43.0
>
>