diff options
author | Frederic Recoules <frederic.recoules@orange.fr> | 2020-03-05 17:54:48 +0100 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2020-03-11 11:37:43 +0300 |
commit | d728ce4e2be5c8328f0af8fc738622915c520aee (patch) | |
tree | 846234bab765236745cf0f3f98eb1cacba118b79 /src | |
parent | 05812c266e009197b7b99bff9a97ba6f793445c5 (diff) | |
download | libatomic_ops-d728ce4e2be5c8328f0af8fc738622915c520aee.tar.gz |
Fix gcc/sunc x86 AO_compare_double_and_swap_double missing side effect
(fix of commits 1dc2fb3, 929954a)
Bind E/RDX to a dummy output since cmpxchg8/16b clobbers it.
* src/atomic_ops/sysdeps/gcc/x86.h [!(AO_GCC_ATOMIC_TEST_AND_SET
&& !AO_SKIPATOMIC_double_compare_and_swap_ANY)]
(AO_compare_double_and_swap_double_full): Declare dummy local variable;
specify "=d"(dummy) for asm code.
* src/atomic_ops/sysdeps/sunc/x86.h [__i386 && !AO_NO_CMPXCHG8B ||
!__i386 && AO_CMPXCHG16B_AVAILABLE]
(AO_compare_double_and_swap_double_full): Likewise.
Diffstat (limited to 'src')
-rw-r--r-- | src/atomic_ops/sysdeps/gcc/x86.h | 16 | ||||
-rw-r--r-- | src/atomic_ops/sysdeps/sunc/x86.h | 7 |
2 files changed, 15 insertions, 8 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h index f68a8b0..57a1fdc 100644 --- a/src/atomic_ops/sysdeps/gcc/x86.h +++ b/src/atomic_ops/sysdeps/gcc/x86.h @@ -442,6 +442,7 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t old_val1, AO_t old_val2, AO_t new_val1, AO_t new_val2) { + AO_t dummy; /* an output for clobbered edx */ char result; # ifdef __PIC__ AO_t saved_ebx; @@ -457,11 +458,12 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, # ifdef __OPTIMIZE__ __asm__ __volatile__("mov %%ebx, %2\n\t" /* save ebx */ "lea %0, %%edi\n\t" /* in case addr is in ebx */ - "mov %7, %%ebx\n\t" /* load new_val1 */ + "mov %8, %%ebx\n\t" /* load new_val1 */ "lock; cmpxchg8b (%%edi)\n\t" "mov %2, %%ebx\n\t" /* restore ebx */ "setz %1" - : "=m" (*addr), "=a" (result), "=m" (saved_ebx) + : "=m" (*addr), "=a" (result), + "=m" (saved_ebx), "=d" (dummy) : "m" (*addr), "d" (old_val2), "a" (old_val1), "c" (new_val2), "m" (new_val1) : "%edi", "memory"); @@ -473,13 +475,13 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, __asm__ __volatile__("mov %%edi, %3\n\t" /* save edi */ "mov %%ebx, %2\n\t" /* save ebx */ "lea %0, %%edi\n\t" /* in case addr is in ebx */ - "mov %8, %%ebx\n\t" /* load new_val1 */ + "mov %9, %%ebx\n\t" /* load new_val1 */ "lock; cmpxchg8b (%%edi)\n\t" "mov %2, %%ebx\n\t" /* restore ebx */ "mov %3, %%edi\n\t" /* restore edi */ "setz %1" : "=m" (*addr), "=a" (result), - "=m" (saved_ebx), "=m" (saved_edi) + "=m" (saved_ebx), "=m" (saved_edi), "=d" (dummy) : "m" (*addr), "d" (old_val2), "a" (old_val1), "c" (new_val2), "m" (new_val1) : "memory"); # endif @@ -488,7 +490,7 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, /* faster) by using ebx as new_val1 (GCC would refuse to compile */ /* such code for PIC mode). */ __asm__ __volatile__ ("lock; cmpxchg8b %0; setz %1" - : "=m" (*addr), "=a" (result) + : "=m" (*addr), "=a" (result), "=d" (dummy) : "m" (*addr), "d" (old_val2), "a" (old_val1), "c" (new_val2), "b" (new_val1) : "memory"); @@ -552,9 +554,11 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t old_val1, AO_t old_val2, AO_t new_val1, AO_t new_val2) { + AO_t dummy; /* an output for clobbered rdx */ char result; + __asm__ __volatile__("lock; cmpxchg16b %0; setz %1" - : "=m"(*addr), "=a"(result) + : "=m" (*addr), "=a" (result), "=d" (dummy) : "m"(*addr), "d" (old_val2), "a" (old_val1), "c" (new_val2), "b" (new_val1) : "memory"); diff --git a/src/atomic_ops/sysdeps/sunc/x86.h b/src/atomic_ops/sysdeps/sunc/x86.h index 88c6a78..dfac1e5 100644 --- a/src/atomic_ops/sysdeps/sunc/x86.h +++ b/src/atomic_ops/sysdeps/sunc/x86.h @@ -176,10 +176,11 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t old_val1, AO_t old_val2, AO_t new_val1, AO_t new_val2) { + AO_t dummy; /* an output for clobbered edx */ char result; __asm__ __volatile__ ("lock; cmpxchg8b %0; setz %1" - : "+m" (*addr), "=a" (result) + : "+m" (*addr), "=a" (result), "=d" (dummy) : "d" (old_val2), "a" (old_val1), "c" (new_val2), "b" (new_val1) : "memory"); @@ -215,9 +216,11 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t old_val1, AO_t old_val2, AO_t new_val1, AO_t new_val2) { + AO_t dummy; char result; + __asm__ __volatile__ ("lock; cmpxchg16b %0; setz %1" - : "+m" (*addr), "=a" (result) + : "+m" (*addr), "=a" (result), "=d" (dummy) : "d" (old_val2), "a" (old_val1), "c" (new_val2), "b" (new_val1) : "memory"); |