linux-mips
[Top] [All Lists]

[PATCH] atomic functions broken

To: linux-mips@linux-mips.org
Subject: [PATCH] atomic functions broken
From: Thomas Koeller <thomas.koeller@baslerweb.com>
Date: Wed, 22 Feb 2006 21:25:39 +0100
Organization: Basler AG
Original-recipient: rfc822;linux-mips@linux-mips.org
Sender: linux-mips-bounce@linux-mips.org
User-agent: KMail/1.6.2
The ll/sc versions of atomic_sub_if_positive(), and the corresponding 64-bit 
functions,
are broken. The value returned by those functions is always one, no matter what.


Signed-off-by: Thomas Koeller  <thomas.koeller@baslerweb.com>




diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 654b97d..472e855 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -247,15 +247,16 @@ static __inline__ int atomic_sub_if_posi
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     ll      %1, %2          # atomic_sub_if_positive\n"
-               "       subu    %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-               "       sc      %0, %2                                  \n"
-               "       beqzl   %0, 1b                                  \n"
+               "       subu    %1, %1, %3                              \n"
+               "       addi    %0, %1, 0                               \n"
+               "       bltz    %1, 1f                                  \n"
+               "       sc      %1, %2                                  \n"
+               "       beqzl   %1, 1b                                  \n"
                "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i)
                : "memory");
        } else if (cpu_has_llsc) {
                unsigned long temp;
@@ -263,15 +264,16 @@ static __inline__ int atomic_sub_if_posi
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     ll      %1, %2          # atomic_sub_if_positive\n"
-               "       subu    %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-               "       sc      %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       subu    %1, %1, %3                              \n"
+               "       addi    %0, %1, 0                               \n"
+               "       bltz    %1, 1f                                  \n"
+               "       sc      %1, %2                                  \n"
+               "       beqz    %1, 1b                                  \n"
                "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i)
                : "memory");
        } else {
                unsigned long flags;
@@ -595,15 +597,16 @@ static __inline__ long atomic64_sub_if_p
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     lld     %1, %2          # atomic64_sub_if_positive\n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-               "       scd     %0, %2                                  \n"
-               "       beqzl   %0, 1b                                  \n"
+               "       dsubu   %1, %1, %3                              \n"
+               "       daddi   %0, %1, 0                               \n"
+               "       bltz    %1, 1f                                  \n"
+               "       scd     %1, %2                                  \n"
+               "       beqzl   %1, 1b                                  \n"
                "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i)
                : "memory");
        } else if (cpu_has_llsc) {
                unsigned long temp;
@@ -611,15 +614,16 @@ static __inline__ long atomic64_sub_if_p
                __asm__ __volatile__(
                "       .set    mips3                                   \n"
                "1:     lld     %1, %2          # atomic64_sub_if_positive\n"
-               "       dsubu   %0, %1, %3                              \n"
-               "       bltz    %0, 1f                                  \n"
-               "       scd     %0, %2                                  \n"
-               "       beqz    %0, 1b                                  \n"
+               "       dsubu   %1, %1, %3                              \n"
+               "       daddi   %0, %1, 0                               \n"
+               "       bltz    %1, 1f                                  \n"
+               "       scd     %1, %2                                  \n"
+               "       beqz    %1, 1b                                  \n"
                "       sync                                            \n"
                "1:                                                     \n"
                "       .set    mips0                                   \n"
-               : "=&r" (result), "=&r" (temp), "=m" (v->counter)
-               : "Ir" (i), "m" (v->counter)
+               : "=&r" (result), "=&r" (temp), "+m" (v->counter)
+               : "Ir" (i)
                : "memory");
        } else {
                unsigned long flags;

-- 
--------------------------------------------------

Thomas Koeller, Software Development
Basler Vision Technologies

thomas dot koeller at baslerweb dot com
http://www.baslerweb.com

==============================


<Prev in Thread] Current Thread [Next in Thread>