qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] target-mips: Fix for helpers for EXTR_* instruc


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] target-mips: Fix for helpers for EXTR_* instructions
Date: Tue, 1 Jan 2013 11:13:18 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

On Mon, Dec 10, 2012 at 04:28:17PM +0100, Petar Jovanovic wrote:
> From: Petar Jovanovic <address@hidden>
> 
> The change removes some unnecessary and incorrect code for EXTR_S.H.
> Further, it corrects the mask for shift value in the EXTR_ instructions. It 
> also
> extends the existing tests so they trigger the issues corrected with the 
> change.
> 
> Signed-off-by: Petar Jovanovic <address@hidden>
> ---
>  target-mips/dsp_helper.c               |   45 +++++++------------------------
>  tests/tcg/mips/mips32-dsp/extr_r_w.c   |   23 ++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extr_rs_w.c  |   23 ++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extr_s_h.c   |   23 ++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extr_w.c     |   23 ++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extrv_r_w.c  |   25 +++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extrv_rs_w.c |   25 +++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extrv_s_h.c  |   17 ++++++++++++
>  tests/tcg/mips/mips32-dsp/extrv_w.c    |   26 ++++++++++++++++++
>  9 files changed, 195 insertions(+), 35 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 14daf91..a54809b 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -484,35 +484,6 @@ static inline uint8_t mipsdsp_rrshift1_sub_u8(uint8_t a, 
> uint8_t b)
>      return (temp >> 1) & 0x00FF;
>  }
>  
> -static inline int64_t mipsdsp_rashift_short_acc(int32_t ac,
> -                                                int32_t shift,
> -                                                CPUMIPSState *env)
> -{
> -    int32_t sign, temp31;
> -    int64_t temp, acc;
> -
> -    sign = (env->active_tc.HI[ac] >> 31) & 0x01;
> -    acc = ((int64_t)env->active_tc.HI[ac] << 32) |
> -          ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
> -    if (shift == 0) {
> -        temp = acc;
> -    } else {
> -        if (sign == 0) {
> -            temp = (((int64_t)0x01 << (32 - shift + 1)) - 1) & (acc >> 
> shift);
> -        } else {
> -            temp = ((((int64_t)0x01 << (shift + 1)) - 1) << (32 - shift)) |
> -                   (acc >> shift);
> -        }
> -    }
> -
> -    temp31 = (temp >> 31) & 0x01;
> -    if (sign != temp31) {
> -        set_DSPControl_overflow_flag(1, 23, env);
> -    }
> -
> -    return temp;
> -}
> -
>  /*  128 bits long. p[0] is LO, p[1] is HI. */
>  static inline void mipsdsp_rndrashift_short_acc(int64_t *p,
>                                                  int32_t ac,
> @@ -3407,7 +3378,7 @@ target_ulong helper_extr_w(target_ulong ac, 
> target_ulong shift,
>      int32_t tempI;
>      int64_t tempDL[2];
>  
> -    shift = shift & 0x0F;
> +    shift = shift & 0x1F;
>  
>      mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env);
>      if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> @@ -3435,7 +3406,7 @@ target_ulong helper_extr_r_w(target_ulong ac, 
> target_ulong shift,
>  {
>      int64_t tempDL[2];
>  
> -    shift = shift & 0x0F;
> +    shift = shift & 0x1F;
>  
>      mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env);
>      if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> @@ -3462,7 +3433,7 @@ target_ulong helper_extr_rs_w(target_ulong ac, 
> target_ulong shift,
>      int32_t tempI, temp64;
>      int64_t tempDL[2];
>  
> -    shift = shift & 0x0F;
> +    shift = shift & 0x1F;
>  
>      mipsdsp_rndrashift_short_acc(tempDL, ac, shift, env);
>      if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> @@ -3645,11 +3616,15 @@ target_ulong helper_dextr_rs_l(target_ulong ac, 
> target_ulong shift,
>  target_ulong helper_extr_s_h(target_ulong ac, target_ulong shift,
>                               CPUMIPSState *env)
>  {
> -    int64_t temp;
> +    int64_t temp, acc;
> +
> +    shift = shift & 0x1F;
> +
> +    acc = ((int64_t)env->active_tc.HI[ac] << 32) |
> +          ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
>  
> -    shift = shift & 0x0F;
> +    temp = acc >> shift;
>  
> -    temp = mipsdsp_rashift_short_acc(ac, shift, env);
>      if (temp > (int64_t)0x7FFF) {
>          temp = 0x00007FFF;
>          set_DSPControl_overflow_flag(1, 23, env);
> diff --git a/tests/tcg/mips/mips32-dsp/extr_r_w.c 
> b/tests/tcg/mips/mips32-dsp/extr_r_w.c
> index 0beeefd..02e0224 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_r_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_r_w.c
> @@ -44,5 +44,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("mthi %2, $ac1\n\t"
> +         "mtlo %3, $ac1\n\t"
> +         "extr_r.w %0, $ac1, 0x1F\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "=r"(dsp)
> +         : "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extr_rs_w.c 
> b/tests/tcg/mips/mips32-dsp/extr_rs_w.c
> index 24c748d..c3a22ee 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_rs_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_rs_w.c
> @@ -44,5 +44,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("mthi %2, $ac1\n\t"
> +         "mtlo %3, $ac1\n\t"
> +         "extr_rs.w %0, $ac1, 0x1F\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "=r"(dsp)
> +         : "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extr_s_h.c 
> b/tests/tcg/mips/mips32-dsp/extr_s_h.c
> index b212913..9bc2a63 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_s_h.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_s_h.c
> @@ -59,5 +59,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dsp */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0x123;
> +    acl = 0x87654321;
> +    result = 0x1238;
> +    __asm
> +        ("mthi %2, $ac1\n\t"
> +         "mtlo %3, $ac1\n\t"
> +         "extr_s.h %0, $ac1, 28\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "=r"(dsp)
> +         : "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extr_w.c 
> b/tests/tcg/mips/mips32-dsp/extr_w.c
> index 02ab9ec..bd6b0b9 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_w.c
> @@ -44,5 +44,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("mthi %2, $ac1\n\t"
> +         "mtlo %3, $ac1\n\t"
> +         "extr.w %0, $ac1, 0x1F\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "=r"(dsp)
> +         : "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extrv_r_w.c 
> b/tests/tcg/mips/mips32-dsp/extrv_r_w.c
> index 005807b..2403b3a 100644
> --- a/tests/tcg/mips/mips32-dsp/extrv_r_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extrv_r_w.c
> @@ -50,5 +50,30 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    rs = 31;
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("wrdsp %1, 0x01\n\t"
> +         "mthi %3, $ac1\n\t"
> +         "mtlo %4, $ac1\n\t"
> +         "extrv_r.w %0, $ac1, %2\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "+r"(dsp)
> +         : "r"(rs), "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extrv_rs_w.c 
> b/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
> index c2d8513..ccceeb9 100644
> --- a/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extrv_rs_w.c
> @@ -48,5 +48,30 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    rs = 0x1F;
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("wrdsp %1, 0x01\n\t"
> +         "mthi %3, $ac1\n\t"
> +         "mtlo %4, $ac1\n\t"
> +         "extrv_rs.w %0, $ac1, %2\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "+r"(dsp)
> +         : "r"(rs), "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extrv_s_h.c 
> b/tests/tcg/mips/mips32-dsp/extrv_s_h.c
> index 8c13b5e..feac3e2 100644
> --- a/tests/tcg/mips/mips32-dsp/extrv_s_h.c
> +++ b/tests/tcg/mips/mips32-dsp/extrv_s_h.c
> @@ -67,5 +67,22 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    rs = 0x1C;
> +    ach = 0x123;
> +    acl = 0x87654321;
> +    result = 0x1238;
> +    __asm
> +        ("wrdsp %1, 0x01\n\t"
> +         "mthi %3, $ac1\n\t"
> +         "mtlo %4, $ac1\n\t"
> +         "extrv_s.h %0, $ac1, %2\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "+r"(dsp)
> +         : "r"(rs), "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
>      return 0;
>  }
> diff --git a/tests/tcg/mips/mips32-dsp/extrv_w.c 
> b/tests/tcg/mips/mips32-dsp/extrv_w.c
> index 9cb493d..9e8b238 100644
> --- a/tests/tcg/mips/mips32-dsp/extrv_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extrv_w.c
> @@ -50,5 +50,31 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    rs = 31;
> +    ach = 0x3fffffff;
> +    acl = 0x2bcdef01;
> +    result = 0x7ffffffe;
> +    __asm
> +        ("wrdsp %1, 0x01\n\t"
> +         "mthi %3, $ac1\n\t"
> +         "mtlo %4, $ac1\n\t"
> +         "extrv.w %0, $ac1, %2\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rt), "+r"(dsp)
> +         : "r"(rs), "r"(ach), "r"(acl)
> +        );
> +    dsp = (dsp >> 23) & 0x01;
> +    assert(dsp == 0);
> +    assert(result == rt);
> +
> +
>      return 0;
>  }

Thanks, applied.


-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net



reply via email to

[Prev in Thread] Current Thread [Next in Thread]