Message ID | 20200317150653.9008-58-zhiwei_liu@c-sky.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | target/riscv: support vector extension v0.7.1 | expand |
On 3/17/20 8:06 AM, LIU Zhiwei wrote: > +/* Floating-Point Scalar Move Instructions */ > +static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) > +{ > + if (!s->vill && has_ext(s, RVF) && > + (s->mstatus_fs != 0) && (s->sew != 0)) { > +#ifdef HOST_WORDS_BIGENDIAN > + int ofs = vreg_ofs(s, a->rs2) + ((7 >> s->sew) << s->sew); > +#else > + int ofs = vreg_ofs(s, a->rs2); > +#endif Use endian_ofs from patch 55. > + switch (s->sew) { > + case MO_8: > + tcg_gen_ld8u_i64(cpu_fpr[a->rd], cpu_env, ofs); > + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], > + 0xffffffffffffff00ULL); > + break; MO_8 should be illegal. > + case MO_16: > + tcg_gen_ld16u_i64(cpu_fpr[a->rd], cpu_env, ofs); > + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], > + 0xffffffffffff0000ULL); > + break; > + case MO_32: > + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); > + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], > + 0xffffffff00000000ULL); > + break; > + default: > + if (has_ext(s, RVD)) { > + tcg_gen_ld_i64(cpu_fpr[a->rd], cpu_env, ofs); > + } else { > + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); > + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], > + 0xffffffff00000000ULL); > + } > + break; Maybe better with MO_64 and default: g_assert_not_reached(). > +static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) > +{ > + if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) { > + TCGv_ptr dest; > + TCGv_i64 src1; > + static gen_helper_vfmv_s_f * const fns[3] = { > + gen_helper_vfmv_s_f_h, > + gen_helper_vfmv_s_f_w, > + gen_helper_vfmv_s_f_d You shouldn't need to duplicate the vmv_s_x_* helpers. r~
On 2020/3/28 11:44, Richard Henderson wrote: > On 3/17/20 8:06 AM, LIU Zhiwei wrote: >> +/* Floating-Point Scalar Move Instructions */ >> +static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) >> +{ >> + if (!s->vill && has_ext(s, RVF) && >> + (s->mstatus_fs != 0) && (s->sew != 0)) { >> +#ifdef HOST_WORDS_BIGENDIAN >> + int ofs = vreg_ofs(s, a->rs2) + ((7 >> s->sew) << s->sew); >> +#else >> + int ofs = vreg_ofs(s, a->rs2); >> +#endif > Use endian_ofs from patch 55. Yes, I forgot it. > >> + switch (s->sew) { >> + case MO_8: >> + tcg_gen_ld8u_i64(cpu_fpr[a->rd], cpu_env, ofs); >> + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], >> + 0xffffffffffffff00ULL); >> + break; > MO_8 should be illegal. Yes, it has been checked in s->sew != 0. > >> + case MO_16: >> + tcg_gen_ld16u_i64(cpu_fpr[a->rd], cpu_env, ofs); >> + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], >> + 0xffffffffffff0000ULL); >> + break; >> + case MO_32: >> + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); >> + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], >> + 0xffffffff00000000ULL); >> + break; >> + default: >> + if (has_ext(s, RVD)) { >> + tcg_gen_ld_i64(cpu_fpr[a->rd], cpu_env, ofs); >> + } else { >> + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); >> + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], >> + 0xffffffff00000000ULL); >> + } >> + break; > Maybe better with MO_64 and default: g_assert_not_reached(). > >> +static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) >> +{ >> + if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) { >> + TCGv_ptr dest; >> + TCGv_i64 src1; >> + static gen_helper_vfmv_s_f * const fns[3] = { >> + gen_helper_vfmv_s_f_h, >> + gen_helper_vfmv_s_f_w, >> + gen_helper_vfmv_s_f_d > You shouldn't need to duplicate the vmv_s_x_* helpers. All these helpers will be away in v7. Zhiwei > > r~
diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 2e3bfdf1dc..044538aef9 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1114,3 +1114,7 @@ DEF_HELPER_3(vmv_s_x_b, void, ptr, tl, env) DEF_HELPER_3(vmv_s_x_h, void, ptr, tl, env) DEF_HELPER_3(vmv_s_x_w, void, ptr, tl, env) DEF_HELPER_3(vmv_s_x_d, void, ptr, tl, env) + +DEF_HELPER_3(vfmv_s_f_h, void, ptr, i64, env) +DEF_HELPER_3(vfmv_s_f_w, void, ptr, i64, env) +DEF_HELPER_3(vfmv_s_f_d, void, ptr, i64, env) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 0741a25540..79f9b37b29 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -563,6 +563,8 @@ viota_m 010110 . ..... 10000 010 ..... 1010111 @r2_vm vid_v 010110 . 00000 10001 010 ..... 1010111 @r1_vm vext_x_v 001100 1 ..... ..... 010 ..... 1010111 @r vmv_s_x 001101 1 00000 ..... 110 ..... 1010111 @r2 +vfmv_f_s 001100 1 ..... 00000 001 ..... 1010111 @r2rd +vfmv_s_f 001101 1 00000 ..... 101 ..... 1010111 @r2 vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm vsetvl 1000000 ..... ..... 111 ..... 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c index 4cf4e54d12..07033662c3 100644 --- a/target/riscv/insn_trans/trans_rvv.inc.c +++ b/target/riscv/insn_trans/trans_rvv.inc.c @@ -2464,3 +2464,75 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a) } return false; } + +/* Floating-Point Scalar Move Instructions */ +static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a) +{ + if (!s->vill && has_ext(s, RVF) && + (s->mstatus_fs != 0) && (s->sew != 0)) { +#ifdef HOST_WORDS_BIGENDIAN + int ofs = vreg_ofs(s, a->rs2) + ((7 >> s->sew) << s->sew); +#else + int ofs = vreg_ofs(s, a->rs2); +#endif + switch (s->sew) { + case MO_8: + tcg_gen_ld8u_i64(cpu_fpr[a->rd], cpu_env, ofs); + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], + 0xffffffffffffff00ULL); + break; + case MO_16: + tcg_gen_ld16u_i64(cpu_fpr[a->rd], cpu_env, ofs); + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], + 0xffffffffffff0000ULL); + break; + case MO_32: + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], + 0xffffffff00000000ULL); + break; + default: + if (has_ext(s, RVD)) { + tcg_gen_ld_i64(cpu_fpr[a->rd], cpu_env, ofs); + } else { + tcg_gen_ld32u_i64(cpu_fpr[a->rd], cpu_env, ofs); + tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], + 0xffffffff00000000ULL); + } + break; + } + mark_fs_dirty(s); + return true; + } + return false; +} + +typedef void gen_helper_vfmv_s_f(TCGv_ptr, TCGv_i64, TCGv_env); +static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a) +{ + if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) { + TCGv_ptr dest; + TCGv_i64 src1; + static gen_helper_vfmv_s_f * const fns[3] = { + gen_helper_vfmv_s_f_h, + gen_helper_vfmv_s_f_w, + gen_helper_vfmv_s_f_d + }; + + src1 = tcg_temp_new_i64(); + dest = tcg_temp_new_ptr(); + if (s->sew == MO_64 && !has_ext(s, RVD)) { + tcg_gen_ori_i64(src1, cpu_fpr[a->rs1], 0xffffffff00000000ULL); + } else { + tcg_gen_mov_i64(src1, cpu_fpr[a->rs1]); + } + tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd)); + + fns[s->sew - 1](dest, src1, cpu_env); + + tcg_temp_free_i64(src1); + tcg_temp_free_ptr(dest); + return true; + } + return false; +} diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 7f67a283c9..723e15a670 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -4691,3 +4691,18 @@ GEN_VEXT_VMV_S_X(vmv_s_x_b, uint8_t, H1, clearb) GEN_VEXT_VMV_S_X(vmv_s_x_h, uint16_t, H2, clearh) GEN_VEXT_VMV_S_X(vmv_s_x_w, uint32_t, H4, clearl) GEN_VEXT_VMV_S_X(vmv_s_x_d, uint64_t, H8, clearq) + +/* Floating-Point Scalar Move Instructions */ +#define GEN_VEXT_VFMV_S_F(NAME, ETYPE, H, CLEAR_FN) \ +void HELPER(NAME)(void *vd, uint64_t s1, CPURISCVState *env) \ +{ \ + if (env->vl == 0) { \ + return; \ + } \ + *((ETYPE *)vd + H(0)) = s1; \ + CLEAR_FN(vd, 1, sizeof(ETYPE), env_archcpu(env)->cfg.vlen / 8); \ +} + +GEN_VEXT_VFMV_S_F(vfmv_s_f_h, uint16_t, H2, clearh) +GEN_VEXT_VFMV_S_F(vfmv_s_f_w, uint32_t, H4, clearl) +GEN_VEXT_VFMV_S_F(vfmv_s_f_d, uint64_t, H8, clearq)
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> --- target/riscv/helper.h | 4 ++ target/riscv/insn32.decode | 2 + target/riscv/insn_trans/trans_rvv.inc.c | 72 +++++++++++++++++++++++++ target/riscv/vector_helper.c | 15 ++++++ 4 files changed, 93 insertions(+)