Signed-off-by: LIU Zhiwei <zhiwei_...@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(+)
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) -- 2.23.0