diff mbox series

[v8,61/78] target/riscv: rvv-1.0: floating-point/integer type-convert instructions

Message ID 20211015074627.3957162-69-frank.chang@sifive.com
State New
Headers show
Series support vector extension v1.0 | expand

Commit Message

Frank Chang Oct. 15, 2021, 7:46 a.m. UTC
From: Frank Chang <frank.chang@sifive.com>

Add the following instructions:

* vfcvt.rtz.xu.f.v
* vfcvt.rtz.x.f.v

Also adjust GEN_OPFV_TRANS() to accept multiple floating-point rounding
modes.

Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
 target/riscv/insn32.decode              | 11 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 84 +++++++++++++++----------
 2 files changed, 59 insertions(+), 36 deletions(-)

Comments

Alistair Francis Oct. 25, 2021, 6:16 a.m. UTC | #1
On Fri, Oct 15, 2021 at 6:43 PM <frank.chang@sifive.com> wrote:
>
> From: Frank Chang <frank.chang@sifive.com>
>
> Add the following instructions:
>
> * vfcvt.rtz.xu.f.v
> * vfcvt.rtz.x.f.v
>
> Also adjust GEN_OPFV_TRANS() to accept multiple floating-point rounding
> modes.
>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn32.decode              | 11 ++--
>  target/riscv/insn_trans/trans_rvv.c.inc | 84 +++++++++++++++----------
>  2 files changed, 59 insertions(+), 36 deletions(-)
>
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 20b3095f56c..02064f8ec98 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -585,10 +585,13 @@ vmfge_vf        011111 . ..... ..... 101 ..... 1010111 @r_vm
>  vfclass_v       010011 . ..... 10000 001 ..... 1010111 @r2_vm
>  vfmerge_vfm     010111 0 ..... ..... 101 ..... 1010111 @r_vm_0
>  vfmv_v_f        010111 1 00000 ..... 101 ..... 1010111 @r2
> -vfcvt_xu_f_v    100010 . ..... 00000 001 ..... 1010111 @r2_vm
> -vfcvt_x_f_v     100010 . ..... 00001 001 ..... 1010111 @r2_vm
> -vfcvt_f_xu_v    100010 . ..... 00010 001 ..... 1010111 @r2_vm
> -vfcvt_f_x_v     100010 . ..... 00011 001 ..... 1010111 @r2_vm
> +
> +vfcvt_xu_f_v       010010 . ..... 00000 001 ..... 1010111 @r2_vm
> +vfcvt_x_f_v        010010 . ..... 00001 001 ..... 1010111 @r2_vm
> +vfcvt_f_xu_v       010010 . ..... 00010 001 ..... 1010111 @r2_vm
> +vfcvt_f_x_v        010010 . ..... 00011 001 ..... 1010111 @r2_vm
> +vfcvt_rtz_xu_f_v   010010 . ..... 00110 001 ..... 1010111 @r2_vm
> +vfcvt_rtz_x_f_v    010010 . ..... 00111 001 ..... 1010111 @r2_vm
>  vfwcvt_xu_f_v   100010 . ..... 01000 001 ..... 1010111 @r2_vm
>  vfwcvt_x_f_v    100010 . ..... 01001 001 ..... 1010111 @r2_vm
>  vfwcvt_f_xu_v   100010 . ..... 01010 001 ..... 1010111 @r2_vm
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 676336a5200..b1ea15517c0 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -1,5 +1,4 @@
>  /*
> - * RISC-V translation routines for the RVV Standard Extension.
>   *
>   * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
>   *
> @@ -2368,34 +2367,41 @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
>             vext_check_ss(s, a->rd, a->rs2, a->vm);
>  }
>
> -#define GEN_OPFV_TRANS(NAME, CHECK)                                \
> -static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
> -{                                                                  \
> -    if (CHECK(s, a)) {                                             \
> -        uint32_t data = 0;                                         \
> -        static gen_helper_gvec_3_ptr * const fns[3] = {            \
> -            gen_helper_##NAME##_h,                                 \
> -            gen_helper_##NAME##_w,                                 \
> -            gen_helper_##NAME##_d,                                 \
> -        };                                                         \
> -        TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, RISCV_FRM_DYN);                              \
> -        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
> -                                                                   \
> -        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
> -        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
> -        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
> -                           vreg_ofs(s, a->rs2), cpu_env,           \
> -                           s->vlen / 8, s->vlen / 8, data,         \
> -                           fns[s->sew - 1]);                       \
> -        mark_vs_dirty(s);                                          \
> -        gen_set_label(over);                                       \
> -        return true;                                               \
> -    }                                                              \
> -    return false;                                                  \
> +static bool do_opfv(DisasContext *s, arg_rmr *a,
> +                    gen_helper_gvec_3_ptr *fn,
> +                    bool (*checkfn)(DisasContext *, arg_rmr *),
> +                    int rm)
> +{
> +    if (checkfn(s, a)) {
> +        uint32_t data = 0;
> +        TCGLabel *over = gen_new_label();
> +        gen_set_rm(s, rm);
> +        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
> +
> +        data = FIELD_DP32(data, VDATA, VM, a->vm);
> +        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> +        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
> +                           vreg_ofs(s, a->rs2), cpu_env,
> +                           s->vlen / 8, s->vlen / 8, data, fn);
> +        mark_vs_dirty(s);
> +        gen_set_label(over);
> +        return true;
> +    }
> +    return false;
> +}
> +
> +#define GEN_OPFV_TRANS(NAME, CHECK, FRM)               \
> +static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
> +{                                                      \
> +    static gen_helper_gvec_3_ptr * const fns[3] = {    \
> +        gen_helper_##NAME##_h,                         \
> +        gen_helper_##NAME##_w,                         \
> +        gen_helper_##NAME##_d                          \
> +    };                                                 \
> +    return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM); \
>  }
>
> -GEN_OPFV_TRANS(vfsqrt_v, opfv_check)
> +GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
>
>  /* Vector Floating-Point MIN/MAX Instructions */
>  GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
> @@ -2441,7 +2447,7 @@ GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
>  GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
>
>  /* Vector Floating-Point Classify Instruction */
> -GEN_OPFV_TRANS(vfclass_v, opfv_check)
> +GEN_OPFV_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
>
>  /* Vector Floating-Point Merge Instruction */
>  GEN_OPFVF_TRANS(vfmerge_vfm,  opfvf_check)
> @@ -2495,10 +2501,24 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
>  }
>
>  /* Single-Width Floating-Point/Integer Type-Convert Instructions */
> -GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check)
> -GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check)
> -GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check)
> -GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check)
> +#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM)               \
> +static bool trans_##NAME(DisasContext *s, arg_rmr *a)       \
> +{                                                           \
> +    static gen_helper_gvec_3_ptr * const fns[3] = {         \
> +        gen_helper_##HELPER##_h,                            \
> +        gen_helper_##HELPER##_w,                            \
> +        gen_helper_##HELPER##_d                             \
> +    };                                                      \
> +    return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM); \
> +}
> +
> +GEN_OPFV_CVT_TRANS(vfcvt_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_DYN)
> +GEN_OPFV_CVT_TRANS(vfcvt_x_f_v, vfcvt_x_f_v, RISCV_FRM_DYN)
> +GEN_OPFV_CVT_TRANS(vfcvt_f_xu_v, vfcvt_f_xu_v, RISCV_FRM_DYN)
> +GEN_OPFV_CVT_TRANS(vfcvt_f_x_v, vfcvt_f_x_v, RISCV_FRM_DYN)
> +/* Reuse the helper functions from vfcvt.xu.f.v and vfcvt.x.f.v */
> +GEN_OPFV_CVT_TRANS(vfcvt_rtz_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_RTZ)
> +GEN_OPFV_CVT_TRANS(vfcvt_rtz_x_f_v, vfcvt_x_f_v, RISCV_FRM_RTZ)
>
>  /* Widening Floating-Point/Integer Type-Convert Instructions */
>
> --
> 2.25.1
>
>
diff mbox series

Patch

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 20b3095f56c..02064f8ec98 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -585,10 +585,13 @@  vmfge_vf        011111 . ..... ..... 101 ..... 1010111 @r_vm
 vfclass_v       010011 . ..... 10000 001 ..... 1010111 @r2_vm
 vfmerge_vfm     010111 0 ..... ..... 101 ..... 1010111 @r_vm_0
 vfmv_v_f        010111 1 00000 ..... 101 ..... 1010111 @r2
-vfcvt_xu_f_v    100010 . ..... 00000 001 ..... 1010111 @r2_vm
-vfcvt_x_f_v     100010 . ..... 00001 001 ..... 1010111 @r2_vm
-vfcvt_f_xu_v    100010 . ..... 00010 001 ..... 1010111 @r2_vm
-vfcvt_f_x_v     100010 . ..... 00011 001 ..... 1010111 @r2_vm
+
+vfcvt_xu_f_v       010010 . ..... 00000 001 ..... 1010111 @r2_vm
+vfcvt_x_f_v        010010 . ..... 00001 001 ..... 1010111 @r2_vm
+vfcvt_f_xu_v       010010 . ..... 00010 001 ..... 1010111 @r2_vm
+vfcvt_f_x_v        010010 . ..... 00011 001 ..... 1010111 @r2_vm
+vfcvt_rtz_xu_f_v   010010 . ..... 00110 001 ..... 1010111 @r2_vm
+vfcvt_rtz_x_f_v    010010 . ..... 00111 001 ..... 1010111 @r2_vm
 vfwcvt_xu_f_v   100010 . ..... 01000 001 ..... 1010111 @r2_vm
 vfwcvt_x_f_v    100010 . ..... 01001 001 ..... 1010111 @r2_vm
 vfwcvt_f_xu_v   100010 . ..... 01010 001 ..... 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 676336a5200..b1ea15517c0 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1,5 +1,4 @@ 
 /*
- * RISC-V translation routines for the RVV Standard Extension.
  *
  * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
  *
@@ -2368,34 +2367,41 @@  static bool opfv_check(DisasContext *s, arg_rmr *a)
            vext_check_ss(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_TRANS(NAME, CHECK)                                \
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
-{                                                                  \
-    if (CHECK(s, a)) {                                             \
-        uint32_t data = 0;                                         \
-        static gen_helper_gvec_3_ptr * const fns[3] = {            \
-            gen_helper_##NAME##_h,                                 \
-            gen_helper_##NAME##_w,                                 \
-            gen_helper_##NAME##_d,                                 \
-        };                                                         \
-        TCGLabel *over = gen_new_label();                          \
-        gen_set_rm(s, RISCV_FRM_DYN);                              \
-        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
-                                                                   \
-        data = FIELD_DP32(data, VDATA, VM, a->vm);                 \
-        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);             \
-        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),     \
-                           vreg_ofs(s, a->rs2), cpu_env,           \
-                           s->vlen / 8, s->vlen / 8, data,         \
-                           fns[s->sew - 1]);                       \
-        mark_vs_dirty(s);                                          \
-        gen_set_label(over);                                       \
-        return true;                                               \
-    }                                                              \
-    return false;                                                  \
+static bool do_opfv(DisasContext *s, arg_rmr *a,
+                    gen_helper_gvec_3_ptr *fn,
+                    bool (*checkfn)(DisasContext *, arg_rmr *),
+                    int rm)
+{
+    if (checkfn(s, a)) {
+        uint32_t data = 0;
+        TCGLabel *over = gen_new_label();
+        gen_set_rm(s, rm);
+        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+
+        data = FIELD_DP32(data, VDATA, VM, a->vm);
+        data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+        tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+                           vreg_ofs(s, a->rs2), cpu_env,
+                           s->vlen / 8, s->vlen / 8, data, fn);
+        mark_vs_dirty(s);
+        gen_set_label(over);
+        return true;
+    }
+    return false;
+}
+
+#define GEN_OPFV_TRANS(NAME, CHECK, FRM)               \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{                                                      \
+    static gen_helper_gvec_3_ptr * const fns[3] = {    \
+        gen_helper_##NAME##_h,                         \
+        gen_helper_##NAME##_w,                         \
+        gen_helper_##NAME##_d                          \
+    };                                                 \
+    return do_opfv(s, a, fns[s->sew - 1], CHECK, FRM); \
 }
 
-GEN_OPFV_TRANS(vfsqrt_v, opfv_check)
+GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point MIN/MAX Instructions */
 GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
@@ -2441,7 +2447,7 @@  GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
 
 /* Vector Floating-Point Classify Instruction */
-GEN_OPFV_TRANS(vfclass_v, opfv_check)
+GEN_OPFV_TRANS(vfclass_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point Merge Instruction */
 GEN_OPFVF_TRANS(vfmerge_vfm,  opfvf_check)
@@ -2495,10 +2501,24 @@  static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
 }
 
 /* Single-Width Floating-Point/Integer Type-Convert Instructions */
-GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check)
-GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check)
-GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check)
-GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check)
+#define GEN_OPFV_CVT_TRANS(NAME, HELPER, FRM)               \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)       \
+{                                                           \
+    static gen_helper_gvec_3_ptr * const fns[3] = {         \
+        gen_helper_##HELPER##_h,                            \
+        gen_helper_##HELPER##_w,                            \
+        gen_helper_##HELPER##_d                             \
+    };                                                      \
+    return do_opfv(s, a, fns[s->sew - 1], opfv_check, FRM); \
+}
+
+GEN_OPFV_CVT_TRANS(vfcvt_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_DYN)
+GEN_OPFV_CVT_TRANS(vfcvt_x_f_v, vfcvt_x_f_v, RISCV_FRM_DYN)
+GEN_OPFV_CVT_TRANS(vfcvt_f_xu_v, vfcvt_f_xu_v, RISCV_FRM_DYN)
+GEN_OPFV_CVT_TRANS(vfcvt_f_x_v, vfcvt_f_x_v, RISCV_FRM_DYN)
+/* Reuse the helper functions from vfcvt.xu.f.v and vfcvt.x.f.v */
+GEN_OPFV_CVT_TRANS(vfcvt_rtz_xu_f_v, vfcvt_xu_f_v, RISCV_FRM_RTZ)
+GEN_OPFV_CVT_TRANS(vfcvt_rtz_x_f_v, vfcvt_x_f_v, RISCV_FRM_RTZ)
 
 /* Widening Floating-Point/Integer Type-Convert Instructions */