diff options
author | Frederic Recoules <frederic.recoules@orange.fr> | 2020-03-05 18:10:22 +0100 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2020-03-11 12:58:12 +0300 |
commit | bf8c33a37b4a0d5a8f04f459a972569f24dc24d3 (patch) | |
tree | d0ec9fb7ef3685a94fb681fe64d13209a024aab3 /src | |
parent | b559c65983536fe8704dc9324c3cd3f04846aa07 (diff) | |
download | libatomic_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.h | 8 |
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) |