Patchwork target-mips: Fix for helpers for EXTR_* instructions

login
register
mail settings
Submitter Petar Jovanovic
Date Dec. 10, 2012, 3:28 p.m.
Message ID <1355153297-30533-1-git-send-email-petar.jovanovic@rt-rk.com>
Download mbox | patch
Permalink /patch/204941/
State New
Headers show

Comments

Petar Jovanovic - Dec. 10, 2012, 3:28 p.m.
From: Petar Jovanovic <petarj@mips.com>

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 <petarj@mips.com>
---
 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(-)
Aurelien Jarno - Jan. 1, 2013, 10:13 a.m.
On Mon, Dec 10, 2012 at 04:28:17PM +0100, Petar Jovanovic wrote:
> From: Petar Jovanovic <petarj@mips.com>
> 
> 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 <petarj@mips.com>
> ---
>  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.

Patch

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;
 }