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 @@ -1,213 +1,212 @@ # $FreeBSD$ .include LIB= compiler_rt NO_PIC= WARNS?= 2 CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN .if ${MACHINE_CPUARCH} == "amd64" CRTARCH=x86_64 .else CRTARCH=${MACHINE_CPUARCH} .endif CRTSRC=${.CURDIR}/../../contrib/compiler-rt/lib .PATH: ${CRTSRC}/${CRTARCH} ${CRTSRC} SRCF= absvdi2 \ absvsi2 \ absvti2 \ addvdi3 \ addvsi3 \ addvti3 \ ashldi3 \ ashlti3 \ ashrdi3 \ ashrti3 \ clzdi2 \ clzsi2 \ clzti2 \ cmpdi2 \ cmpti2 \ comparedf2 \ comparesf2 \ ctzdi2 \ ctzsi2 \ ctzti2 \ divdc3 \ divdi3 \ divmoddi4 \ divmodsi4 \ divsc3 \ divti3 \ divxc3 \ enable_execute_stack \ eprintf \ ffsdi2 \ ffsti2 \ fixdfdi \ fixdfti \ fixsfdi \ fixsfti \ fixunsdfdi \ fixunsdfsi \ fixunsdfti \ fixunssfdi \ fixunssfsi \ fixunssfti \ fixunsxfdi \ fixunsxfsi \ fixunsxfti \ fixxfdi \ fixxfti \ floatdidf \ floatdisf \ floatdixf \ floattidf \ floattisf \ floattixf \ floatundidf \ floatundisf \ floatundixf \ floatunsidf \ floatunsisf \ floatuntidf \ floatuntisf \ floatuntixf \ int_util \ lshrdi3 \ lshrti3 \ moddi3 \ modti3 \ muldc3 \ muldi3 \ mulodi4 \ mulosi4 \ muloti4 \ mulsc3 \ multi3 \ mulvdi3 \ mulvsi3 \ mulvti3 \ mulxc3 \ negdf2 \ negdi2 \ negsf2 \ negti2 \ negvdi2 \ negvsi2 \ negvti2 \ paritydi2 \ paritysi2 \ parityti2 \ popcountdi2 \ popcountsi2 \ popcountti2 \ powidf2 \ powisf2 \ powitf2 \ powixf2 \ subvdi3 \ subvsi3 \ subvti3 \ trampoline_setup \ ucmpdi2 \ ucmpti2 \ udivdi3 \ udivmoddi4 \ udivmodsi4 \ udivmodti4 \ udivti3 \ umoddi3 \ umodti3 # Don't build clear_cache on ARM with clang as it is a builtin there. .if ${MACHINE_CPUARCH} != "arm" || ${COMPILER_TYPE} != "clang" SRCF+= clear_cache .endif # These are already shipped by libc.a on arm and mips .if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "mips" SRCF+= adddf3 \ addsf3 \ divdf3 \ divsf3 \ extendsfdf2 \ fixdfsi \ fixsfsi \ floatsidf \ floatsisf \ muldf3 \ mulsf3 \ subdf3 \ subsf3 \ truncdfsf2 .endif .if ${MACHINE_CPUARCH} != "mips" && \ (${MACHINE_CPUARCH} != "arm" || ${MK_ARM_EABI} != "no") SRCF+= divsi3 \ modsi3 \ udivsi3 \ 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 \ __sync_fetch_and_sub_4 \ __sync_fetch_and_xor_4 \ __sync_lock_test_and_set_4 \ __sync_val_compare_and_swap_4 .endif .if ${MACHINE_ARCH:Mmips64*} != "" SRCF+= __sync_fetch_and_add_8 \ __sync_fetch_and_and_8 \ __sync_fetch_and_or_8 \ __sync_fetch_and_sub_8 \ __sync_fetch_and_xor_8 \ __sync_lock_test_and_set_8 \ __sync_val_compare_and_swap_8 .endif .for file in ${SRCF} . if ${MACHINE_CPUARCH} != "arm" && exists(${CRTSRC}/${CRTARCH}/${file}.S) SRCS+= ${file}.S . else SRCS+= ${file}.c . endif .endfor .if ${MACHINE_CPUARCH} == "arm" && ${MK_ARM_EABI} != "no" SRCS+= aeabi_idivmod.S \ aeabi_ldivmod.S \ aeabi_memcmp.S \ aeabi_memcpy.S \ aeabi_memmove.S \ aeabi_memset.S \ aeabi_uidivmod.S \ aeabi_uldivmod.S .endif .if ${MK_INSTALLLIB} != "no" SYMLINKS+=libcompiler_rt.a ${LIBDIR}/libgcc.a .endif .if ${MK_PROFILE} != "no" SYMLINKS+=libcompiler_rt_p.a ${LIBDIR}/libgcc_p.a .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ ${MACHINE_CPUARCH} == "powerpc" AFLAGS+=--noexecstack ACFLAGS+=-Wa,--noexecstack .endif .include 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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 @@ -1,47 +1,56 @@ /*- * Copyright (c) 2011 Ed Schouten * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __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; #ifdef FETCHADD t = FETCHADD(ptr, value); #else do { t = *ptr; } while (!CMPSET(ptr, t, EXPRESSION)); #endif 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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,7 +1,7 @@ /* $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 #include "__sync_fetch_and_op_n.h" 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 @@ -1,45 +1,54 @@ /*- * Copyright (c) 2011 Ed Schouten * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __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; while (!CMPSET(ptr, oldval, newval)) { t = *ptr; if (t != oldval) return (t); } return (oldval); } + +#ifdef __clang__ +__strong_reference(atomic_func, NAME); +#endif