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().
This commit is contained in:
Ed Schouten 2013-04-27 04:56:02 +00:00
parent ec8025b5e2
commit 0315980bb8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=249968
17 changed files with 34 additions and 17 deletions

View File

@ -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 \

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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