Patchwork [38/48] target-arm: fix neon vrshl instruction

login
register
mail settings
Submitter Riku Voipio
Date March 26, 2010, 4:06 p.m.
Message ID <ba0d10a3afaf17e4798aa5e5c0ae086546ad82b4.1269617187.git.riku.voipio@nokia.com>
Download mbox | patch
Permalink /patch/48676/
State New
Headers show

Comments

Riku Voipio - March 26, 2010, 4:06 p.m.
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 |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)
Nathan Froyd - March 26, 2010, 5:26 p.m.
On Fri, Mar 26, 2010 at 04:06:58PM +0000, Riku Voipio wrote:
> +uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
> +{
> +    int8_t shift = (int8_t)shiftop;
> +    if (shift >= 32 || shift < -32) {
> +        val = 0;
> +    } else if (shift == -32) {
> +        val >>= shift - 1;
           ^^^^^^^^^^^^^^^^^

This looks wrong.  Compare the equivalent case for 64-bit:

>  uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
>      } else if (shift == -64) {
>          /* Rounding a 1-bit result just preserves that bit.  */
>          val >>= 63;

Bonus points for factoring out the duplicated 32/64-bit code.

-Nathan

Patch

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index ec1964f..0df13f5 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -547,20 +547,33 @@  uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
     }} while (0)
 NEON_VOP(rshl_u8, neon_u8, 4)
 NEON_VOP(rshl_u16, neon_u16, 2)
-NEON_VOP(rshl_u32, neon_u32, 1)
 #undef NEON_FN
 
+uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
+{
+    int8_t shift = (int8_t)shiftop;
+    if (shift >= 32 || shift < -32) {
+        val = 0;
+    } else if (shift == -32) {
+        val >>= shift - 1;
+    } else if (shift < 0) {
+        val = ((uint64_t)val + (1 << (-1 - shift))) >> -shift;
+    } else {
+        val <<= shift;
+    }
+    return val;
+}
+
 uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
 {
     int8_t shift = (uint8_t)shiftop;
-    if (shift >= 64 || shift < 64) {
+    if (shift >= 64 || shift < -64) {
         val = 0;
     } else if (shift == -64) {
         /* Rounding a 1-bit result just preserves that bit.  */
         val >>= 63;
     } if (shift < 0) {
         val = (val + ((uint64_t)1 << (-1 - shift))) >> -shift;
-        val >>= -shift;
     } else {
         val <<= shift;
     }