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 rndrashift_short_acc and code


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] target-mips: fix rndrashift_short_acc and code for EXTR_ instructions
Date: Sun, 17 Mar 2013 11:10:10 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

On Fri, Mar 15, 2013 at 06:56:19PM +0100, Petar Jovanovic wrote:
> From: Petar Jovanovic <address@hidden>
> 
> Fix for rndrashift_short_acc to set correct value to higher 64 bits.
> This change also corrects conditions when bit 23 of the DSPControl register
> is set.
> 
> The existing test files have been extended with several examples that
> trigger the issues. One bug/example in the test file for EXTR_RS_W has been
> found and reported by Klaus Peichl.
> 
> Signed-off-by: Petar Jovanovic <address@hidden>
> ---
>  target-mips/dsp_helper.c              |   23 +++++++----------
>  tests/tcg/mips/mips32-dsp/extr_r_w.c  |   23 +++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extr_rs_w.c |   46 
> +++++++++++++++++++++++++++++++++
>  tests/tcg/mips/mips32-dsp/extr_w.c    |   23 +++++++++++++++++
>  4 files changed, 101 insertions(+), 14 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index 472be35..c7df595 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -517,13 +517,8 @@ static inline void mipsdsp_rndrashift_short_acc(int64_t 
> *p,
>  
>      acc = ((int64_t)env->active_tc.HI[ac] << 32) |
>            ((int64_t)env->active_tc.LO[ac] & 0xFFFFFFFF);
> -    if (shift == 0) {
> -        p[0] = acc << 1;
> -        p[1] = (acc >> 63) & 0x01;
> -    } else {
> -        p[0] = acc >> (shift - 1);
> -        p[1] = 0;
> -    }
> +    p[0] = (shift == 0) ? (acc << 1) : (acc >> (shift - 1));
> +    p[1] = (acc >> 63) & 0x01;
>  }
>  
>  /* 128 bits long. p[0] is LO, p[1] is HI */
> @@ -3161,8 +3156,8 @@ target_ulong helper_extr_w(target_ulong ac, 
> target_ulong shift,
>          tempDL[1] += 1;
>      }
>  
> -    if ((!(tempDL[1] == 0 && (tempDL[0] & MIPSDSP_LHI) == 0x00)) &&
> -        (!(tempDL[1] == 1 && (tempDL[0] & MIPSDSP_LHI) == MIPSDSP_LHI))) {
> +    if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> +        ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != 
> MIPSDSP_LHI)) {
>          set_DSPControl_overflow_flag(1, 23, env);
>      }
>  
> @@ -3187,8 +3182,8 @@ target_ulong helper_extr_r_w(target_ulong ac, 
> target_ulong shift,
>          tempDL[1] += 1;
>      }
>  
> -    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> -        (tempDL[1] != 1 && (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
> +    if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> +        ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != 
> MIPSDSP_LHI)) {
>          set_DSPControl_overflow_flag(1, 23, env);
>      }
>  
> @@ -3214,9 +3209,9 @@ target_ulong helper_extr_rs_w(target_ulong ac, 
> target_ulong shift,
>      }
>      tempI = tempDL[0] >> 1;
>  
> -    if ((tempDL[1] != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> -        (tempDL[1] != 1 || (tempDL[0] & MIPSDSP_LHI) != MIPSDSP_LHI)) {
> -        temp64 = tempDL[1];
> +    if (((tempDL[1] & 0x01) != 0 || (tempDL[0] & MIPSDSP_LHI) != 0) &&
> +        ((tempDL[1] & 0x01) != 1 || (tempDL[0] & MIPSDSP_LHI) != 
> MIPSDSP_LHI)) {
> +        temp64 = tempDL[1] & 0x01;
>          if (temp64 == 0) {
>              tempI = 0x7FFFFFFF;
>          } else {
> diff --git a/tests/tcg/mips/mips32-dsp/extr_r_w.c 
> b/tests/tcg/mips/mips32-dsp/extr_r_w.c
> index 02e0224..489c193 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_r_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_r_w.c
> @@ -67,5 +67,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0xFFFFFFFF;
> +    acl = 0xFFFFFFFF;
> +    result = 0;
> +    __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 c3a22ee..f9d2ed6 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_rs_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_rs_w.c
> @@ -67,5 +67,51 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0x80000000;
> +    acl = 0x00000000;
> +    result = 0x80000000;
> +    __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 == 1);
> +    assert(result == rt);
> +
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0xFFFFFFFF;
> +    acl = 0xFFFFFFFF;
> +    result = 0;
> +    __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_w.c 
> b/tests/tcg/mips/mips32-dsp/extr_w.c
> index bd6b0b9..cf92614 100644
> --- a/tests/tcg/mips/mips32-dsp/extr_w.c
> +++ b/tests/tcg/mips/mips32-dsp/extr_w.c
> @@ -67,5 +67,28 @@ int main()
>      assert(dsp == 0);
>      assert(result == rt);
>  
> +    /* Clear dspcontrol */
> +    dsp = 0;
> +    __asm
> +        ("wrdsp %0\n\t"
> +         :
> +         : "r"(dsp)
> +        );
> +
> +    ach = 0xFFFFFFFF;
> +    acl = 0xFFFFFFFF;
> +    result = 0xFFFFFFFF;
> +    __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;
>  }

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]