Patchwork SPARC64: fix VIS1 SIMD signed compare instructions

login
register
mail settings
Submitter Tsuneo Saito
Date July 18, 2011, 6 a.m.
Message ID <1310968800-23292-1-git-send-email-tsnsaito@gmail.com>
Download mbox | patch
Permalink /patch/105162/
State New
Headers show

Comments

Tsuneo Saito - July 18, 2011, 6 a.m.
The destination registers of SIMD signed compare instructions
(fcmp*<16|32>) are not FP registers but general purpose r registers.
Comparisons should be freg_rs1 CMP freg_rs2, that were reversed.

Signed-off-by: Tsuneo Saito <tsnsaito@gmail.com>
---
 target-sparc/helper.h    |    4 ++--
 target-sparc/op_helper.c |   23 +++++++++++++----------
 target-sparc/translate.c |   32 ++++++++++++++++----------------
 3 files changed, 31 insertions(+), 28 deletions(-)
Blue Swirl - July 20, 2011, 8:52 p.m.
Thanks, applied.

On Mon, Jul 18, 2011 at 9:00 AM, Tsuneo Saito <tsnsaito@gmail.com> wrote:
> The destination registers of SIMD signed compare instructions
> (fcmp*<16|32>) are not FP registers but general purpose r registers.
> Comparisons should be freg_rs1 CMP freg_rs2, that were reversed.
>
> Signed-off-by: Tsuneo Saito <tsnsaito@gmail.com>
> ---
>  target-sparc/helper.h    |    4 ++--
>  target-sparc/op_helper.c |   23 +++++++++++++----------
>  target-sparc/translate.c |   32 ++++++++++++++++----------------
>  3 files changed, 31 insertions(+), 28 deletions(-)
>
> diff --git a/target-sparc/helper.h b/target-sparc/helper.h
> index 023f4d6..2d36af3 100644
> --- a/target-sparc/helper.h
> +++ b/target-sparc/helper.h
> @@ -148,8 +148,8 @@ F_HELPER_0_0(expand);
>  VIS_HELPER(padd);
>  VIS_HELPER(psub);
>  #define VIS_CMPHELPER(name)                              \
> -    F_HELPER_0_0(name##16);                              \
> -    F_HELPER_0_0(name##32)
> +    DEF_HELPER_0(f##name##16, i64);                      \
> +    DEF_HELPER_0(f##name##32, i64)
>  VIS_CMPHELPER(cmpgt);
>  VIS_CMPHELPER(cmpeq);
>  VIS_CMPHELPER(cmple);
> diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
> index 15af27b..b99223e 100644
> --- a/target-sparc/op_helper.c
> +++ b/target-sparc/op_helper.c
> @@ -525,6 +525,7 @@ typedef union {
>     uint16_t w[4];
>     int16_t sw[4];
>     uint32_t l[2];
> +    uint64_t ll;
>     float64 d;
>  } vis64;
>
> @@ -789,32 +790,34 @@ VIS_HELPER(helper_fpadd, FADD)
>  VIS_HELPER(helper_fpsub, FSUB)
>
>  #define VIS_CMPHELPER(name, F)                                        \
> -    void name##16(void)                                           \
> +    uint64_t name##16(void)                                       \
>     {                                                             \
>         vis64 s, d;                                               \
>                                                                   \
>         s.d = DT0;                                                \
>         d.d = DT1;                                                \
>                                                                   \
> -        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
> -        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
> -        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
> -        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
> +        d.VIS_W64(0) = F(s.VIS_W64(0), d.VIS_W64(0)) ? 1 : 0;     \
> +        d.VIS_W64(0) |= F(s.VIS_W64(1), d.VIS_W64(1)) ? 2 : 0;    \
> +        d.VIS_W64(0) |= F(s.VIS_W64(2), d.VIS_W64(2)) ? 4 : 0;    \
> +        d.VIS_W64(0) |= F(s.VIS_W64(3), d.VIS_W64(3)) ? 8 : 0;    \
> +        d.VIS_W64(1) = d.VIS_W64(2) = d.VIS_W64(3) = 0;           \
>                                                                   \
> -        DT0 = d.d;                                                \
> +        return d.ll;                                              \
>     }                                                             \
>                                                                   \
> -    void name##32(void)                                           \
> +    uint64_t name##32(void)                                       \
>     {                                                             \
>         vis64 s, d;                                               \
>                                                                   \
>         s.d = DT0;                                                \
>         d.d = DT1;                                                \
>                                                                   \
> -        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
> -        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
> +        d.VIS_L64(0) = F(s.VIS_L64(0), d.VIS_L64(0)) ? 1 : 0;     \
> +        d.VIS_L64(0) |= F(s.VIS_L64(1), d.VIS_L64(1)) ? 2 : 0;    \
> +        d.VIS_L64(1) = 0;                                         \
>                                                                   \
> -        DT0 = d.d;                                                \
> +        return d.ll;                                              \
>     }
>
>  #define FCMPGT(a, b) ((a) > (b))
> diff --git a/target-sparc/translate.c b/target-sparc/translate.c
> index 27c2cf9..a1a19c3 100644
> --- a/target-sparc/translate.c
> +++ b/target-sparc/translate.c
> @@ -3789,57 +3789,57 @@ static void disas_sparc_insn(DisasContext * dc)
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmple16();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmple16(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x022: /* VIS I fcmpne16 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpne16();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpne16(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x024: /* VIS I fcmple32 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmple32();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmple32(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x026: /* VIS I fcmpne32 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpne32();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpne32(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x028: /* VIS I fcmpgt16 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpgt16();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpgt16(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x02a: /* VIS I fcmpeq16 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpeq16();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpeq16(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x02c: /* VIS I fcmpgt32 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpgt32();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpgt32(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x02e: /* VIS I fcmpeq32 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
>                     gen_op_load_fpr_DT0(DFPREG(rs1));
>                     gen_op_load_fpr_DT1(DFPREG(rs2));
> -                    gen_helper_fcmpeq32();
> -                    gen_op_store_DT0_fpr(DFPREG(rd));
> +                    gen_helper_fcmpeq32(cpu_dst);
> +                    gen_movl_TN_reg(rd, cpu_dst);
>                     break;
>                 case 0x031: /* VIS I fmul8x16 */
>                     CHECK_FPU_FEATURE(dc, VIS1);
> --
> 1.7.5.4
>
>
>

Patch

diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 023f4d6..2d36af3 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -148,8 +148,8 @@  F_HELPER_0_0(expand);
 VIS_HELPER(padd);
 VIS_HELPER(psub);
 #define VIS_CMPHELPER(name)                              \
-    F_HELPER_0_0(name##16);                              \
-    F_HELPER_0_0(name##32)
+    DEF_HELPER_0(f##name##16, i64);                      \
+    DEF_HELPER_0(f##name##32, i64)
 VIS_CMPHELPER(cmpgt);
 VIS_CMPHELPER(cmpeq);
 VIS_CMPHELPER(cmple);
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 15af27b..b99223e 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -525,6 +525,7 @@  typedef union {
     uint16_t w[4];
     int16_t sw[4];
     uint32_t l[2];
+    uint64_t ll;
     float64 d;
 } vis64;
 
@@ -789,32 +790,34 @@  VIS_HELPER(helper_fpadd, FADD)
 VIS_HELPER(helper_fpsub, FSUB)
 
 #define VIS_CMPHELPER(name, F)                                        \
-    void name##16(void)                                           \
+    uint64_t name##16(void)                                       \
     {                                                             \
         vis64 s, d;                                               \
                                                                   \
         s.d = DT0;                                                \
         d.d = DT1;                                                \
                                                                   \
-        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0))? 1: 0;       \
-        d.VIS_W64(0) |= F(d.VIS_W64(1), s.VIS_W64(1))? 2: 0;      \
-        d.VIS_W64(0) |= F(d.VIS_W64(2), s.VIS_W64(2))? 4: 0;      \
-        d.VIS_W64(0) |= F(d.VIS_W64(3), s.VIS_W64(3))? 8: 0;      \
+        d.VIS_W64(0) = F(s.VIS_W64(0), d.VIS_W64(0)) ? 1 : 0;     \
+        d.VIS_W64(0) |= F(s.VIS_W64(1), d.VIS_W64(1)) ? 2 : 0;    \
+        d.VIS_W64(0) |= F(s.VIS_W64(2), d.VIS_W64(2)) ? 4 : 0;    \
+        d.VIS_W64(0) |= F(s.VIS_W64(3), d.VIS_W64(3)) ? 8 : 0;    \
+        d.VIS_W64(1) = d.VIS_W64(2) = d.VIS_W64(3) = 0;           \
                                                                   \
-        DT0 = d.d;                                                \
+        return d.ll;                                              \
     }                                                             \
                                                                   \
-    void name##32(void)                                           \
+    uint64_t name##32(void)                                       \
     {                                                             \
         vis64 s, d;                                               \
                                                                   \
         s.d = DT0;                                                \
         d.d = DT1;                                                \
                                                                   \
-        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0))? 1: 0;       \
-        d.VIS_L64(0) |= F(d.VIS_L64(1), s.VIS_L64(1))? 2: 0;      \
+        d.VIS_L64(0) = F(s.VIS_L64(0), d.VIS_L64(0)) ? 1 : 0;     \
+        d.VIS_L64(0) |= F(s.VIS_L64(1), d.VIS_L64(1)) ? 2 : 0;    \
+        d.VIS_L64(1) = 0;                                         \
                                                                   \
-        DT0 = d.d;                                                \
+        return d.ll;                                              \
     }
 
 #define FCMPGT(a, b) ((a) > (b))
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 27c2cf9..a1a19c3 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -3789,57 +3789,57 @@  static void disas_sparc_insn(DisasContext * dc)
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmple16();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmple16(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x022: /* VIS I fcmpne16 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpne16();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpne16(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x024: /* VIS I fcmple32 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmple32();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmple32(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x026: /* VIS I fcmpne32 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpne32();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpne32(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x028: /* VIS I fcmpgt16 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpgt16();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpgt16(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x02a: /* VIS I fcmpeq16 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpeq16();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpeq16(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x02c: /* VIS I fcmpgt32 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpgt32();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpgt32(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x02e: /* VIS I fcmpeq32 */
                     CHECK_FPU_FEATURE(dc, VIS1);
                     gen_op_load_fpr_DT0(DFPREG(rs1));
                     gen_op_load_fpr_DT1(DFPREG(rs2));
-                    gen_helper_fcmpeq32();
-                    gen_op_store_DT0_fpr(DFPREG(rd));
+                    gen_helper_fcmpeq32(cpu_dst);
+                    gen_movl_TN_reg(rd, cpu_dst);
                     break;
                 case 0x031: /* VIS I fmul8x16 */
                     CHECK_FPU_FEATURE(dc, VIS1);