diff mbox series

[8/8] target/sparc: Fix VIS subtraction instructions.

Message ID 20230925050545.30912-9-nbowler@draconx.ca
State New
Headers show
Series SPARC VIS fixes | expand

Commit Message

Nick Bowler Sept. 25, 2023, 5:03 a.m. UTC
All of the VIS subtraction instructions are documented to subtract the
second input operand from the first.  This is also consistent with how
the instructions actually work on a real UltraSparc II.

But the emulator is implementing the subtraction in the wrong order,
subtracting the first input from the second, so the results are wrong
in all nontrivial cases.

Signed-off-by: Nick Bowler <nbowler@draconx.ca>
---
 target/sparc/vis_helper.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

Comments

Richard Henderson Sept. 28, 2023, 9:40 p.m. UTC | #1
On 9/24/23 01:03, Nick Bowler wrote:
> All of the VIS subtraction instructions are documented to subtract the
> second input operand from the first.  This is also consistent with how
> the instructions actually work on a real UltraSparc II.
> 
> But the emulator is implementing the subtraction in the wrong order,
> subtracting the first input from the second, so the results are wrong
> in all nontrivial cases.
> 
> Signed-off-by: Nick Bowler <nbowler@draconx.ca>
> ---
>   target/sparc/vis_helper.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)

While this patch works, better to use

void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);

void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);

from "tcg/tcg-op-gvec.h" and remove the sparc helpers.


r~
Nick Bowler Sept. 29, 2023, 12:31 a.m. UTC | #2
On 2023-09-28, Richard Henderson <richard.henderson@linaro.org> wrote:
> On 9/24/23 01:03, Nick Bowler wrote:
>> All of the VIS subtraction instructions are documented to subtract the
>> second input operand from the first.  This is also consistent with how
>> the instructions actually work on a real UltraSparc II.
>>
>> But the emulator is implementing the subtraction in the wrong order,
>> subtracting the first input from the second, so the results are wrong
>> in all nontrivial cases.
>>
>> Signed-off-by: Nick Bowler <nbowler@draconx.ca>
>> ---
>>   target/sparc/vis_helper.c | 18 +++++++++---------
>>   1 file changed, 9 insertions(+), 9 deletions(-)
>
> While this patch works, better to use
>
> void tcg_gen_vec_add16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
> void tcg_gen_vec_add16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
> void tcg_gen_vec_add32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
>
> void tcg_gen_vec_sub16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
> void tcg_gen_vec_sub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
> void tcg_gen_vec_sub32_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
>
> from "tcg/tcg-op-gvec.h" and remove the sparc helpers.

OK, I will try to respin this one using these.

Thanks,
  Nick
diff mbox series

Patch

diff --git a/target/sparc/vis_helper.c b/target/sparc/vis_helper.c
index 3903beaf5d..fa97e09ffa 100644
--- a/target/sparc/vis_helper.c
+++ b/target/sparc/vis_helper.c
@@ -282,10 +282,10 @@  uint64_t helper_fexpand(uint32_t src2)
         s.ll = src1;                                    \
         d.ll = src2;                                    \
                                                         \
-        d.VIS_W64(0) = F(d.VIS_W64(0), s.VIS_W64(0));   \
-        d.VIS_W64(1) = F(d.VIS_W64(1), s.VIS_W64(1));   \
-        d.VIS_W64(2) = F(d.VIS_W64(2), s.VIS_W64(2));   \
-        d.VIS_W64(3) = F(d.VIS_W64(3), s.VIS_W64(3));   \
+        d.VIS_W64(0) = F(s.VIS_W64(0), d.VIS_W64(0));   \
+        d.VIS_W64(1) = F(s.VIS_W64(1), d.VIS_W64(1));   \
+        d.VIS_W64(2) = F(s.VIS_W64(2), d.VIS_W64(2));   \
+        d.VIS_W64(3) = F(s.VIS_W64(3), d.VIS_W64(3));   \
                                                         \
         return d.ll;                                    \
     }                                                   \
@@ -297,8 +297,8 @@  uint64_t helper_fexpand(uint32_t src2)
         s.l = src1;                                     \
         d.l = src2;                                     \
                                                         \
-        d.VIS_W32(0) = F(d.VIS_W32(0), s.VIS_W32(0));   \
-        d.VIS_W32(1) = F(d.VIS_W32(1), s.VIS_W32(1));   \
+        d.VIS_W32(0) = F(s.VIS_W32(0), d.VIS_W32(0));   \
+        d.VIS_W32(1) = F(s.VIS_W32(1), d.VIS_W32(1));   \
                                                         \
         return d.l;                                     \
     }                                                   \
@@ -310,8 +310,8 @@  uint64_t helper_fexpand(uint32_t src2)
         s.ll = src1;                                    \
         d.ll = src2;                                    \
                                                         \
-        d.VIS_L64(0) = F(d.VIS_L64(0), s.VIS_L64(0));   \
-        d.VIS_L64(1) = F(d.VIS_L64(1), s.VIS_L64(1));   \
+        d.VIS_L64(0) = F(s.VIS_L64(0), d.VIS_L64(0));   \
+        d.VIS_L64(1) = F(s.VIS_L64(1), d.VIS_L64(1));   \
                                                         \
         return d.ll;                                    \
     }                                                   \
@@ -323,7 +323,7 @@  uint64_t helper_fexpand(uint32_t src2)
         s.l = src1;                                     \
         d.l = src2;                                     \
                                                         \
-        d.l = F(d.l, s.l);                              \
+        d.l = F(s.l, d.l);                              \
                                                         \
         return d.l;                                     \
     }