diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h')
| -rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h index 38363e87556..47581282a78 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_atomic_clang.h @@ -71,16 +71,26 @@ INLINE typename T::Type atomic_exchange(volatile T *a, return v; } -template<typename T> -INLINE bool atomic_compare_exchange_strong(volatile T *a, - typename T::Type *cmp, +template <typename T> +INLINE bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp, typename T::Type xchg, memory_order mo) { typedef typename T::Type Type; Type cmpv = *cmp; - Type prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg); - if (prev == cmpv) - return true; + Type prev; +#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 + if (sizeof(*a) == 8) { + Type volatile *val_ptr = const_cast<Type volatile *>(&a->val_dont_use); + prev = __mips_sync_val_compare_and_swap<u64>( + reinterpret_cast<u64 volatile *>(val_ptr), reinterpret_cast<u64> cmpv, + reinterpret_cast<u64> xchg); + } else { + prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg); + } +#else + prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg); +#endif + if (prev == cmpv) return true; *cmp = prev; return false; } |

