diff mbox series

[v8,34/78] target/riscv: rvv-1.0: allow load element with sign-extended

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

Commit Message

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

For some vector instructions (e.g. vmv.s.x), the element is loaded with
sign-extended.

Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 32 +++++++++++++++++--------
 1 file changed, 22 insertions(+), 10 deletions(-)

Comments

Alistair Francis Oct. 21, 2021, 4:28 a.m. UTC | #1
On Fri, Oct 15, 2021 at 6:28 PM <frank.chang@sifive.com> wrote:
>
> From: Frank Chang <frank.chang@sifive.com>
>
> For some vector instructions (e.g. vmv.s.x), the element is loaded with
> sign-extended.
>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 32 +++++++++++++++++--------
>  1 file changed, 22 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 3751496676f..31ea231b3be 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2824,17 +2824,29 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
>  /* Integer Extract Instruction */
>
>  static void load_element(TCGv_i64 dest, TCGv_ptr base,
> -                         int ofs, int sew)
> +                         int ofs, int sew, bool sign)
>  {
>      switch (sew) {
>      case MO_8:
> -        tcg_gen_ld8u_i64(dest, base, ofs);
> +        if (!sign) {
> +            tcg_gen_ld8u_i64(dest, base, ofs);
> +        } else {
> +            tcg_gen_ld8s_i64(dest, base, ofs);
> +        }
>          break;
>      case MO_16:
> -        tcg_gen_ld16u_i64(dest, base, ofs);
> +        if (!sign) {
> +            tcg_gen_ld16u_i64(dest, base, ofs);
> +        } else {
> +            tcg_gen_ld16s_i64(dest, base, ofs);
> +        }
>          break;
>      case MO_32:
> -        tcg_gen_ld32u_i64(dest, base, ofs);
> +        if (!sign) {
> +            tcg_gen_ld32u_i64(dest, base, ofs);
> +        } else {
> +            tcg_gen_ld32s_i64(dest, base, ofs);
> +        }
>          break;
>      case MO_64:
>          tcg_gen_ld_i64(dest, base, ofs);
> @@ -2889,7 +2901,7 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
>
>      /* Perform the load. */
>      load_element(dest, base,
> -                 vreg_ofs(s, vreg), s->sew);
> +                 vreg_ofs(s, vreg), s->sew, false);
>      tcg_temp_free_ptr(base);
>      tcg_temp_free_i32(ofs);
>
> @@ -2905,9 +2917,9 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
>  }
>
>  static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
> -                              int vreg, int idx)
> +                              int vreg, int idx, bool sign)
>  {
> -    load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew);
> +    load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
>  }
>
>  static bool trans_vext_x_v(DisasContext *s, arg_r *a)
> @@ -2917,7 +2929,7 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>
>      if (a->rs1 == 0) {
>          /* Special case vmv.x.s rd, vs2. */
> -        vec_element_loadi(s, tmp, a->rs2, 0);
> +        vec_element_loadi(s, tmp, a->rs2, 0, false);
>      } else {
>          /* This instruction ignores LMUL and vector register groups */
>          int vlmax = s->vlen >> (3 + s->sew);
> @@ -2999,7 +3011,7 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
>          (s->mstatus_fs != 0) && (s->sew != 0)) {
>          unsigned int len = 8 << s->sew;
>
> -        vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0);
> +        vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
>          if (len < 64) {
>              tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
>                              MAKE_64BIT_MASK(len, 64 - len));
> @@ -3101,7 +3113,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
>          TCGv_i64 dest = tcg_temp_new_i64();
>
>          if (a->rs1 == 0) {
> -            vec_element_loadi(s, dest, a->rs2, 0);
> +            vec_element_loadi(s, dest, a->rs2, 0, false);
>          } else {
>              vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
>          }
> --
> 2.25.1
>
>
diff mbox series

Patch

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 3751496676f..31ea231b3be 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2824,17 +2824,29 @@  static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
 /* Integer Extract Instruction */
 
 static void load_element(TCGv_i64 dest, TCGv_ptr base,
-                         int ofs, int sew)
+                         int ofs, int sew, bool sign)
 {
     switch (sew) {
     case MO_8:
-        tcg_gen_ld8u_i64(dest, base, ofs);
+        if (!sign) {
+            tcg_gen_ld8u_i64(dest, base, ofs);
+        } else {
+            tcg_gen_ld8s_i64(dest, base, ofs);
+        }
         break;
     case MO_16:
-        tcg_gen_ld16u_i64(dest, base, ofs);
+        if (!sign) {
+            tcg_gen_ld16u_i64(dest, base, ofs);
+        } else {
+            tcg_gen_ld16s_i64(dest, base, ofs);
+        }
         break;
     case MO_32:
-        tcg_gen_ld32u_i64(dest, base, ofs);
+        if (!sign) {
+            tcg_gen_ld32u_i64(dest, base, ofs);
+        } else {
+            tcg_gen_ld32s_i64(dest, base, ofs);
+        }
         break;
     case MO_64:
         tcg_gen_ld_i64(dest, base, ofs);
@@ -2889,7 +2901,7 @@  static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
 
     /* Perform the load. */
     load_element(dest, base,
-                 vreg_ofs(s, vreg), s->sew);
+                 vreg_ofs(s, vreg), s->sew, false);
     tcg_temp_free_ptr(base);
     tcg_temp_free_i32(ofs);
 
@@ -2905,9 +2917,9 @@  static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
 }
 
 static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
-                              int vreg, int idx)
+                              int vreg, int idx, bool sign)
 {
-    load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew);
+    load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
 }
 
 static bool trans_vext_x_v(DisasContext *s, arg_r *a)
@@ -2917,7 +2929,7 @@  static bool trans_vext_x_v(DisasContext *s, arg_r *a)
 
     if (a->rs1 == 0) {
         /* Special case vmv.x.s rd, vs2. */
-        vec_element_loadi(s, tmp, a->rs2, 0);
+        vec_element_loadi(s, tmp, a->rs2, 0, false);
     } else {
         /* This instruction ignores LMUL and vector register groups */
         int vlmax = s->vlen >> (3 + s->sew);
@@ -2999,7 +3011,7 @@  static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
         (s->mstatus_fs != 0) && (s->sew != 0)) {
         unsigned int len = 8 << s->sew;
 
-        vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0);
+        vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
         if (len < 64) {
             tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
                             MAKE_64BIT_MASK(len, 64 - len));
@@ -3101,7 +3113,7 @@  static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
         TCGv_i64 dest = tcg_temp_new_i64();
 
         if (a->rs1 == 0) {
-            vec_element_loadi(s, dest, a->rs2, 0);
+            vec_element_loadi(s, dest, a->rs2, 0, false);
         } else {
             vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
         }