Re: [PATCH v5 04/60] target/riscv: add vector configure instruction

2020-03-13 Thread Richard Henderson
On 3/12/20 7:58 AM, LIU Zhiwei wrote:
> +static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl * a)
> +{
> +TCGv s1, s2, dst;
> +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(s2, a->rs2);
> +gen_helper_vsetvl(dst, cpu_env, s1, s2);
> +gen_set_gpr(a->rd, dst);
> +tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
> +exit_tb(ctx);

You can use lookup_and_goto_ptr here.  But either way,
Reviewed-by: Richard Henderson 


r~




Re: [PATCH v5 04/60] target/riscv: add vector configure instruction

2020-03-12 Thread Alistair Francis
On Thu, Mar 12, 2020 at 3:00 PM LIU Zhiwei  wrote:
>
>
>
> On 2020/3/13 5:23, Alistair Francis wrote:
> > On Thu, Mar 12, 2020 at 8:07 AM LIU Zhiwei  wrote:
> >> vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
> >> should update after configure instructions. The (ill, lmul, sew ) of vtype
> >> and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.
> >>
> >> Signed-off-by: LIU Zhiwei 
> >> ---
> >>   target/riscv/Makefile.objs  |  2 +-
> >>   target/riscv/cpu.h  | 63 ++
> >>   target/riscv/helper.h   |  2 +
> >>   target/riscv/insn32.decode  |  5 ++
> >>   target/riscv/insn_trans/trans_rvv.inc.c | 69 +
> >>   target/riscv/translate.c| 17 +-
> >>   target/riscv/vector_helper.c| 53 +++
> >>   7 files changed, 199 insertions(+), 12 deletions(-)
> >>   create mode 100644 target/riscv/insn_trans/trans_rvv.inc.c
> >>   create mode 100644 target/riscv/vector_helper.c
> >>

...

> >> +gen_get_gpr(s2, a->rs2);
> >> +gen_helper_vsetvl(dst, cpu_env, s1, s2);
> >> +gen_set_gpr(a->rd, dst);
> >> +tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
> >> +exit_tb(ctx);
> > Why does this
> As the vsetvl will change vtype, the tb flags of the instructions next
> to the vsetvl
> will change(some tb flags  are from vtype, like LMUL).
> >
> >> +ctx->base.is_jmp = DISAS_NORETURN;
> >> +
> >> +tcg_temp_free(s1);
> >> +tcg_temp_free(s2);
> >> +tcg_temp_free(dst);
> >> +return true;
> >> +}
> >> +
> >> +static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli * a)
> >> +{
> >> +TCGv s1, s2, dst;
> >> +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_set_gpr(a->rd, dst);
> >> +gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
> > Need to be different to this?
> Although vsetvli will also change vtype, the vtype will be a constant.
> So the tb flags of  the instruction(A) next to
> it will always be same with the tb flags at first translation of A.
> That's why gen_goto_tb is enough.

Ah ok. Makes sense.

Once you fix the one nit pick I had you can add my reviewed by:

Reviewed-by: Alistair Francis 

Alistair

>
> Zhiwei



Re: [PATCH v5 04/60] target/riscv: add vector configure instruction

2020-03-12 Thread LIU Zhiwei




On 2020/3/13 5:23, Alistair Francis wrote:

On Thu, Mar 12, 2020 at 8:07 AM LIU Zhiwei  wrote:

vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
should update after configure instructions. The (ill, lmul, sew ) of vtype
and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.

Signed-off-by: LIU Zhiwei 
---
  target/riscv/Makefile.objs  |  2 +-
  target/riscv/cpu.h  | 63 ++
  target/riscv/helper.h   |  2 +
  target/riscv/insn32.decode  |  5 ++
  target/riscv/insn_trans/trans_rvv.inc.c | 69 +
  target/riscv/translate.c| 17 +-
  target/riscv/vector_helper.c| 53 +++
  7 files changed, 199 insertions(+), 12 deletions(-)
  create mode 100644 target/riscv/insn_trans/trans_rvv.inc.c
  create mode 100644 target/riscv/vector_helper.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ff651f69f6..ff38df6219 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
vector_helper.o gdbstub.o
  obj-$(CONFIG_SOFTMMU) += pmp.o

  ifeq ($(CONFIG_SOFTMMU),y)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 603715f849..505d1a8515 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -21,6 +21,7 @@
  #define RISCV_CPU_H

  #include "hw/core/cpu.h"
+#include "hw/registerfields.h"
  #include "exec/cpu-defs.h"
  #include "fpu/softfloat-types.h"

@@ -99,6 +100,12 @@ typedef struct CPURISCVState CPURISCVState;

  #define RV_VLEN_MAX 512

+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, VILL, sizeof(target_ulong) * 8 - 2, 1)
+
  struct CPURISCVState {
  target_ulong gpr[32];
  uint64_t fpr[32]; /* assume both F and D extensions */
@@ -358,19 +365,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, 
target_ulong);
  #define TB_FLAGS_MMU_MASK   3
  #define TB_FLAGS_MSTATUS_FS MSTATUS_FS

+typedef CPURISCVState CPUArchState;
+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)
+
+/*
+ * A simplification for VLMAX
+ * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
+ * = (VLEN << LMUL) / (8 << SEW)
+ * = (VLEN << LMUL) >> (SEW + 3)
+ * = VLEN >> (SEW + 3 - LMUL)
+ */
+static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
+{
+uint8_t sew, lmul;
+
+sew = FIELD_EX64(vtype, VTYPE, VSEW);
+lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
+return cpu->cfg.vlen >> (sew + 3 - lmul);
+}
+
  static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
-target_ulong *cs_base, uint32_t *flags)
+target_ulong *cs_base, uint32_t 
*pflags)
  {
+uint32_t flags = 0;
+
  *pc = env->pc;
  *cs_base = 0;
+
+if (env->misa & RVV) {

Can you use: riscv_has_ext(env, RVV) instead?

Yes. It will be clearer.



+uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
+bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
+flags = FIELD_DP32(flags, TB_FLAGS, VILL,
+FIELD_EX64(env->vtype, VTYPE, VILL));
+flags = FIELD_DP32(flags, TB_FLAGS, SEW,
+FIELD_EX64(env->vtype, VTYPE, 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);
+} else {
+flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
+}
+
  #ifdef CONFIG_USER_ONLY
-*flags = TB_FLAGS_MSTATUS_FS;
+flags |= TB_FLAGS_MSTATUS_FS;
  #else
-*flags = cpu_mmu_index(env, 0);
+flags |= cpu_mmu_index(env, 0);
  if (riscv_cpu_fp_enabled(env)) {
-*flags |= env->mstatus & MSTATUS_FS;
+flags |= env->mstatus & MSTATUS_FS;
  }
  #endif
+*pflags = flags;
  }

  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
@@ -411,9 +461,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations 
*ops);

  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);

-typedef CPURISCVState CPUArchState;
-typedef RISCVCPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
  #endif /* RISCV_CPU_H */
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index debb22a480..3c28c7e407 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -76,3 +76,5 @@ DEF_HELPER_2(mret, tl, env, tl)
  DEF_HELPER_1(wfi, void, env)
  DEF_HELPER_1(tlb_flush, void, env)
  #endif
+/* Vector functions */
+DEF_HELPER_3(vsetvl, tl, env, tl, tl)
diff --git a/target/riscv/insn32.decode 

Re: [PATCH v5 04/60] target/riscv: add vector configure instruction

2020-03-12 Thread Alistair Francis
On Thu, Mar 12, 2020 at 8:07 AM LIU Zhiwei  wrote:
>
> vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
> should update after configure instructions. The (ill, lmul, sew ) of vtype
> and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.
>
> Signed-off-by: LIU Zhiwei 
> ---
>  target/riscv/Makefile.objs  |  2 +-
>  target/riscv/cpu.h  | 63 ++
>  target/riscv/helper.h   |  2 +
>  target/riscv/insn32.decode  |  5 ++
>  target/riscv/insn_trans/trans_rvv.inc.c | 69 +
>  target/riscv/translate.c| 17 +-
>  target/riscv/vector_helper.c| 53 +++
>  7 files changed, 199 insertions(+), 12 deletions(-)
>  create mode 100644 target/riscv/insn_trans/trans_rvv.inc.c
>  create mode 100644 target/riscv/vector_helper.c
>
> diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
> index ff651f69f6..ff38df6219 100644
> --- a/target/riscv/Makefile.objs
> +++ b/target/riscv/Makefile.objs
> @@ -1,4 +1,4 @@
> -obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
> gdbstub.o
> +obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
> vector_helper.o gdbstub.o
>  obj-$(CONFIG_SOFTMMU) += pmp.o
>
>  ifeq ($(CONFIG_SOFTMMU),y)
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 603715f849..505d1a8515 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -21,6 +21,7 @@
>  #define RISCV_CPU_H
>
>  #include "hw/core/cpu.h"
> +#include "hw/registerfields.h"
>  #include "exec/cpu-defs.h"
>  #include "fpu/softfloat-types.h"
>
> @@ -99,6 +100,12 @@ typedef struct CPURISCVState CPURISCVState;
>
>  #define RV_VLEN_MAX 512
>
> +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, VILL, sizeof(target_ulong) * 8 - 2, 1)
> +
>  struct CPURISCVState {
>  target_ulong gpr[32];
>  uint64_t fpr[32]; /* assume both F and D extensions */
> @@ -358,19 +365,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, 
> target_ulong);
>  #define TB_FLAGS_MMU_MASK   3
>  #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
>
> +typedef CPURISCVState CPUArchState;
> +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)
> +
> +/*
> + * A simplification for VLMAX
> + * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
> + * = (VLEN << LMUL) / (8 << SEW)
> + * = (VLEN << LMUL) >> (SEW + 3)
> + * = VLEN >> (SEW + 3 - LMUL)
> + */
> +static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
> +{
> +uint8_t sew, lmul;
> +
> +sew = FIELD_EX64(vtype, VTYPE, VSEW);
> +lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
> +return cpu->cfg.vlen >> (sew + 3 - lmul);
> +}
> +
>  static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
> -target_ulong *cs_base, uint32_t 
> *flags)
> +target_ulong *cs_base, uint32_t 
> *pflags)
>  {
> +uint32_t flags = 0;
> +
>  *pc = env->pc;
>  *cs_base = 0;
> +
> +if (env->misa & RVV) {

Can you use: riscv_has_ext(env, RVV) instead?

> +uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
> +bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
> +flags = FIELD_DP32(flags, TB_FLAGS, VILL,
> +FIELD_EX64(env->vtype, VTYPE, VILL));
> +flags = FIELD_DP32(flags, TB_FLAGS, SEW,
> +FIELD_EX64(env->vtype, VTYPE, 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);
> +} else {
> +flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
> +}
> +
>  #ifdef CONFIG_USER_ONLY
> -*flags = TB_FLAGS_MSTATUS_FS;
> +flags |= TB_FLAGS_MSTATUS_FS;
>  #else
> -*flags = cpu_mmu_index(env, 0);
> +flags |= cpu_mmu_index(env, 0);
>  if (riscv_cpu_fp_enabled(env)) {
> -*flags |= env->mstatus & MSTATUS_FS;
> +flags |= env->mstatus & MSTATUS_FS;
>  }
>  #endif
> +*pflags = flags;
>  }
>
>  int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
> @@ -411,9 +461,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations 
> *ops);
>
>  void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
> -typedef CPURISCVState CPUArchState;
> -typedef RISCVCPU ArchCPU;
> -
> -#include "exec/cpu-all.h"
> -
>  #endif /* RISCV_CPU_H */
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index debb22a480..3c28c7e407 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -76,3 +76,5 @@ DEF_HELPER_2(mret, tl, env, tl)
>  DEF_HELPER_1(wfi, void, 

[PATCH v5 04/60] target/riscv: add vector configure instruction

2020-03-12 Thread LIU Zhiwei
vsetvl and vsetvli are two configure instructions for vl, vtype. TB flags
should update after configure instructions. The (ill, lmul, sew ) of vtype
and the bit of (VSTART == 0 && VL == VLMAX) will be placed within tb_flags.

Signed-off-by: LIU Zhiwei 
---
 target/riscv/Makefile.objs  |  2 +-
 target/riscv/cpu.h  | 63 ++
 target/riscv/helper.h   |  2 +
 target/riscv/insn32.decode  |  5 ++
 target/riscv/insn_trans/trans_rvv.inc.c | 69 +
 target/riscv/translate.c| 17 +-
 target/riscv/vector_helper.c| 53 +++
 7 files changed, 199 insertions(+), 12 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvv.inc.c
 create mode 100644 target/riscv/vector_helper.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index ff651f69f6..ff38df6219 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
vector_helper.o gdbstub.o
 obj-$(CONFIG_SOFTMMU) += pmp.o
 
 ifeq ($(CONFIG_SOFTMMU),y)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 603715f849..505d1a8515 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -21,6 +21,7 @@
 #define RISCV_CPU_H
 
 #include "hw/core/cpu.h"
+#include "hw/registerfields.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
 
@@ -99,6 +100,12 @@ typedef struct CPURISCVState CPURISCVState;
 
 #define RV_VLEN_MAX 512
 
+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, VILL, sizeof(target_ulong) * 8 - 2, 1)
+
 struct CPURISCVState {
 target_ulong gpr[32];
 uint64_t fpr[32]; /* assume both F and D extensions */
@@ -358,19 +365,62 @@ void riscv_cpu_set_fflags(CPURISCVState *env, 
target_ulong);
 #define TB_FLAGS_MMU_MASK   3
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
 
+typedef CPURISCVState CPUArchState;
+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)
+
+/*
+ * A simplification for VLMAX
+ * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
+ * = (VLEN << LMUL) / (8 << SEW)
+ * = (VLEN << LMUL) >> (SEW + 3)
+ * = VLEN >> (SEW + 3 - LMUL)
+ */
+static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
+{
+uint8_t sew, lmul;
+
+sew = FIELD_EX64(vtype, VTYPE, VSEW);
+lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
+return cpu->cfg.vlen >> (sew + 3 - lmul);
+}
+
 static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
-target_ulong *cs_base, uint32_t *flags)
+target_ulong *cs_base, uint32_t 
*pflags)
 {
+uint32_t flags = 0;
+
 *pc = env->pc;
 *cs_base = 0;
+
+if (env->misa & RVV) {
+uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
+bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
+flags = FIELD_DP32(flags, TB_FLAGS, VILL,
+FIELD_EX64(env->vtype, VTYPE, VILL));
+flags = FIELD_DP32(flags, TB_FLAGS, SEW,
+FIELD_EX64(env->vtype, VTYPE, 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);
+} else {
+flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
+}
+
 #ifdef CONFIG_USER_ONLY
-*flags = TB_FLAGS_MSTATUS_FS;
+flags |= TB_FLAGS_MSTATUS_FS;
 #else
-*flags = cpu_mmu_index(env, 0);
+flags |= cpu_mmu_index(env, 0);
 if (riscv_cpu_fp_enabled(env)) {
-*flags |= env->mstatus & MSTATUS_FS;
+flags |= env->mstatus & MSTATUS_FS;
 }
 #endif
+*pflags = flags;
 }
 
 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
@@ -411,9 +461,4 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations 
*ops);
 
 void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 
-typedef CPURISCVState CPUArchState;
-typedef RISCVCPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index debb22a480..3c28c7e407 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -76,3 +76,5 @@ DEF_HELPER_2(mret, tl, env, tl)
 DEF_HELPER_1(wfi, void, env)
 DEF_HELPER_1(tlb_flush, void, env)
 #endif
+/* Vector functions */
+DEF_HELPER_3(vsetvl, tl, env, tl, tl)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b883672e63..53340bdbc4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -62,6 +62,7 @@
 @r_rm...   . . ... . ... %rs2 %rs1