summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2013-04-27 04:56:02 +0000
committered <ed@FreeBSD.org>2013-04-27 04:56:02 +0000
commitf201fcc561ac7eab4ed7997403288e40b18a75a4 (patch)
tree4b862626af7bfbb06d0c17477809c39c52c3c91c
parent44c2a968f1f309c08b4f02d245f5af4afaf4fe76 (diff)
downloadFreeBSD-src-f201fcc561ac7eab4ed7997403288e40b18a75a4.zip
FreeBSD-src-f201fcc561ac7eab4ed7997403288e40b18a75a4.tar.gz
Unbreak <stdatomic.h> on ARM + Clang.
Clang only supports atomic operations for ARMv6. For non-ARMv6, we still need to emit these functions. Clang's prototype for these functions slightly differs, as it is truly based on GCC's documentation. It requires the use of signed types, but also requires varargs. Still, we are not allowed to simply implement this function directly. Cleverly work around this by implementing it under a different name and using __strong_reference().
-rw-r--r--lib/libcompiler_rt/Makefile5
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_add_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_add_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_and_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_and_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_op_n.h9
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_or_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_or_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_sub_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_sub_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_xor_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_fetch_and_xor_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_lock_test_and_set_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_lock_test_and_set_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_val_compare_and_swap_4.c2
-rw-r--r--lib/libcompiler_rt/__sync_val_compare_and_swap_8.c2
-rw-r--r--lib/libcompiler_rt/__sync_val_compare_and_swap_n.h9
17 files changed, 34 insertions, 17 deletions
diff --git a/lib/libcompiler_rt/Makefile b/lib/libcompiler_rt/Makefile
index 2e869cc..c75ae07 100644
--- a/lib/libcompiler_rt/Makefile
+++ b/lib/libcompiler_rt/Makefile
@@ -156,9 +156,8 @@ SRCF+= divsi3 \
umodsi3
.endif
-# FreeBSD-specific atomic intrinsics. Clang provides them as a builtin.
-.if (${MACHINE_CPUARCH} == "arm" && ${COMPILER_TYPE} != "clang") || \
- ${MACHINE_CPUARCH} == "mips"
+# FreeBSD-specific atomic intrinsics.
+.if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "mips"
SRCF+= __sync_fetch_and_add_4 \
__sync_fetch_and_and_4 \
__sync_fetch_and_or_4 \
diff --git a/lib/libcompiler_rt/__sync_fetch_and_add_4.c b/lib/libcompiler_rt/__sync_fetch_and_add_4.c
index 3c11a3b..6126cfa 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_add_4.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_add_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_add_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define FETCHADD(x, y) atomic_fetchadd_32(x, y)
#include "__sync_fetch_and_op_n.h"
diff --git a/lib/libcompiler_rt/__sync_fetch_and_add_8.c b/lib/libcompiler_rt/__sync_fetch_and_add_8.c
index 6157c15..2738d5d 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_add_8.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_add_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_add_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define FETCHADD(x, y) atomic_fetchadd_64(x, y)
#include "__sync_fetch_and_op_n.h"
diff --git a/lib/libcompiler_rt/__sync_fetch_and_and_4.c b/lib/libcompiler_rt/__sync_fetch_and_and_4.c
index 1a488ec..49fab80 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_and_4.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_and_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_and_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define CMPSET atomic_cmpset_32
#define EXPRESSION t & value
diff --git a/lib/libcompiler_rt/__sync_fetch_and_and_8.c b/lib/libcompiler_rt/__sync_fetch_and_and_8.c
index 9923e31..f681785 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_and_8.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_and_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_and_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define CMPSET atomic_cmpset_64
#define EXPRESSION t & value
diff --git a/lib/libcompiler_rt/__sync_fetch_and_op_n.h b/lib/libcompiler_rt/__sync_fetch_and_op_n.h
index f7f0e06..994e271 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_op_n.h
+++ b/lib/libcompiler_rt/__sync_fetch_and_op_n.h
@@ -30,8 +30,13 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/atomic.h>
+#if defined __clang__
+static TYPE
+atomic_func(volatile TYPE *ptr, TYPE value, ...)
+#else
TYPE
NAME(volatile TYPE *ptr, TYPE value)
+#endif
{
TYPE t;
@@ -45,3 +50,7 @@ NAME(volatile TYPE *ptr, TYPE value)
return (t);
}
+
+#ifdef __clang__
+__strong_reference(atomic_func, NAME);
+#endif
diff --git a/lib/libcompiler_rt/__sync_fetch_and_or_4.c b/lib/libcompiler_rt/__sync_fetch_and_or_4.c
index 1feeeb1..879b9ae 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_or_4.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_or_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_or_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define CMPSET atomic_cmpset_32
#define EXPRESSION t | value
diff --git a/lib/libcompiler_rt/__sync_fetch_and_or_8.c b/lib/libcompiler_rt/__sync_fetch_and_or_8.c
index 7cb9403..c88a37b 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_or_8.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_or_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_or_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define CMPSET atomic_cmpset_64
#define EXPRESSION t | value
diff --git a/lib/libcompiler_rt/__sync_fetch_and_sub_4.c b/lib/libcompiler_rt/__sync_fetch_and_sub_4.c
index a251add..e0fe14c 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_sub_4.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_sub_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_sub_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define FETCHADD(x, y) atomic_fetchadd_32(x, -(y))
#include "__sync_fetch_and_op_n.h"
diff --git a/lib/libcompiler_rt/__sync_fetch_and_sub_8.c b/lib/libcompiler_rt/__sync_fetch_and_sub_8.c
index 5a93f97..4f239b3 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_sub_8.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_sub_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_sub_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define FETCHADD(x, y) atomic_fetchadd_64(x, -(y))
#include "__sync_fetch_and_op_n.h"
diff --git a/lib/libcompiler_rt/__sync_fetch_and_xor_4.c b/lib/libcompiler_rt/__sync_fetch_and_xor_4.c
index d5f732d..8a6aec6 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_xor_4.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_xor_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_xor_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define CMPSET atomic_cmpset_32
#define EXPRESSION t ^ value
diff --git a/lib/libcompiler_rt/__sync_fetch_and_xor_8.c b/lib/libcompiler_rt/__sync_fetch_and_xor_8.c
index 610037e..be677f57 100644
--- a/lib/libcompiler_rt/__sync_fetch_and_xor_8.c
+++ b/lib/libcompiler_rt/__sync_fetch_and_xor_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_fetch_and_xor_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define CMPSET atomic_cmpset_64
#define EXPRESSION t ^ value
diff --git a/lib/libcompiler_rt/__sync_lock_test_and_set_4.c b/lib/libcompiler_rt/__sync_lock_test_and_set_4.c
index d4965f9..73d1bab 100644
--- a/lib/libcompiler_rt/__sync_lock_test_and_set_4.c
+++ b/lib/libcompiler_rt/__sync_lock_test_and_set_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_lock_test_and_set_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define CMPSET atomic_cmpset_32
#define EXPRESSION value
diff --git a/lib/libcompiler_rt/__sync_lock_test_and_set_8.c b/lib/libcompiler_rt/__sync_lock_test_and_set_8.c
index 1e02203..83c1a6a 100644
--- a/lib/libcompiler_rt/__sync_lock_test_and_set_8.c
+++ b/lib/libcompiler_rt/__sync_lock_test_and_set_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_lock_test_and_set_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define CMPSET atomic_cmpset_64
#define EXPRESSION value
diff --git a/lib/libcompiler_rt/__sync_val_compare_and_swap_4.c b/lib/libcompiler_rt/__sync_val_compare_and_swap_4.c
index e0ab115..d69b6f5 100644
--- a/lib/libcompiler_rt/__sync_val_compare_and_swap_4.c
+++ b/lib/libcompiler_rt/__sync_val_compare_and_swap_4.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_val_compare_and_swap_4
-#define TYPE uint32_t
+#define TYPE int32_t
#define CMPSET atomic_cmpset_32
#include "__sync_val_compare_and_swap_n.h"
diff --git a/lib/libcompiler_rt/__sync_val_compare_and_swap_8.c b/lib/libcompiler_rt/__sync_val_compare_and_swap_8.c
index c6f1101..6b7a17d 100644
--- a/lib/libcompiler_rt/__sync_val_compare_and_swap_8.c
+++ b/lib/libcompiler_rt/__sync_val_compare_and_swap_8.c
@@ -1,6 +1,6 @@
/* $FreeBSD$ */
#define NAME __sync_val_compare_and_swap_8
-#define TYPE uint64_t
+#define TYPE int64_t
#define CMPSET atomic_cmpset_64
#include "__sync_val_compare_and_swap_n.h"
diff --git a/lib/libcompiler_rt/__sync_val_compare_and_swap_n.h b/lib/libcompiler_rt/__sync_val_compare_and_swap_n.h
index cd4c9a3..ee9d025 100644
--- a/lib/libcompiler_rt/__sync_val_compare_and_swap_n.h
+++ b/lib/libcompiler_rt/__sync_val_compare_and_swap_n.h
@@ -30,8 +30,13 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/atomic.h>
+#if defined __clang__
+static TYPE
+atomic_func(volatile TYPE *ptr, TYPE oldval, TYPE newval, ...)
+#else
TYPE
NAME(volatile TYPE *ptr, TYPE oldval, TYPE newval)
+#endif
{
TYPE t;
@@ -43,3 +48,7 @@ NAME(volatile TYPE *ptr, TYPE oldval, TYPE newval)
return (oldval);
}
+
+#ifdef __clang__
+__strong_reference(atomic_func, NAME);
+#endif
OpenPOWER on IntegriCloud