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 calculation of overflow for SH


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] target-mips: fix calculation of overflow for SHLL.PH and SHLL.QB
Date: Fri, 3 May 2013 11:50:53 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

On Sun, Apr 28, 2013 at 03:18:36AM +0200, Petar Jovanovic wrote:
> From: Petar Jovanovic <address@hidden>
> 
> This change corrects and simplifies how discard is calculated for shift
> left logical vector instructions. It is used to detect overflow and set bit
> 22 in the DSPControl register.
> 
> The existing tests (shll_ph.c, shll_qb.c) are extended with the corner cases
> that expose incorrectness in the previous implementation.
> 
> Signed-off-by: Petar Jovanovic <address@hidden>
> ---
>  target-mips/dsp_helper.c            |   30 ++++++------------------------
>  tests/tcg/mips/mips32-dsp/shll_ph.c |   33 ++++++++++++++++++++++++++++++++-
>  tests/tcg/mips/mips32-dsp/shll_qb.c |   23 +++++++++++++++++++++--
>  3 files changed, 59 insertions(+), 27 deletions(-)
> 
> diff --git a/target-mips/dsp_helper.c b/target-mips/dsp_helper.c
> index f975da0..805247d 100644
> --- a/target-mips/dsp_helper.c
> +++ b/target-mips/dsp_helper.c
> @@ -682,49 +682,31 @@ static inline uint8_t 
> mipsdsp_sat8_reduce_precision(uint16_t a,
>  
>  static inline uint8_t mipsdsp_lshift8(uint8_t a, uint8_t s, CPUMIPSState 
> *env)
>  {
> -    uint8_t sign;
>      uint8_t discard;
>  
> -    if (s == 0) {
> -        return a;
> -    } else {
> -        sign = (a >> 7) & 0x01;
> -        if (sign != 0) {
> -            discard = (((0x01 << (8 - s)) - 1) << s) |
> -                      ((a >> (6 - (s - 1))) & ((0x01 << s) - 1));
> -        } else {
> -            discard = a >> (6 - (s - 1));
> -        }
> +    if (s != 0) {
> +        discard = a >> (8 - s);
>  
>          if (discard != 0x00) {
>              set_DSPControl_overflow_flag(1, 22, env);
>          }
> -        return a << s;
>      }
> +    return a << s;
>  }
>  
>  static inline uint16_t mipsdsp_lshift16(uint16_t a, uint8_t s,
>                                          CPUMIPSState *env)
>  {
> -    uint8_t  sign;
>      uint16_t discard;
>  
> -    if (s == 0) {
> -        return a;
> -    } else {
> -        sign = (a >> 15) & 0x01;
> -        if (sign != 0) {
> -            discard = (((0x01 << (16 - s)) - 1) << s) |
> -                      ((a >> (14 - (s - 1))) & ((0x01 << s) - 1));
> -        } else {
> -            discard = a >> (14 - (s - 1));
> -        }
> +    if (s != 0) {
> +        discard = (int16_t)a >> (15 - s);
>  
>          if ((discard != 0x0000) && (discard != 0xFFFF)) {
>              set_DSPControl_overflow_flag(1, 22, env);
>          }
> -        return a << s;
>      }
> +    return a << s;
>  }
>  
>  
> diff --git a/tests/tcg/mips/mips32-dsp/shll_ph.c 
> b/tests/tcg/mips/mips32-dsp/shll_ph.c
> index b8f1ff5..5fa58cc 100644
> --- a/tests/tcg/mips/mips32-dsp/shll_ph.c
> +++ b/tests/tcg/mips/mips32-dsp/shll_ph.c
> @@ -11,7 +11,38 @@ int main()
>      resultdsp = 1;
>  
>      __asm
> -        ("shll.ph %0, %2, 0x0B\n\t"
> +        ("wrdsp $0\n\t"
> +         "shll.ph %0, %2, 0x0B\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rd), "=r"(dsp)
> +         : "r"(rt)
> +        );
> +    dsp = (dsp >> 22) & 0x01;
> +    assert(dsp == resultdsp);
> +    assert(rd  == result);
> +
> +    rt        = 0x7fff8000;
> +    result    = 0xfffe0000;
> +    resultdsp = 1;
> +
> +    __asm
> +        ("wrdsp $0\n\t"
> +         "shll.ph %0, %2, 0x01\n\t"
> +         "rddsp %1\n\t"
> +         : "=r"(rd), "=r"(dsp)
> +         : "r"(rt)
> +        );
> +    dsp = (dsp >> 22) & 0x01;
> +    assert(dsp == resultdsp);
> +    assert(rd  == result);
> +
> +    rt        = 0x00000001;
> +    result    = 0x00008000;
> +    resultdsp = 1;
> +
> +    __asm
> +        ("wrdsp $0\n\t"
> +         "shll.ph %0, %2, 0x0F\n\t"
>           "rddsp %1\n\t"
>           : "=r"(rd), "=r"(dsp)
>           : "r"(rt)
> diff --git a/tests/tcg/mips/mips32-dsp/shll_qb.c 
> b/tests/tcg/mips/mips32-dsp/shll_qb.c
> index 8c1b91c..729716d 100644
> --- a/tests/tcg/mips/mips32-dsp/shll_qb.c
> +++ b/tests/tcg/mips/mips32-dsp/shll_qb.c
> @@ -11,12 +11,14 @@ int main()
>      resultdsp = 0x00;
>  
>      __asm
> -        ("shll.qb %0, %2, 0x00\n\t"
> +        ("wrdsp $0\n\t"
> +         "shll.qb %0, %2, 0x00\n\t"
>           "rddsp   %1\n\t"
>           : "=r"(rd), "=r"(dsp)
>           : "r"(rt)
>          );
>      dsp = (dsp >> 22) & 0x01;
> +    assert(dsp == resultdsp);
>      assert(rd == result);
>  
>      rt     = 0x87654321;
> @@ -24,12 +26,29 @@ int main()
>      resultdsp = 0x01;
>  
>      __asm
> -        ("shll.qb %0, %2, 0x03\n\t"
> +        ("wrdsp $0\n\t"
> +         "shll.qb %0, %2, 0x03\n\t"
>           "rddsp   %1\n\t"
>           : "=r"(rd), "=r"(dsp)
>           : "r"(rt)
>          );
>      dsp = (dsp >> 22) & 0x01;
> +    assert(dsp == resultdsp);
> +    assert(rd == result);
> +
> +    rt     = 0x00000001;
> +    result = 0x00000080;
> +    resultdsp = 0x00;
> +
> +    __asm
> +        ("wrdsp $0\n\t"
> +         "shll.qb %0, %2, 0x07\n\t"
> +         "rddsp   %1\n\t"
> +         : "=r"(rd), "=r"(dsp)
> +         : "r"(rt)
> +        );
> +    dsp = (dsp >> 22) & 0x01;
> +    assert(dsp == resultdsp);
>      assert(rd == result);
>  
>      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]