summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrederic Recoules <frederic.recoules@orange.fr>2020-03-05 18:10:22 +0100
committerIvan Maidanski <ivmai@mail.ru>2020-03-11 12:58:12 +0300
commitbf8c33a37b4a0d5a8f04f459a972569f24dc24d3 (patch)
treed0ec9fb7ef3685a94fb681fe64d13209a024aab3 /src
parentb559c65983536fe8704dc9324c3cd3f04846aa07 (diff)
downloadlibatomic_ops-bf8c33a37b4a0d5a8f04f459a972569f24dc24d3.tar.gz
Turn off compare_double_and_swap_double_full PIC hack for GCC 5+ (x86)
Reuse of the PIC hard register, instead of using a fixed register, is implemented in Clang and GCC 5.1+, at least. * src/atomic_ops/sysdeps/gcc/x86.h [!(AO_GCC_ATOMIC_TEST_AND_SET && !AO_SKIPATOMIC_double_compare_and_swap_ANY) && !__x86_64__ && (!AO_USE_SYNC_CAS_BUILTIN || AO_GCC_ATOMIC_TEST_AND_SET) && __PIC__] (AO_compare_double_and_swap_double_full): Use non-PIC implementation if GCC version >= 5.1 or Clang version >= 4.
Diffstat (limited to 'src')
-rw-r--r--src/atomic_ops/sysdeps/gcc/x86.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/atomic_ops/sysdeps/gcc/x86.h b/src/atomic_ops/sysdeps/gcc/x86.h
index d131e16..b9003ce 100644
--- a/src/atomic_ops/sysdeps/gcc/x86.h
+++ b/src/atomic_ops/sysdeps/gcc/x86.h
@@ -459,9 +459,11 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
{
AO_t dummy; /* an output for clobbered edx */
char result;
-# ifdef __PIC__
+# if defined(__PIC__) && !(AO_GNUC_PREREQ(5, 1) || AO_CLANG_PREREQ(4, 0))
AO_t saved_ebx;
+ /* The following applies to an ancient GCC (and, probably, it was */
+ /* never needed for Clang): */
/* If PIC is turned on, we cannot use ebx as it is reserved for the */
/* GOT pointer. We should save and restore ebx. The proposed */
/* solution is not so efficient as the older alternatives using */
@@ -503,7 +505,9 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val,
# endif
# else
/* For non-PIC mode, this operation could be simplified (and be */
- /* faster) by using ebx as new_val1 (GCC would refuse to compile */
+ /* faster) by using ebx as new_val1. Reuse of the PIC hard */
+ /* register, instead of using a fixed register, is implemented */
+ /* in Clang and GCC 5.1+, at least. (Older GCC refused to compile */
/* such code for PIC mode). */
__asm__ __volatile__ ("lock; cmpxchg8b %0; setz %1"
: "+m" (*addr), "=a" (result), "=d" (dummy)