diff --git a/ChangeLog b/ChangeLog index e42182f..a9bc8fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-11-18 Ken Werner + + * sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h (atomic_full_barrier, + __arch_compare_and_exchange_val_32_acq): Use the atomic builtins + provided by GCC if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is defined. + 2010-04-14 Joseph Myers * libc-abis: Remove. diff --git a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h index b0586ea..979db9f 100644 --- a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h +++ b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h @@ -37,7 +37,12 @@ typedef uintmax_t uatomic_max_t; void __arm_link_error (void); -#ifdef __thumb2__ +/* Use the atomic builtins provided by GCC in case the backend provides + a pattern to do this efficiently. */ + +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +#define atomic_full_barrier() __sync_synchronize () +#elif defined __thumb2__ #define atomic_full_barrier() \ __asm__ __volatile__ \ ("movw\tip, #0x0fa0\n\t" \ @@ -64,11 +69,15 @@ void __arm_link_error (void); #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ ({ __arm_link_error (); oldval; }) +#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + __sync_val_compare_and_swap ((mem), (oldval), (newval)) + /* It doesn't matter what register is used for a_oldval2, but we must specify one to work around GCC PR rtl-optimization/21223. Otherwise it may cause a_oldval or a_tmp to be moved to a different register. */ -#ifdef __thumb2__ +#elif defined __thumb2__ /* Thumb-2 has ldrex/strex. However it does not have barrier instructions, so we still need to use the kernel helper. */ #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \