diff mbox

target-mips: Fix incorrect shift for SHILO and SHILOV

Message ID 1354632583-22403-1-git-send-email-petar.jovanovic@rt-rk.com
State New
Headers show

Commit Message

Petar Jovanovic Dec. 4, 2012, 2:49 p.m. UTC
From: Petar Jovanovic <petarj@mips.com>

helper_shilo has not been shifting an accumulator value correctly for negative
values in 'shift' field. Minor optimization for shift=0 case.
This change also adds tests that will trigger issue and check for regressions.

Signed-off-by: Petar Jovanovic <petarj@mips.com>
---
 target-mips/dsp_helper.c           |   16 ++++++++--------
 tests/tcg/mips/mips32-dsp/shilo.c  |   18 ++++++++++++++++++
 tests/tcg/mips/mips32-dsp/shilov.c |   20 ++++++++++++++++++++
 3 files changed, 46 insertions(+), 8 deletions(-)

Comments

Blue Swirl Dec. 4, 2012, 7 p.m. UTC | #1
On Tue, Dec 4, 2012 at 2:49 PM, Petar Jovanovic
<petar.jovanovic@rt-rk.com> wrote:
> From: Petar Jovanovic <petarj@mips.com>
>
> helper_shilo has not been shifting an accumulator value correctly for negative
> values in 'shift' field. Minor optimization for shift=0 case.
> This change also adds tests that will trigger issue and check for regressions.
>
> Signed-off-by: Petar Jovanovic <petarj@mips.com>
> ---
>  target-mips/dsp_helper.c           |   16 ++++++++--------
>  tests/tcg/mips/mips32-dsp/shilo.c  |   18 ++++++++++++++++++
>  tests/tcg/mips/mips32-dsp/shilov.c |   20 ++++++++++++++++++++
>  3 files changed, 46 insertions(+), 8 deletions(-)
>
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index e7949c2..f8a7a9f 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -3814,17 +3814,17 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
>
>      rs5_0 = rs & 0x3F;
>      rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
> -    rs5_0 = MIPSDSP_ABS(rs5_0);
> +
> +    if (rs5_0 == 0)
> +        return;

The check should be moved to translation time so that the call to this
helper is not generated at all.

In general, please add missing braces, read CODING_STYLE and use checkpatch.pl.

> +
>      acc   = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) |
>              ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
> -    if (rs5_0 == 0) {
> -        temp = acc;
> +
> +    if (rs5_0 > 0) {
> +        temp = acc >> MIPSDSP_ABS(rs5_0);
>      } else {
> -        if (rs5_0 > 0) {
> -            temp = acc >> rs5_0;
> -        } else {
> -            temp = acc << rs5_0;
> -        }
> +        temp = acc << MIPSDSP_ABS(rs5_0);
>      }
>
>      env->active_tc.HI[ac] = (target_ulong)(int32_t)((temp & MIPSDSP_LHI) >> 32);
> diff --git a/tests/tcg/mips/mips32-dsp/shilo.c b/tests/tcg/mips/mips32-dsp/shilo.c
> index b686616..ce8ebc6 100644
> --- a/tests/tcg/mips/mips32-dsp/shilo.c
> +++ b/tests/tcg/mips/mips32-dsp/shilo.c
> @@ -23,5 +23,23 @@ int main()
>      assert(ach == resulth);
>      assert(acl == resultl);
>
> +
> +    ach = 0x1;
> +    acl = 0x80000000;
> +
> +    resulth = 0x3;
> +    resultl = 0x0;
> +
> +    __asm
> +        ("mthi %0, $ac1\n\t"
> +         "mtlo %1, $ac1\n\t"
> +         "shilo $ac1, -1\n\t"
> +         "mfhi %0, $ac1\n\t"
> +         "mflo %1, $ac1\n\t"
> +         : "+r"(ach), "+r"(acl)
> +        );
> +    assert(ach == resulth);
> +    assert(acl == resultl);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/shilov.c b/tests/tcg/mips/mips32-dsp/shilov.c
> index f186032..e1d6cea 100644
> --- a/tests/tcg/mips/mips32-dsp/shilov.c
> +++ b/tests/tcg/mips/mips32-dsp/shilov.c
> @@ -25,5 +25,25 @@ int main()
>      assert(ach == resulth);
>      assert(acl == resultl);
>
> +
> +    rs  = 0xffffffff;
> +    ach = 0x1;
> +    acl = 0x80000000;
> +
> +    resulth = 0x3;
> +    resultl = 0x0;
> +
> +    __asm
> +        ("mthi %0, $ac1\n\t"
> +         "mtlo %1, $ac1\n\t"
> +         "shilov $ac1, %2\n\t"
> +         "mfhi %0, $ac1\n\t"
> +         "mflo %1, $ac1\n\t"
> +         : "+r"(ach), "+r"(acl)
> +         : "r"(rs)
> +        );
> +    assert(ach == resulth);
> +    assert(acl == resultl);
> +
>      return 0;
>  }
> --
> 1.7.5.4
>
>
Richard Henderson Dec. 4, 2012, 7:43 p.m. UTC | #2
On 2012-12-04 13:00, Blue Swirl wrote:
>> > +    if (rs5_0 == 0)
>> > +        return;
> The check should be moved to translation time so that the call to this
> helper is not generated at all.

No, we'd do that only if this value were an immediate.
Branch over helper is not an optimization for an edge case runtime value.


r~
Jovanovic, Petar Dec. 4, 2012, 7:48 p.m. UTC | #3
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index e7949c2..f8a7a9f 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -3814,17 +3814,17 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
>
>      rs5_0 = rs & 0x3F;
>      rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
> -    rs5_0 = MIPSDSP_ABS(rs5_0);
> +
> +    if (rs5_0 == 0)
> +        return;

> The check should be moved to translation time so that the call to this
> helper is not generated at all.

This case is not likely so generation of unnecessary call is unlikely too.
Let me know what you think.

I will add the missing braces and I can also get rid of
MIPSDSP_ABS(rs5_0).

Petar
Blue Swirl Dec. 4, 2012, 7:52 p.m. UTC | #4
On Tue, Dec 4, 2012 at 7:43 PM, Richard Henderson <rth@twiddle.net> wrote:
> On 2012-12-04 13:00, Blue Swirl wrote:
>>> > +    if (rs5_0 == 0)
>>> > +        return;
>> The check should be moved to translation time so that the call to this
>> helper is not generated at all.
>
> No, we'd do that only if this value were an immediate.
> Branch over helper is not an optimization for an edge case runtime value.

Right, for some reason I thought rs was a register number, sorry.

>
>
> r~
Blue Swirl Dec. 4, 2012, 7:54 p.m. UTC | #5
On Tue, Dec 4, 2012 at 7:48 PM, Jovanovic, Petar <petarj@mips.com> wrote:
>> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
>> index e7949c2..f8a7a9f 100644
>> --- a/target-mips/dsp_helper.c
>> +++ b/target-mips/dsp_helper.c
>> @@ -3814,17 +3814,17 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
>>
>>      rs5_0 = rs & 0x3F;
>>      rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
>> -    rs5_0 = MIPSDSP_ABS(rs5_0);
>> +
>> +    if (rs5_0 == 0)
>> +        return;
>
>> The check should be moved to translation time so that the call to this
>> helper is not generated at all.
>
> This case is not likely so generation of unnecessary call is unlikely too.
> Let me know what you think.

Sorry, I was confused.

> I will add the missing braces and I can also get rid of
> MIPSDSP_ABS(rs5_0).

OK.

>
> Petar
Andreas Färber Dec. 4, 2012, 9:13 p.m. UTC | #6
Am 04.12.2012 20:48, schrieb Jovanovic, Petar:
>> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
>> index e7949c2..f8a7a9f 100644
>> --- a/target-mips/dsp_helper.c
>> +++ b/target-mips/dsp_helper.c
>> @@ -3814,17 +3814,17 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
>>
>>      rs5_0 = rs & 0x3F;
>>      rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
>> -    rs5_0 = MIPSDSP_ABS(rs5_0);
>> +
>> +    if (rs5_0 == 0)
>> +        return;
> 
>> The check should be moved to translation time so that the call to this
>> helper is not generated at all.
> 
> This case is not likely so generation of unnecessary call is unlikely too.
> Let me know what you think.

FWIW you could use our unlikely() macro then to aid branch prediction.

Andreas
Jovanovic, Petar Dec. 4, 2012, 11:34 p.m. UTC | #7
> From: Andreas Färber [afaerber@suse.de]
>FWIW you could use our unlikely() macro then to aid branch prediction.

Just did. Thanks.

Petar
diff mbox

Patch

diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
index e7949c2..f8a7a9f 100644
--- a/target-mips/dsp_helper.c
+++ b/target-mips/dsp_helper.c
@@ -3814,17 +3814,17 @@  void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
 
     rs5_0 = rs & 0x3F;
     rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
-    rs5_0 = MIPSDSP_ABS(rs5_0);
+
+    if (rs5_0 == 0)
+        return;
+
     acc   = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) |
             ((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
-    if (rs5_0 == 0) {
-        temp = acc;
+
+    if (rs5_0 > 0) {
+        temp = acc >> MIPSDSP_ABS(rs5_0);
     } else {
-        if (rs5_0 > 0) {
-            temp = acc >> rs5_0;
-        } else {
-            temp = acc << rs5_0;
-        }
+        temp = acc << MIPSDSP_ABS(rs5_0);
     }
 
     env->active_tc.HI[ac] = (target_ulong)(int32_t)((temp & MIPSDSP_LHI) >> 32);
diff --git a/tests/tcg/mips/mips32-dsp/shilo.c b/tests/tcg/mips/mips32-dsp/shilo.c
index b686616..ce8ebc6 100644
--- a/tests/tcg/mips/mips32-dsp/shilo.c
+++ b/tests/tcg/mips/mips32-dsp/shilo.c
@@ -23,5 +23,23 @@  int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
+
+    ach = 0x1;
+    acl = 0x80000000;
+
+    resulth = 0x3;
+    resultl = 0x0;
+
+    __asm
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "shilo $ac1, -1\n\t"
+         "mfhi %0, $ac1\n\t"
+         "mflo %1, $ac1\n\t"
+         : "+r"(ach), "+r"(acl)
+        );
+    assert(ach == resulth);
+    assert(acl == resultl);
+
     return 0;
 }
diff --git a/tests/tcg/mips/mips32-dsp/shilov.c b/tests/tcg/mips/mips32-dsp/shilov.c
index f186032..e1d6cea 100644
--- a/tests/tcg/mips/mips32-dsp/shilov.c
+++ b/tests/tcg/mips/mips32-dsp/shilov.c
@@ -25,5 +25,25 @@  int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
+
+    rs  = 0xffffffff;
+    ach = 0x1;
+    acl = 0x80000000;
+
+    resulth = 0x3;
+    resultl = 0x0;
+
+    __asm
+        ("mthi %0, $ac1\n\t"
+         "mtlo %1, $ac1\n\t"
+         "shilov $ac1, %2\n\t"
+         "mfhi %0, $ac1\n\t"
+         "mflo %1, $ac1\n\t"
+         : "+r"(ach), "+r"(acl)
+         : "r"(rs)
+        );
+    assert(ach == resulth);
+    assert(acl == resultl);
+
     return 0;
 }