diff mbox

[44/48] target-arm: fix neon v(q)(r)shrn instructions

Message ID 912247d64af6b6f7aba2cb3b7d57acee33dc6106.1269617187.git.riku.voipio@nokia.com
State New
Headers show

Commit Message

Riku Voipio March 26, 2010, 4:07 p.m. UTC
From: Juha Riihimäki <juha.riihimaki@nokia.com>

Signed-Off-By: Riku Voipio <riku.voipio@nokia.com>
Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com>
---
 target-arm/neon_helper.c |   23 +++++++++++++++++++++--
 target-arm/translate.c   |   19 ++++++++++++++-----
 2 files changed, 35 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 6464317..7cef783 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -509,9 +509,28 @@  uint64_t HELPER(neon_shl_s64)(uint64_t valop, uint64_t shiftop)
     }} while (0)
 NEON_VOP(rshl_s8, neon_s8, 4)
 NEON_VOP(rshl_s16, neon_s16, 2)
-NEON_VOP(rshl_s32, neon_s32, 1)
 #undef NEON_FN
 
+uint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop)
+{
+    int8_t shift =(int8_t)shiftop;
+    int32_t val = valop;
+    if (shift >= 32) {
+        val = 0;
+    } else if (shift < -32) {
+        val >>= 31;
+    } else if (shift == -32) {
+        val >>= 31;
+        val++;
+        val >>= 1;
+    } else if (shift < 0) {
+        val = ((int64_t)val + (1 << (-1 - shift))) >> -shift;
+    } else {
+        val <<= shift;
+    }
+    return val;
+}
+
 uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
 {
     int8_t shift = (int8_t)shiftop;
@@ -520,7 +539,7 @@  uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
         val = 0;
     } else if (shift < -64) {
         val >>= 63;
-    } else if (shift == -63) {
+    } else if (shift == -64) {
         val >>= 63;
         val++;
         val >>= 1;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index de2ea92..92c8a1a 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4781,6 +4781,7 @@  static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                     abort();
                 }
 
+                TCGV_UNUSED(tmp5);
                 for (pass = 0; pass < 2; pass++) {
                     if (size == 3) {
                         neon_load_reg64(cpu_V0, rm + pass);
@@ -4812,18 +4813,26 @@  static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
                         dead_tmp(tmp);
                         dead_tmp(tmp3);
                     }
-                    tmp = new_tmp();
+                    tmp4 = new_tmp();
                     if (op == 8) {
                         if (u) { /* VQSHRUN / VQRSHRUN */
-                            gen_neon_unarrow_sats(size - 1, tmp, cpu_V0);
+                            gen_neon_unarrow_sats(size - 1, tmp4, cpu_V0);
                         } else { /* VSHRN / VRSHRN */
-                            gen_neon_narrow(size - 1, tmp, cpu_V0);
+                            gen_neon_narrow(size - 1, tmp4, cpu_V0);
                         }
                     } else { /* VQSHRN / VQRSHRN */
-                        gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
+                        if (u) {
+                            gen_neon_narrow_satu(size - 1, tmp4, cpu_V0);
+                        } else {
+                            gen_neon_narrow_sats(size - 1, tmp4, cpu_V0);
+                        }
+                    }
+                    if (!pass) {
+                        tmp5 = tmp4;
                     }
-                    neon_store_reg(rd, pass, tmp);
                 } /* for pass */
+                neon_store_reg(rd, 0, tmp5);
+                neon_store_reg(rd, 1, tmp4);
                 if (size == 3) {
                     tcg_temp_free_i64(tmp64);
                 } else {