Re: [PATCH v5 04/60] target/riscv: add vector configure instruction
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
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
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
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
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