diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/sparcv9/bits/atomic.h | 14 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/bits/atomic.h | 28 |
3 files changed, 39 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog index 418b9320d1..00f702735e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2013-01-23 David S. Miller <davem@davemloft.net> + + * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h + (__arch_compare_and_exchange_val_32_acq): Use %g0 as second + argument of CAS if possible. + * sysdeps/sparc/sparc64/bits/atomic.h + (__arch_compare_and_exchange_val_32_acq): Likewise. + (__arch_compare_and_exchange_val_64_acq): Likewise. + 2013-01-23 Pino Toscano <toscano.pino@tiscali.it> * sysdeps/unix/sysv/linux/ulimit.c: Moved to ... diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h index b1a89584f6..937d7a149f 100644 --- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h +++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h @@ -55,10 +55,16 @@ typedef uintmax_t uatomic_max_t; ({ \ __typeof (*(mem)) __acev_tmp; \ __typeof (mem) __acev_mem = (mem); \ - __asm __volatile ("cas [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ + if (__builtin_constant_p (oldval) && (oldval) == 0) \ + __asm __volatile ("cas [%3], %%g0, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ + else \ + __asm __volatile ("cas [%4], %2, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ __acev_tmp; }) /* This can be implemented if needed. */ diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h index 0afbb4ba5e..96611de42f 100644 --- a/sysdeps/sparc/sparc64/bits/atomic.h +++ b/sysdeps/sparc/sparc64/bits/atomic.h @@ -55,20 +55,32 @@ typedef uintmax_t uatomic_max_t; ({ \ __typeof (*(mem)) __acev_tmp; \ __typeof (mem) __acev_mem = (mem); \ - __asm __volatile ("cas [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ - "0" (newval) : "memory"); \ + if (__builtin_constant_p (oldval) && (oldval) == 0) \ + __asm __volatile ("cas [%3], %%g0, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ + else \ + __asm __volatile ("cas [%4], %2, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \ + "0" (newval) : "memory"); \ __acev_tmp; }) #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ ({ \ __typeof (*(mem)) __acev_tmp; \ __typeof (mem) __acev_mem = (mem); \ - __asm __volatile ("casx [%4], %2, %0" \ - : "=r" (__acev_tmp), "=m" (*__acev_mem) \ - : "r" ((long) (oldval)), "m" (*__acev_mem), \ - "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \ + if (__builtin_constant_p (oldval) && (oldval) == 0) \ + __asm __volatile ("casx [%3], %%g0, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "m" (*__acev_mem), "r" (__acev_mem), \ + "0" ((long) (newval)) : "memory"); \ + else \ + __asm __volatile ("casx [%4], %2, %0" \ + : "=r" (__acev_tmp), "=m" (*__acev_mem) \ + : "r" ((long) (oldval)), "m" (*__acev_mem), \ + "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \ __acev_tmp; }) #define atomic_exchange_acq(mem, newvalue) \ |