diff options
author | David S. Miller <davem@davemloft.net> | 2013-01-23 11:27:24 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-23 11:27:24 -0800 |
commit | bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a (patch) | |
tree | b2deb8c9c341212727f5c04750c5cc6401635698 /sysdeps | |
parent | 67b3f58c83d4ffc29ab939e3d0bbeb9fb38103e7 (diff) | |
download | glibc-bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a.tar glibc-bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a.tar.gz glibc-bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a.tar.bz2 glibc-bae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a.zip |
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.
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/sparc/sparc32/sparcv9/bits/atomic.h | 14 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/bits/atomic.h | 28 |
2 files changed, 30 insertions, 12 deletions
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) \ |