summaryrefslogtreecommitdiff
path: root/lib/builtins/emutls.c
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2017-08-03 19:04:28 +0000
committerMartin Storsjo <martin@martin.st>2017-08-03 19:04:28 +0000
commit8293838e866814d904640f6359954d00852f2421 (patch)
tree6cab5f492f0f2bc423ec9be2e38328d25fc2bd8c /lib/builtins/emutls.c
parent6b85e16e8efc13254b113ab4c6087000b21f3e56 (diff)
downloadcompiler-rt-8293838e866814d904640f6359954d00852f2421.tar.gz
[builtins] Use Interlocked* intrinsics for atomics on MSVC
Tested on MSVC 2013, 2015 and 2017 targeting X86, X64 and ARM. This fixes building emutls.c for Windows for ARM (both with clang which don't need these atomics fallbacks at all, but just failed due to the immintrin.h include before, and with MSVC). Differential Revision: https://reviews.llvm.org/D36071 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@309974 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/builtins/emutls.c')
-rw-r--r--lib/builtins/emutls.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/lib/builtins/emutls.c b/lib/builtins/emutls.c
index 12aad3a42..5dd8dd154 100644
--- a/lib/builtins/emutls.c
+++ b/lib/builtins/emutls.c
@@ -102,7 +102,6 @@ static __inline emutls_address_array* emutls_getspecific() {
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
-#include <immintrin.h>
static LPCRITICAL_SECTION emutls_mutex;
static DWORD emutls_tls_index = TLS_OUT_OF_INDEXES;
@@ -203,25 +202,24 @@ static __inline emutls_address_array* emutls_getspecific() {
/* Provide atomic load/store functions for emutls_get_index if built with MSVC.
*/
#if !defined(__ATOMIC_RELEASE)
+#include <intrin.h>
enum { __ATOMIC_ACQUIRE = 2, __ATOMIC_RELEASE = 3 };
static __inline uintptr_t __atomic_load_n(void *ptr, unsigned type) {
assert(type == __ATOMIC_ACQUIRE);
+ // These return the previous value - but since we do an OR with 0,
+ // it's equivalent to a plain load.
#ifdef _WIN64
- return (uintptr_t) _load_be_u64(ptr);
+ return InterlockedOr64(ptr, 0);
#else
- return (uintptr_t) _load_be_u32(ptr);
+ return InterlockedOr(ptr, 0);
#endif
}
static __inline void __atomic_store_n(void *ptr, uintptr_t val, unsigned type) {
assert(type == __ATOMIC_RELEASE);
-#ifdef _WIN64
- _store_be_u64(ptr, val);
-#else
- _store_be_u32(ptr, val);
-#endif
+ InterlockedExchangePointer((void *volatile *)ptr, (void *)val);
}
#endif