From e50d89fa6009e8c60dee72488e1decd8c8c77f54 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 5 Sep 2012 08:55:04 +0400 Subject: [PATCH] Implement compare_double_and_swap_double for SunCC/x86 (Tested only with Sun C 5.11 SunOS_i386.) * src/atomic_ops/sysdeps/sunc/x86.h (AO_compare_double_and_swap_double_full): Implement (define only if AO_NO_CMPXCHG8B unset) using same algorithm as for gcc/x86 non-PIC. --- src/atomic_ops/sysdeps/sunc/x86.h | 55 ++++++++++++++------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/src/atomic_ops/sysdeps/sunc/x86.h b/src/atomic_ops/sysdeps/sunc/x86.h index 45f1d4a..1b0850c 100644 --- a/src/atomic_ops/sysdeps/sunc/x86.h +++ b/src/atomic_ops/sysdeps/sunc/x86.h @@ -162,41 +162,24 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, } #define AO_HAVE_fetch_compare_and_swap_full -#if 0 -/* FIXME: not tested (and probably wrong). Besides, */ -/* it tickles a bug in Sun C 5.10 (when optimizing). */ -/* Returns nonzero if the comparison succeeded. */ -/* Really requires at least a Pentium. */ -AO_INLINE int -AO_compare_double_and_swap_double_full(volatile AO_double_t *addr, - AO_t old_val1, AO_t old_val2, - AO_t new_val1, AO_t new_val2) -{ - char result; -#if __PIC__ - /* If PIC is turned on, we can't use %ebx as it is reserved for the - GOT pointer. We can save and restore %ebx because GCC won't be - using it for anything else (such as any of the m operands) */ - __asm__ __volatile__("pushl %%ebx;" /* save ebx used for PIC GOT ptr */ - "movl %6,%%ebx;" /* move new_val1 to %ebx */ - "lock; cmpxchg8b %0; setz %1;" - "pop %%ebx;" /* restore %ebx */ - : "=m"(*addr), "=a"(result) - : "m"(*addr), "d" (old_val2), "a" (old_val1), - "c" (new_val2), "m" (new_val1) : "memory"); -#else - /* We can't just do the same thing in non-PIC mode, because GCC - * might be using %ebx as the memory operand. We could have ifdef'd - * in a clobber, but there's no point doing the push/pop if we don't - * have to. */ - __asm__ __volatile__("lock; cmpxchg8b %0; setz %1;" - : "=m"(*addr), "=a"(result) - : /* "m"(*addr), */ "d" (old_val2), "a" (old_val1), - "c" (new_val2), "b" (new_val1) : "memory"); -#endif - return (int) result; -} -#define AO_HAVE_compare_double_and_swap_double_full -#endif +#ifndef AO_NO_CMPXCHG8B + /* Returns nonzero if the comparison succeeded. */ + /* Really requires at least a Pentium. */ + AO_INLINE int + AO_compare_double_and_swap_double_full(volatile AO_double_t *addr, + AO_t old_val1, AO_t old_val2, + AO_t new_val1, AO_t new_val2) + { + char result; + + __asm__ __volatile__("lock; cmpxchg8b %0; setz %1" + : "=m" (*addr), "=a" (result) + : /* "m" (*addr), */ "d" (old_val2), "a" (old_val1), + "c" (new_val2), "b" (new_val1) + : "memory"); + return (int) result; + } +# define AO_HAVE_compare_double_and_swap_double_full +#endif /* !AO_NO_CMPXCHG8B */ #define AO_T_IS_INT -- 2.7.4