From 0315980bb88b04abea42c346f1af558b89d1e29d Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 27 Apr 2013 04:56:02 +0000 Subject: [PATCH] Unbreak 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(). --- lib/libcompiler_rt/Makefile | 5 ++--- lib/libcompiler_rt/__sync_fetch_and_add_4.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_add_8.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_and_4.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_and_8.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_op_n.h | 9 +++++++++ lib/libcompiler_rt/__sync_fetch_and_or_4.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_or_8.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_sub_4.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_sub_8.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_xor_4.c | 2 +- lib/libcompiler_rt/__sync_fetch_and_xor_8.c | 2 +- lib/libcompiler_rt/__sync_lock_test_and_set_4.c | 2 +- lib/libcompiler_rt/__sync_lock_test_and_set_8.c | 2 +- lib/libcompiler_rt/__sync_val_compare_and_swap_4.c | 2 +- lib/libcompiler_rt/__sync_val_compare_and_swap_8.c | 2 +- lib/libcompiler_rt/__sync_val_compare_and_swap_n.h | 9 +++++++++ 17 files changed, 34 insertions(+), 17 deletions(-) diff --git a/lib/libcompiler_rt/Makefile b/lib/libcompiler_rt/Makefile index 2e869ccd19d9..c75ae07d26cd 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 3c11a3b87dd1..6126cfa822d1 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 6157c151767a..2738d5dd82e9 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 1a488ec27887..49fab808a796 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 9923e31158bd..f681785b64ae 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 f7f0e06e83a0..994e271ed088 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 #include +#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 1feeeb17a1d6..879b9aece713 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 7cb9403bed17..c88a37b7f20c 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 a251adde54f0..e0fe14c0ad54 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 5a93f977ec89..4f239b3e9209 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 d5f732d65f6b..8a6aec67be9d 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 610037ef28bc..be677f5794c5 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 d4965f96484f..73d1bab83f8c 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 1e02203d2be5..83c1a6acc6a8 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 e0ab11515efd..d69b6f505291 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 c6f1101a72c0..6b7a17d5b3c3 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 cd4c9a3d1663..ee9d02578397 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 #include +#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