diff mbox series

[v6,57/61] target/riscv: floating-point scalar move instructions

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

Commit Message

LIU Zhiwei March 17, 2020, 3:06 p.m. UTC
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(+)

Comments

Richard Henderson March 28, 2020, 3:44 a.m. UTC | #1
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~
LIU Zhiwei March 28, 2020, 4:31 p.m. UTC | #2
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 mbox series

Patch

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)