summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/builtins
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
commitbecd2ef602f52a50134be9e9743dcc1e7cd44561 (patch)
tree10b870aad86251ee11aa2ca8ed57591bb07f8f1f /compiler-rt/lib/builtins
parent3eaab9620d2892093a10d2f5f23b0763a59c8237 (diff)
downloadbcm5719-llvm-becd2ef602f52a50134be9e9743dcc1e7cd44561.tar.gz
bcm5719-llvm-becd2ef602f52a50134be9e9743dcc1e7cd44561.zip
[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 llvm-svn: 309974
Diffstat (limited to 'compiler-rt/lib/builtins')
-rw-r--r--compiler-rt/lib/builtins/emutls.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/compiler-rt/lib/builtins/emutls.c b/compiler-rt/lib/builtins/emutls.c
index 12aad3a42b7..5dd8dd15477 100644
--- a/compiler-rt/lib/builtins/emutls.c
+++ b/compiler-rt/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
OpenPOWER on IntegriCloud