summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrederic Recoules <frederic.recoules@orange.fr>2020-03-05 17:54:48 +0100
committerIvan Maidanski <ivmai@mail.ru>2020-03-11 11:37:43 +0300
commitd728ce4e2be5c8328f0af8fc738622915c520aee (patch)
tree846234bab765236745cf0f3f98eb1cacba118b79 /src
parent05812c266e009197b7b99bff9a97ba6f793445c5 (diff)
downloadlibatomic_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.h16
-rw-r--r--src/atomic_ops/sysdeps/sunc/x86.h7
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");