From bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 23 Jan 2013 11:27:24 -0800 Subject: Add a minor 'cas' atomic optimization on sparc. * 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. --- sysdeps/sparc/sparc32/sparcv9/bits/atomic.h | 14 ++++++++++---- sysdeps/sparc/sparc64/bits/atomic.h | 28 ++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'sysdeps') 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) \ -- cgit 1.4.1