diff options
author | andrew <andrew@FreeBSD.org> | 2012-08-08 09:42:44 +0000 |
---|---|---|
committer | andrew <andrew@FreeBSD.org> | 2012-08-08 09:42:44 +0000 |
commit | 30502844bd04cb59ab3146bfc660987e81eaaac0 (patch) | |
tree | ee445c9472d0093c3489f12d8048a72fe6e55f66 /contrib | |
parent | 54cb95d6380dbb936499b9c35fd4ad12ba649f42 (diff) | |
parent | cfeab007a554034f0b3ab4a677cf9dd2696c12f9 (diff) | |
download | FreeBSD-src-30502844bd04cb59ab3146bfc660987e81eaaac0.zip FreeBSD-src-30502844bd04cb59ab3146bfc660987e81eaaac0.tar.gz |
Import compiler-rt r160957.
This is mostly a no-op other than for ARM where it adds missing
__aeabi_mem* and __aeabi_*divmod functions. Even on ARM these will remain
unused until the rest of the ARM EABI code is merged.
Diffstat (limited to 'contrib')
87 files changed, 665 insertions, 124 deletions
diff --git a/contrib/compiler-rt/LICENSE.TXT b/contrib/compiler-rt/LICENSE.TXT index c41925e..f717942 100644 --- a/contrib/compiler-rt/LICENSE.TXT +++ b/contrib/compiler-rt/LICENSE.TXT @@ -94,5 +94,4 @@ licenses, and/or restrictions: Program Directory ------- --------- -sysinfo lib/asan/sysinfo -mach_override lib/asan/mach_override +mach_override lib/interception/mach_override diff --git a/contrib/compiler-rt/lib/absvti2.c b/contrib/compiler-rt/lib/absvti2.c index 8f2bddc..c1c7277 100644 --- a/contrib/compiler-rt/lib/absvti2.c +++ b/contrib/compiler-rt/lib/absvti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: absolute value */ /* Effects: aborts if abs(x) < 0 */ diff --git a/contrib/compiler-rt/lib/adddf3.c b/contrib/compiler-rt/lib/adddf3.c index 7eb40a1..a55e82d 100644 --- a/contrib/compiler-rt/lib/adddf3.c +++ b/contrib/compiler-rt/lib/adddf3.c @@ -15,7 +15,7 @@ #define DOUBLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(dadd, adddf3); +ARM_EABI_FNALIAS(dadd, adddf3) COMPILER_RT_ABI fp_t __adddf3(fp_t a, fp_t b) { @@ -85,7 +85,7 @@ __adddf3(fp_t a, fp_t b) { // Shift the significand of b by the difference in exponents, with a sticky // bottom bit to get rounding correct. - const int align = aExponent - bExponent; + const unsigned int align = aExponent - bExponent; if (align) { if (align < typeWidth) { const bool sticky = bSignificand << (typeWidth - align); diff --git a/contrib/compiler-rt/lib/addsf3.c b/contrib/compiler-rt/lib/addsf3.c index e57270a..0268324 100644 --- a/contrib/compiler-rt/lib/addsf3.c +++ b/contrib/compiler-rt/lib/addsf3.c @@ -15,7 +15,7 @@ #define SINGLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(fadd, addsf3); +ARM_EABI_FNALIAS(fadd, addsf3) fp_t __addsf3(fp_t a, fp_t b) { @@ -84,7 +84,7 @@ fp_t __addsf3(fp_t a, fp_t b) { // Shift the significand of b by the difference in exponents, with a sticky // bottom bit to get rounding correct. - const int align = aExponent - bExponent; + const unsigned int align = aExponent - bExponent; if (align) { if (align < typeWidth) { const bool sticky = bSignificand << (typeWidth - align); diff --git a/contrib/compiler-rt/lib/addvti3.c b/contrib/compiler-rt/lib/addvti3.c index 9105c17..2efcf3b 100644 --- a/contrib/compiler-rt/lib/addvti3.c +++ b/contrib/compiler-rt/lib/addvti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a + b */ /* Effects: aborts if a + b overflows */ diff --git a/contrib/compiler-rt/lib/arm/aeabi_idivmod.S b/contrib/compiler-rt/lib/arm/aeabi_idivmod.S new file mode 100644 index 0000000..0237f22 --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_idivmod.S @@ -0,0 +1,27 @@ +//===-- aeabi_idivmod.S - EABI idivmod implementation ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// struct { int quot, int rem} __aeabi_idivmod(int numerator, int denominator) { +// int rem, quot; +// quot = __divmodsi4(numerator, denominator, &rem); +// return {quot, rem}; +// } + + .syntax unified + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod) + push { lr } + sub sp, sp, #4 + mov r2, sp + bl SYMBOL_NAME(__divmodsi4) + ldr r1, [sp] + add sp, sp, #4 + pop { pc } diff --git a/contrib/compiler-rt/lib/arm/aeabi_ldivmod.S b/contrib/compiler-rt/lib/arm/aeabi_ldivmod.S new file mode 100644 index 0000000..197c459 --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_ldivmod.S @@ -0,0 +1,30 @@ +//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// struct { int64_t quot, int64_t rem} +// __aeabi_ldivmod(int64_t numerator, int64_t denominator) { +// int64_t rem, quot; +// quot = __divmoddi4(numerator, denominator, &rem); +// return {quot, rem}; +// } + + .syntax unified + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod) + push {r11, lr} + sub sp, sp, #16 + add r12, sp, #8 + str r12, [sp] + bl SYMBOL_NAME(__divmoddi4) + ldr r2, [sp, #8] + ldr r3, [sp, #12] + add sp, sp, #16 + pop {r11, pc} diff --git a/contrib/compiler-rt/lib/arm/aeabi_memcmp.S b/contrib/compiler-rt/lib/arm/aeabi_memcmp.S new file mode 100644 index 0000000..ca29c10 --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_memcmp.S @@ -0,0 +1,19 @@ +//===-- aeabi_memcmp.S - EABI memcmp implementation -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// void __aeabi_memcmp(void *dest, void *src, size_t n) { memcmp(dest, src, n); } + + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_memcmp) + b memcmp + +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp) +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp) diff --git a/contrib/compiler-rt/lib/arm/aeabi_memcpy.S b/contrib/compiler-rt/lib/arm/aeabi_memcpy.S new file mode 100644 index 0000000..8b9c7fd --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_memcpy.S @@ -0,0 +1,19 @@ +//===-- aeabi_memcpy.S - EABI memcpy implementation -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// void __aeabi_memcpy(void *dest, void *src, size_t n) { memcpy(dest, src, n); } + + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_memcpy) + b memcpy + +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy) +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy) diff --git a/contrib/compiler-rt/lib/arm/aeabi_memmove.S b/contrib/compiler-rt/lib/arm/aeabi_memmove.S new file mode 100644 index 0000000..c94ed2b --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_memmove.S @@ -0,0 +1,19 @@ +//===-- aeabi_memmove.S - EABI memmove implementation --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "../assembly.h" + +// void __aeabi_memmove(void *dest, void *src, size_t n) { memmove(dest, src, n); } + + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_memmove) + b memmove + +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove) +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove) diff --git a/contrib/compiler-rt/lib/arm/aeabi_memset.S b/contrib/compiler-rt/lib/arm/aeabi_memset.S new file mode 100644 index 0000000..30ab4ba --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_memset.S @@ -0,0 +1,32 @@ +//===-- aeabi_memset.S - EABI memset implementation -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// void __aeabi_memset(void *dest, size_t n, int c) { memset(dest, c, n); } +// void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); } + + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_memset) + mov r3, r1 + mov r1, r2 + mov r2, r3 + b memset + +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset4, __aeabi_memset) +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memset8, __aeabi_memset) + +DEFINE_COMPILERRT_FUNCTION(__aeabi_memclr) + mov r2, r1 + mov r1, #0 + b memset + +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr) +DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr) + diff --git a/contrib/compiler-rt/lib/arm/aeabi_uidivmod.S b/contrib/compiler-rt/lib/arm/aeabi_uidivmod.S new file mode 100644 index 0000000..f7e1d2e --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_uidivmod.S @@ -0,0 +1,28 @@ +//===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// struct { unsigned quot, unsigned rem} +// __aeabi_uidivmod(unsigned numerator, unsigned denominator) { +// unsigned rem, quot; +// quot = __udivmodsi4(numerator, denominator, &rem); +// return {quot, rem}; +// } + + .syntax unified + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod) + push { lr } + sub sp, sp, #4 + mov r2, sp + bl SYMBOL_NAME(__udivmodsi4) + ldr r1, [sp] + add sp, sp, #4 + pop { pc } diff --git a/contrib/compiler-rt/lib/arm/aeabi_uldivmod.S b/contrib/compiler-rt/lib/arm/aeabi_uldivmod.S new file mode 100644 index 0000000..724049d --- /dev/null +++ b/contrib/compiler-rt/lib/arm/aeabi_uldivmod.S @@ -0,0 +1,30 @@ +//===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "../assembly.h" + +// struct { uint64_t quot, uint64_t rem} +// __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) { +// uint64_t rem, quot; +// quot = __udivmoddi4(numerator, denominator, &rem); +// return {quot, rem}; +// } + + .syntax unified + .align 2 +DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod) + push {r11, lr} + sub sp, sp, #16 + add r12, sp, #8 + str r12, [sp] + bl SYMBOL_NAME(__udivmoddi4) + ldr r2, [sp, #8] + ldr r3, [sp, #12] + add sp, sp, #16 + pop {r11, pc}
\ No newline at end of file diff --git a/contrib/compiler-rt/lib/ashldi3.c b/contrib/compiler-rt/lib/ashldi3.c index 6c558fe..eb4698a 100644 --- a/contrib/compiler-rt/lib/ashldi3.c +++ b/contrib/compiler-rt/lib/ashldi3.c @@ -18,7 +18,7 @@ /* Precondition: 0 <= b < bits_in_dword */ -ARM_EABI_FNALIAS(llsl, ashldi3); +ARM_EABI_FNALIAS(llsl, ashldi3) COMPILER_RT_ABI di_int __ashldi3(di_int a, si_int b) diff --git a/contrib/compiler-rt/lib/ashlti3.c b/contrib/compiler-rt/lib/ashlti3.c index 7042b53..4bd8219 100644 --- a/contrib/compiler-rt/lib/ashlti3.c +++ b/contrib/compiler-rt/lib/ashlti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a << b */ /* Precondition: 0 <= b < bits_in_tword */ diff --git a/contrib/compiler-rt/lib/ashrdi3.c b/contrib/compiler-rt/lib/ashrdi3.c index 38ab716..14c878b 100644 --- a/contrib/compiler-rt/lib/ashrdi3.c +++ b/contrib/compiler-rt/lib/ashrdi3.c @@ -18,7 +18,7 @@ /* Precondition: 0 <= b < bits_in_dword */ -ARM_EABI_FNALIAS(lasr, ashrdi3); +ARM_EABI_FNALIAS(lasr, ashrdi3) COMPILER_RT_ABI di_int __ashrdi3(di_int a, si_int b) diff --git a/contrib/compiler-rt/lib/ashrti3.c b/contrib/compiler-rt/lib/ashrti3.c index 4d16230..ed43641 100644 --- a/contrib/compiler-rt/lib/ashrti3.c +++ b/contrib/compiler-rt/lib/ashrti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: arithmetic a >> b */ /* Precondition: 0 <= b < bits_in_tword */ diff --git a/contrib/compiler-rt/lib/assembly.h b/contrib/compiler-rt/lib/assembly.h index 83bed12..3d8e50d 100644 --- a/contrib/compiler-rt/lib/assembly.h +++ b/contrib/compiler-rt/lib/assembly.h @@ -25,9 +25,11 @@ #if defined(__APPLE__) #define HIDDEN_DIRECTIVE .private_extern #define LOCAL_LABEL(name) L_##name +#define FILE_LEVEL_DIRECTIVE .subsections_via_symbols #else #define HIDDEN_DIRECTIVE .hidden #define LOCAL_LABEL(name) .L_##name +#define FILE_LEVEL_DIRECTIVE #endif #define GLUE2(a, b) a ## b @@ -42,6 +44,7 @@ #endif #define DEFINE_COMPILERRT_FUNCTION(name) \ + FILE_LEVEL_DIRECTIVE SEPARATOR \ .globl SYMBOL_NAME(name) SEPARATOR \ DECLARE_SYMBOL_VISIBILITY(name) \ SYMBOL_NAME(name): diff --git a/contrib/compiler-rt/lib/atomic.c b/contrib/compiler-rt/lib/atomic.c new file mode 100644 index 0000000..a291f0d --- /dev/null +++ b/contrib/compiler-rt/lib/atomic.c @@ -0,0 +1,315 @@ +/*===-- atomic.c - Implement support functions for atomic operations.------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------=== + * + * atomic.c defines a set of functions for performing atomic accesses on + * arbitrary-sized memory locations. This design uses locks that should + * be fast in the uncontended case, for two reasons: + * + * 1) This code must work with C programs that do not link to anything + * (including pthreads) and so it should not depend on any pthread + * functions. + * 2) Atomic operations, rather than explicit mutexes, are most commonly used + * on code where contended operations are rate. + * + * To avoid needing a per-object lock, this code allocates an array of + * locks and hashes the object pointers to find the one that it should use. + * For operations that must be atomic on two locations, the lower lock is + * always acquired first, to avoid deadlock. + * + *===----------------------------------------------------------------------=== + */ + +#include <stdint.h> +#include <string.h> + +// Clang objects if you redefine a builtin. This little hack allows us to +// define a function with the same name as an intrinsic. +#pragma redefine_extname __atomic_load_c __atomic_load +#pragma redefine_extname __atomic_store_c __atomic_store +#pragma redefine_extname __atomic_exchange_c __atomic_exchange +#pragma redefine_extname __atomic_compare_exchange_c __atomic_compare_exchange + +/// Number of locks. This allocates one page on 32-bit platforms, two on +/// 64-bit. This can be specified externally if a different trade between +/// memory usage and contention probability is required for a given platform. +#ifndef SPINLOCK_COUNT +#define SPINLOCK_COUNT (1<<10) +#endif +static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1; + +//////////////////////////////////////////////////////////////////////////////// +// Platform-specific lock implementation. Falls back to spinlocks if none is +// defined. Each platform should define the Lock type, and corresponding +// lock() and unlock() functions. +//////////////////////////////////////////////////////////////////////////////// +#ifdef __FreeBSD__ +#include <errno.h> +#include <sys/types.h> +#include <machine/atomic.h> +#include <sys/umtx.h> +typedef struct _usem Lock; +inline static void unlock(Lock *l) { + __c11_atomic_store((_Atomic(uint32_t)*)&l->_count, 1, __ATOMIC_RELEASE); + __c11_atomic_thread_fence(__ATOMIC_SEQ_CST); + if (l->_has_waiters) + _umtx_op(l, UMTX_OP_SEM_WAKE, 1, 0, 0); +} +inline static void lock(Lock *l) { + uint32_t old = 1; + while (!__c11_atomic_compare_exchange_weak((_Atomic(uint32_t)*)&l->_count, &old, + 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { + _umtx_op(l, UMTX_OP_SEM_WAIT, 0, 0, 0); + old = 1; + } +} +/// locks for atomic operations +static Lock locks[SPINLOCK_COUNT] = { [0 ... SPINLOCK_COUNT-1] = {0,1,0} }; +#else +typedef _Atomic(uintptr_t) Lock; +/// Unlock a lock. This is a release operation. +inline static void unlock(Lock *l) { + __c11_atomic_store(l, 0, __ATOMIC_RELEASE); +} +/// Locks a lock. In the current implementation, this is potentially +/// unbounded in the contended case. +inline static void lock(Lock *l) { + uintptr_t old = 0; + while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE, + __ATOMIC_RELAXED)) + old = 0; +} +/// locks for atomic operations +static Lock locks[SPINLOCK_COUNT]; +#endif + + +/// Returns a lock to use for a given pointer. +static inline Lock *lock_for_pointer(void *ptr) { + intptr_t hash = (intptr_t)ptr; + // Disregard the lowest 4 bits. We want all values that may be part of the + // same memory operation to hash to the same value and therefore use the same + // lock. + hash >>= 4; + // Use the next bits as the basis for the hash + intptr_t low = hash & SPINLOCK_MASK; + // Now use the high(er) set of bits to perturb the hash, so that we don't + // get collisions from atomic fields in a single object + hash >>= 16; + hash ^= low; + // Return a pointer to the word to use + return locks + (hash & SPINLOCK_MASK); +} + +/// Macros for determining whether a size is lock free. Clang can not yet +/// codegen __atomic_is_lock_free(16), so for now we assume 16-byte values are +/// not lock free. +#define IS_LOCK_FREE_1 __c11_atomic_is_lock_free(1) +#define IS_LOCK_FREE_2 __c11_atomic_is_lock_free(2) +#define IS_LOCK_FREE_4 __c11_atomic_is_lock_free(4) +#define IS_LOCK_FREE_8 __c11_atomic_is_lock_free(8) +#define IS_LOCK_FREE_16 0 + +/// Macro that calls the compiler-generated lock-free versions of functions +/// when they exist. +#define LOCK_FREE_CASES() \ + do {\ + switch (size) {\ + case 2:\ + if (IS_LOCK_FREE_2) {\ + LOCK_FREE_ACTION(uint16_t);\ + }\ + case 4:\ + if (IS_LOCK_FREE_4) {\ + LOCK_FREE_ACTION(uint32_t);\ + }\ + case 8:\ + if (IS_LOCK_FREE_8) {\ + LOCK_FREE_ACTION(uint64_t);\ + }\ + case 16:\ + if (IS_LOCK_FREE_16) {\ + /* FIXME: __uint128_t isn't available on 32 bit platforms. + LOCK_FREE_ACTION(__uint128_t);*/\ + }\ + }\ + } while (0) + + +/// An atomic load operation. This is atomic with respect to the source +/// pointer only. +void __atomic_load_c(int size, void *src, void *dest, int model) { +#define LOCK_FREE_ACTION(type) \ + *((type*)dest) = __c11_atomic_load((_Atomic(type)*)src, model);\ + return; + LOCK_FREE_CASES(); +#undef LOCK_FREE_ACTION + Lock *l = lock_for_pointer(src); + lock(l); + memcpy(dest, src, size); + unlock(l); +} + +/// An atomic store operation. This is atomic with respect to the destination +/// pointer only. +void __atomic_store_c(int size, void *dest, void *src, int model) { +#define LOCK_FREE_ACTION(type) \ + __c11_atomic_store((_Atomic(type)*)dest, *(type*)dest, model);\ + return; + LOCK_FREE_CASES(); +#undef LOCK_FREE_ACTION + Lock *l = lock_for_pointer(dest); + lock(l); + memcpy(dest, src, size); + unlock(l); +} + +/// Atomic compare and exchange operation. If the value at *ptr is identical +/// to the value at *expected, then this copies value at *desired to *ptr. If +/// they are not, then this stores the current value from *ptr in *expected. +/// +/// This function returns 1 if the exchange takes place or 0 if it fails. +int __atomic_compare_exchange_c(int size, void *ptr, void *expected, + void *desired, int success, int failure) { +#define LOCK_FREE_ACTION(type) \ + return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, (type*)expected,\ + *(type*)desired, success, failure) + LOCK_FREE_CASES(); +#undef LOCK_FREE_ACTION + Lock *l = lock_for_pointer(ptr); + lock(l); + if (memcmp(ptr, expected, size) == 0) { + memcpy(ptr, desired, size); + unlock(l); + return 1; + } + memcpy(expected, ptr, size); + unlock(l); + return 0; +} + +/// Performs an atomic exchange operation between two pointers. This is atomic +/// with respect to the target address. +void __atomic_exchange_c(int size, void *ptr, void *val, void *old, int model) { +#define LOCK_FREE_ACTION(type) \ + *(type*)old = __c11_atomic_exchange((_Atomic(type)*)ptr, *(type*)val,\ + model);\ + return; + LOCK_FREE_CASES(); +#undef LOCK_FREE_ACTION + Lock *l = lock_for_pointer(ptr); + lock(l); + memcpy(old, ptr, size); + memcpy(ptr, val, size); + unlock(l); +} + +//////////////////////////////////////////////////////////////////////////////// +// Where the size is known at compile time, the compiler may emit calls to +// specialised versions of the above functions. +//////////////////////////////////////////////////////////////////////////////// +#define OPTIMISED_CASES\ + OPTIMISED_CASE(1, IS_LOCK_FREE_1, uint8_t)\ + OPTIMISED_CASE(2, IS_LOCK_FREE_2, uint16_t)\ + OPTIMISED_CASE(4, IS_LOCK_FREE_4, uint32_t)\ + OPTIMISED_CASE(8, IS_LOCK_FREE_8, uint64_t)\ + /* FIXME: __uint128_t isn't available on 32 bit platforms. + OPTIMISED_CASE(16, IS_LOCK_FREE_16, __uint128_t)*/\ + +#define OPTIMISED_CASE(n, lockfree, type)\ +type __atomic_load_##n(type *src, int model) {\ + if (lockfree)\ + return __c11_atomic_load((_Atomic(type)*)src, model);\ + Lock *l = lock_for_pointer(src);\ + lock(l);\ + type val = *src;\ + unlock(l);\ + return val;\ +} +OPTIMISED_CASES +#undef OPTIMISED_CASE + +#define OPTIMISED_CASE(n, lockfree, type)\ +void __atomic_store_##n(type *dest, type val, int model) {\ + if (lockfree) {\ + __c11_atomic_store((_Atomic(type)*)dest, val, model);\ + return;\ + }\ + Lock *l = lock_for_pointer(dest);\ + lock(l);\ + *dest = val;\ + unlock(l);\ + return;\ +} +OPTIMISED_CASES +#undef OPTIMISED_CASE + +#define OPTIMISED_CASE(n, lockfree, type)\ +type __atomic_exchange_##n(type *dest, type val, int model) {\ + if (lockfree)\ + return __c11_atomic_exchange((_Atomic(type)*)dest, val, model);\ + Lock *l = lock_for_pointer(dest);\ + lock(l);\ + type tmp = *dest;\ + *dest = val;\ + unlock(l);\ + return tmp;\ +} +OPTIMISED_CASES +#undef OPTIMISED_CASE + +#define OPTIMISED_CASE(n, lockfree, type)\ +int __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\ + int success, int failure) {\ + if (lockfree)\ + return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, expected, desired,\ + success, failure);\ + Lock *l = lock_for_pointer(ptr);\ + lock(l);\ + if (*ptr == *expected) {\ + *ptr = desired;\ + unlock(l);\ + return 1;\ + }\ + *expected = *ptr;\ + unlock(l);\ + return 0;\ +} +OPTIMISED_CASES +#undef OPTIMISED_CASE + +//////////////////////////////////////////////////////////////////////////////// +// Atomic read-modify-write operations for integers of various sizes. +//////////////////////////////////////////////////////////////////////////////// +#define ATOMIC_RMW(n, lockfree, type, opname, op) \ +type __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\ + if (lockfree) \ + return __c11_atomic_fetch_##opname((_Atomic(type)*)ptr, val, model);\ + Lock *l = lock_for_pointer(ptr);\ + lock(l);\ + type tmp = *ptr;\ + *ptr = tmp op val;\ + unlock(l);\ + return tmp;\ +} + +#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, add, +) +OPTIMISED_CASES +#undef OPTIMISED_CASE +#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, sub, -) +OPTIMISED_CASES +#undef OPTIMISED_CASE +#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, and, &) +OPTIMISED_CASES +#undef OPTIMISED_CASE +#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, or, |) +OPTIMISED_CASES +#undef OPTIMISED_CASE +#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, xor, ^) +OPTIMISED_CASES +#undef OPTIMISED_CASE diff --git a/contrib/compiler-rt/lib/clzti2.c b/contrib/compiler-rt/lib/clzti2.c index 7a650eb..355c20e 100644 --- a/contrib/compiler-rt/lib/clzti2.c +++ b/contrib/compiler-rt/lib/clzti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: the number of leading 0-bits */ /* Precondition: a != 0 */ diff --git a/contrib/compiler-rt/lib/cmpti2.c b/contrib/compiler-rt/lib/cmpti2.c index b156fce..d0aec45 100644 --- a/contrib/compiler-rt/lib/cmpti2.c +++ b/contrib/compiler-rt/lib/cmpti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 diff --git a/contrib/compiler-rt/lib/ctzti2.c b/contrib/compiler-rt/lib/ctzti2.c index 1c9508f..66dc01b 100644 --- a/contrib/compiler-rt/lib/ctzti2.c +++ b/contrib/compiler-rt/lib/ctzti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: the number of trailing 0-bits */ /* Precondition: a != 0 */ diff --git a/contrib/compiler-rt/lib/divdf3.c b/contrib/compiler-rt/lib/divdf3.c index cc034dd..efce6bb 100644 --- a/contrib/compiler-rt/lib/divdf3.c +++ b/contrib/compiler-rt/lib/divdf3.c @@ -19,7 +19,7 @@ #define DOUBLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(ddiv, divdf3); +ARM_EABI_FNALIAS(ddiv, divdf3) fp_t __divdf3(fp_t a, fp_t b) { diff --git a/contrib/compiler-rt/lib/divmoddi4.c b/contrib/compiler-rt/lib/divmoddi4.c index a2b8714..2fe2b48 100644 --- a/contrib/compiler-rt/lib/divmoddi4.c +++ b/contrib/compiler-rt/lib/divmoddi4.c @@ -16,8 +16,6 @@ extern COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); -ARM_EABI_FNALIAS(ldivmod, divmoddi4); - /* Returns: a / b, *rem = a % b */ COMPILER_RT_ABI di_int diff --git a/contrib/compiler-rt/lib/divsf3.c b/contrib/compiler-rt/lib/divsf3.c index a8230e4..c91c648 100644 --- a/contrib/compiler-rt/lib/divsf3.c +++ b/contrib/compiler-rt/lib/divsf3.c @@ -19,7 +19,7 @@ #define SINGLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(fdiv, divsf3); +ARM_EABI_FNALIAS(fdiv, divsf3) fp_t __divsf3(fp_t a, fp_t b) { diff --git a/contrib/compiler-rt/lib/divsi3.c b/contrib/compiler-rt/lib/divsi3.c index 0d81cb8..cd19de9 100644 --- a/contrib/compiler-rt/lib/divsi3.c +++ b/contrib/compiler-rt/lib/divsi3.c @@ -18,7 +18,7 @@ su_int COMPILER_RT_ABI __udivsi3(su_int n, su_int d); /* Returns: a / b */ -ARM_EABI_FNALIAS(idiv, divsi3); +ARM_EABI_FNALIAS(idiv, divsi3) COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b) @@ -29,5 +29,11 @@ __divsi3(si_int a, si_int b) a = (a ^ s_a) - s_a; /* negate if s_a == -1 */ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */ s_a ^= s_b; /* sign of quotient */ - return (__udivsi3(a, b) ^ s_a) - s_a; /* negate if s_a == -1 */ + /* + * On CPUs without unsigned hardware division support, + * this calls __udivsi3 (notice the cast to su_int). + * On CPUs with unsigned hardware division support, + * this uses the unsigned division instruction. + */ + return ((su_int)a/(su_int)b ^ s_a) - s_a; /* negate if s_a == -1 */ } diff --git a/contrib/compiler-rt/lib/divti3.c b/contrib/compiler-rt/lib/divti3.c index 4ec3fa3..0242c13 100644 --- a/contrib/compiler-rt/lib/divti3.c +++ b/contrib/compiler-rt/lib/divti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); /* Returns: a / b */ diff --git a/contrib/compiler-rt/lib/extendsfdf2.c b/contrib/compiler-rt/lib/extendsfdf2.c index 9466de7..91fd2b4 100644 --- a/contrib/compiler-rt/lib/extendsfdf2.c +++ b/contrib/compiler-rt/lib/extendsfdf2.c @@ -66,7 +66,7 @@ static inline dst_t dstFromRep(dst_rep_t x) { // End helper routines. Conversion implementation follows. -ARM_EABI_FNALIAS(f2d, extendsfdf2); +ARM_EABI_FNALIAS(f2d, extendsfdf2) dst_t __extendsfdf2(src_t a) { diff --git a/contrib/compiler-rt/lib/ffsti2.c b/contrib/compiler-rt/lib/ffsti2.c index 948c696..27e15d5 100644 --- a/contrib/compiler-rt/lib/ffsti2.c +++ b/contrib/compiler-rt/lib/ffsti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: the index of the least significant 1-bit in a, or * the value zero if a is zero. The least significant bit is index one. */ diff --git a/contrib/compiler-rt/lib/fixdfdi.c b/contrib/compiler-rt/lib/fixdfdi.c index c6732db..7665ea5 100644 --- a/contrib/compiler-rt/lib/fixdfdi.c +++ b/contrib/compiler-rt/lib/fixdfdi.c @@ -23,7 +23,7 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(d2lz, fixdfdi); +ARM_EABI_FNALIAS(d2lz, fixdfdi) di_int __fixdfdi(double a) diff --git a/contrib/compiler-rt/lib/fixdfsi.c b/contrib/compiler-rt/lib/fixdfsi.c index 3d4379e..614d032 100644 --- a/contrib/compiler-rt/lib/fixdfsi.c +++ b/contrib/compiler-rt/lib/fixdfsi.c @@ -18,7 +18,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(d2iz, fixdfsi); +ARM_EABI_FNALIAS(d2iz, fixdfsi) int __fixdfsi(fp_t a) { diff --git a/contrib/compiler-rt/lib/fixdfti.c b/contrib/compiler-rt/lib/fixdfti.c index 4140d14..b110a94 100644 --- a/contrib/compiler-rt/lib/fixdfti.c +++ b/contrib/compiler-rt/lib/fixdfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a signed long long, rounding toward zero. */ /* Assumption: double is a IEEE 64 bit floating point type diff --git a/contrib/compiler-rt/lib/fixsfdi.c b/contrib/compiler-rt/lib/fixsfdi.c index 81ceab0..8a06690 100644 --- a/contrib/compiler-rt/lib/fixsfdi.c +++ b/contrib/compiler-rt/lib/fixsfdi.c @@ -23,7 +23,7 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(d2lz, fixsfdi); +ARM_EABI_FNALIAS(d2lz, fixsfdi) COMPILER_RT_ABI di_int __fixsfdi(float a) diff --git a/contrib/compiler-rt/lib/fixsfsi.c b/contrib/compiler-rt/lib/fixsfsi.c index f6de609..e3cc42d 100644 --- a/contrib/compiler-rt/lib/fixsfsi.c +++ b/contrib/compiler-rt/lib/fixsfsi.c @@ -16,7 +16,7 @@ #define SINGLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(f2iz, fixsfsi); +ARM_EABI_FNALIAS(f2iz, fixsfsi) COMPILER_RT_ABI int __fixsfsi(fp_t a) { diff --git a/contrib/compiler-rt/lib/fixsfti.c b/contrib/compiler-rt/lib/fixsfti.c index c64e5ae..c730ae0 100644 --- a/contrib/compiler-rt/lib/fixsfti.c +++ b/contrib/compiler-rt/lib/fixsfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a signed long long, rounding toward zero. */ /* Assumption: float is a IEEE 32 bit floating point type diff --git a/contrib/compiler-rt/lib/fixunsdfdi.c b/contrib/compiler-rt/lib/fixunsdfdi.c index c0ff160..9e63713 100644 --- a/contrib/compiler-rt/lib/fixunsdfdi.c +++ b/contrib/compiler-rt/lib/fixunsdfdi.c @@ -26,7 +26,7 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(d2ulz, fixunsdfdi); +ARM_EABI_FNALIAS(d2ulz, fixunsdfdi) COMPILER_RT_ABI du_int __fixunsdfdi(double a) diff --git a/contrib/compiler-rt/lib/fixunsdfsi.c b/contrib/compiler-rt/lib/fixunsdfsi.c index 2ce4999..c6a3c75 100644 --- a/contrib/compiler-rt/lib/fixunsdfsi.c +++ b/contrib/compiler-rt/lib/fixunsdfsi.c @@ -26,7 +26,7 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(d2uiz, fixunsdfsi); +ARM_EABI_FNALIAS(d2uiz, fixunsdfsi) COMPILER_RT_ABI su_int __fixunsdfsi(double a) diff --git a/contrib/compiler-rt/lib/fixunsdfti.c b/contrib/compiler-rt/lib/fixunsdfti.c index 524a207..fb0336f 100644 --- a/contrib/compiler-rt/lib/fixunsdfti.c +++ b/contrib/compiler-rt/lib/fixunsdfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a unsigned long long, rounding toward zero. * Negative values all become zero. */ diff --git a/contrib/compiler-rt/lib/fixunssfdi.c b/contrib/compiler-rt/lib/fixunssfdi.c index 09078db..69d5952 100644 --- a/contrib/compiler-rt/lib/fixunssfdi.c +++ b/contrib/compiler-rt/lib/fixunssfdi.c @@ -25,7 +25,7 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(f2ulz, fixunssfdi); +ARM_EABI_FNALIAS(f2ulz, fixunssfdi) COMPILER_RT_ABI du_int __fixunssfdi(float a) diff --git a/contrib/compiler-rt/lib/fixunssfsi.c b/contrib/compiler-rt/lib/fixunssfsi.c index d80ed18..e034139 100644 --- a/contrib/compiler-rt/lib/fixunssfsi.c +++ b/contrib/compiler-rt/lib/fixunssfsi.c @@ -26,7 +26,7 @@ /* seee eeee emmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(f2uiz, fixunssfsi); +ARM_EABI_FNALIAS(f2uiz, fixunssfsi) COMPILER_RT_ABI su_int __fixunssfsi(float a) diff --git a/contrib/compiler-rt/lib/fixunssfti.c b/contrib/compiler-rt/lib/fixunssfti.c index b807910..8f4c626 100644 --- a/contrib/compiler-rt/lib/fixunssfti.c +++ b/contrib/compiler-rt/lib/fixunssfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a unsigned long long, rounding toward zero. * Negative values all become zero. */ diff --git a/contrib/compiler-rt/lib/fixunsxfti.c b/contrib/compiler-rt/lib/fixunsxfti.c index f0e16db..260bfc0 100644 --- a/contrib/compiler-rt/lib/fixunsxfti.c +++ b/contrib/compiler-rt/lib/fixunsxfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a unsigned long long, rounding toward zero. * Negative values all become zero. */ diff --git a/contrib/compiler-rt/lib/fixxfti.c b/contrib/compiler-rt/lib/fixxfti.c index 1022770..973dc31 100644 --- a/contrib/compiler-rt/lib/fixxfti.c +++ b/contrib/compiler-rt/lib/fixxfti.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a signed long long, rounding toward zero. */ /* Assumption: long double is an intel 80 bit floating point type padded with 6 bytes diff --git a/contrib/compiler-rt/lib/floatdidf.c b/contrib/compiler-rt/lib/floatdidf.c index 2af9e10..e53fa25 100644 --- a/contrib/compiler-rt/lib/floatdidf.c +++ b/contrib/compiler-rt/lib/floatdidf.c @@ -22,7 +22,7 @@ /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */ -ARM_EABI_FNALIAS(l2d, floatdidf); +ARM_EABI_FNALIAS(l2d, floatdidf) #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag diff --git a/contrib/compiler-rt/lib/floatdisf.c b/contrib/compiler-rt/lib/floatdisf.c index 6607307..3e47580 100644 --- a/contrib/compiler-rt/lib/floatdisf.c +++ b/contrib/compiler-rt/lib/floatdisf.c @@ -22,7 +22,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(l2f, floatdisf); +ARM_EABI_FNALIAS(l2f, floatdisf) COMPILER_RT_ABI float __floatdisf(di_int a) diff --git a/contrib/compiler-rt/lib/floatsidf.c b/contrib/compiler-rt/lib/floatsidf.c index 74cb66b..18f378f 100644 --- a/contrib/compiler-rt/lib/floatsidf.c +++ b/contrib/compiler-rt/lib/floatsidf.c @@ -18,7 +18,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(i2d, floatsidf); +ARM_EABI_FNALIAS(i2d, floatsidf) fp_t __floatsidf(int a) { diff --git a/contrib/compiler-rt/lib/floatsisf.c b/contrib/compiler-rt/lib/floatsisf.c index a981391..8398393 100644 --- a/contrib/compiler-rt/lib/floatsisf.c +++ b/contrib/compiler-rt/lib/floatsisf.c @@ -18,7 +18,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(i2f, floatsisf); +ARM_EABI_FNALIAS(i2f, floatsisf) fp_t __floatsisf(int a) { diff --git a/contrib/compiler-rt/lib/floattidf.c b/contrib/compiler-rt/lib/floattidf.c index 3cafea8..77749f8 100644 --- a/contrib/compiler-rt/lib/floattidf.c +++ b/contrib/compiler-rt/lib/floattidf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a double, rounding toward even.*/ /* Assumption: double is a IEEE 64 bit floating point type diff --git a/contrib/compiler-rt/lib/floattisf.c b/contrib/compiler-rt/lib/floattisf.c index ab33e4a..4776125 100644 --- a/contrib/compiler-rt/lib/floattisf.c +++ b/contrib/compiler-rt/lib/floattisf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a float, rounding toward even. */ /* Assumption: float is a IEEE 32 bit floating point type diff --git a/contrib/compiler-rt/lib/floattixf.c b/contrib/compiler-rt/lib/floattixf.c index 852acc7..3813dc6 100644 --- a/contrib/compiler-rt/lib/floattixf.c +++ b/contrib/compiler-rt/lib/floattixf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a long double, rounding toward even. */ /* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits diff --git a/contrib/compiler-rt/lib/floatundidf.c b/contrib/compiler-rt/lib/floatundidf.c index 6791701..e52fa0a 100644 --- a/contrib/compiler-rt/lib/floatundidf.c +++ b/contrib/compiler-rt/lib/floatundidf.c @@ -22,7 +22,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(ul2d, floatundidf); +ARM_EABI_FNALIAS(ul2d, floatundidf) #ifndef __SOFT_FP__ /* Support for systems that have hardware floating-point; we'll set the inexact flag diff --git a/contrib/compiler-rt/lib/floatundisf.c b/contrib/compiler-rt/lib/floatundisf.c index 1bf5fbb..713a44a 100644 --- a/contrib/compiler-rt/lib/floatundisf.c +++ b/contrib/compiler-rt/lib/floatundisf.c @@ -22,7 +22,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(ul2f, floatundisf); +ARM_EABI_FNALIAS(ul2f, floatundisf) COMPILER_RT_ABI float __floatundisf(du_int a) diff --git a/contrib/compiler-rt/lib/floatunsidf.c b/contrib/compiler-rt/lib/floatunsidf.c index 0722248..ba6c2cf 100644 --- a/contrib/compiler-rt/lib/floatunsidf.c +++ b/contrib/compiler-rt/lib/floatunsidf.c @@ -18,7 +18,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(ui2d, floatunsidf); +ARM_EABI_FNALIAS(ui2d, floatunsidf) fp_t __floatunsidf(unsigned int a) { diff --git a/contrib/compiler-rt/lib/floatunsisf.c b/contrib/compiler-rt/lib/floatunsisf.c index 3dc1cd4..e392c0e 100644 --- a/contrib/compiler-rt/lib/floatunsisf.c +++ b/contrib/compiler-rt/lib/floatunsisf.c @@ -18,7 +18,7 @@ #include "int_lib.h" -ARM_EABI_FNALIAS(ui2f, floatunsisf); +ARM_EABI_FNALIAS(ui2f, floatunsisf) fp_t __floatunsisf(unsigned int a) { diff --git a/contrib/compiler-rt/lib/floatuntidf.c b/contrib/compiler-rt/lib/floatuntidf.c index d0889a0..4c1d328 100644 --- a/contrib/compiler-rt/lib/floatuntidf.c +++ b/contrib/compiler-rt/lib/floatuntidf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a double, rounding toward even. */ /* Assumption: double is a IEEE 64 bit floating point type diff --git a/contrib/compiler-rt/lib/floatuntisf.c b/contrib/compiler-rt/lib/floatuntisf.c index f552758..c8da260 100644 --- a/contrib/compiler-rt/lib/floatuntisf.c +++ b/contrib/compiler-rt/lib/floatuntisf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a float, rounding toward even. */ /* Assumption: float is a IEEE 32 bit floating point type diff --git a/contrib/compiler-rt/lib/floatuntixf.c b/contrib/compiler-rt/lib/floatuntixf.c index 00c07d8..dbce80f 100644 --- a/contrib/compiler-rt/lib/floatuntixf.c +++ b/contrib/compiler-rt/lib/floatuntixf.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: convert a to a long double, rounding toward even. */ /* Assumption: long double is a IEEE 80 bit floating point type padded to 128 bits diff --git a/contrib/compiler-rt/lib/fp_lib.h b/contrib/compiler-rt/lib/fp_lib.h index de5f17f..661119a 100644 --- a/contrib/compiler-rt/lib/fp_lib.h +++ b/contrib/compiler-rt/lib/fp_lib.h @@ -124,7 +124,7 @@ static inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) { *lo = *lo << count; } -static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, int count) { +static inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) { if (count < typeWidth) { const bool sticky = *lo << (typeWidth - count); *lo = *hi << (typeWidth - count) | *lo >> count | sticky; diff --git a/contrib/compiler-rt/lib/int_endianness.h b/contrib/compiler-rt/lib/int_endianness.h index 9466ed4..70bd1773 100644 --- a/contrib/compiler-rt/lib/int_endianness.h +++ b/contrib/compiler-rt/lib/int_endianness.h @@ -31,7 +31,7 @@ /* .. */ -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__minix) #include <sys/endian.h> #if _BYTE_ORDER == _BIG_ENDIAN @@ -80,6 +80,13 @@ #endif /* GNU/Linux */ +#if defined(_WIN32) + +#define _YUGA_LITTLE_ENDIAN 1 +#define _YUGA_BIG_ENDIAN 0 + +#endif /* Windows */ + /* . */ #if !defined(_YUGA_LITTLE_ENDIAN) || !defined(_YUGA_BIG_ENDIAN) diff --git a/contrib/compiler-rt/lib/int_util.c b/contrib/compiler-rt/lib/int_util.c index f194768..871d191 100644 --- a/contrib/compiler-rt/lib/int_util.c +++ b/contrib/compiler-rt/lib/int_util.c @@ -29,6 +29,19 @@ void compilerrt_abort_impl(const char *file, int line, const char *function) { panic("%s:%d: abort in %s", file, line, function); } +#elif __APPLE__ && !__STATIC__ + +/* from libSystem.dylib */ +extern void __assert_rtn(const char *func, const char *file, + int line, const char * message) __attribute__((noreturn)); + +__attribute__((weak)) +__attribute__((visibility("hidden"))) +void compilerrt_abort_impl(const char *file, int line, const char *function) { + __assert_rtn(function, file, line, "libcompiler_rt abort"); +} + + #else /* Get the system definition of abort() */ diff --git a/contrib/compiler-rt/lib/int_util.h b/contrib/compiler-rt/lib/int_util.h index 17d7722..1348b85 100644 --- a/contrib/compiler-rt/lib/int_util.h +++ b/contrib/compiler-rt/lib/int_util.h @@ -22,11 +22,8 @@ /** \brief Trigger a program abort (or panic for kernel code). */ #define compilerrt_abort() compilerrt_abort_impl(__FILE__, __LINE__, \ __FUNCTION__) + void compilerrt_abort_impl(const char *file, int line, - const char *function) -#ifndef KERNEL_USE - __attribute__((weak)) -#endif - __attribute__((noreturn)) __attribute__((visibility("hidden"))); + const char *function) __attribute__((noreturn)); #endif /* INT_UTIL_H */ diff --git a/contrib/compiler-rt/lib/lshrdi3.c b/contrib/compiler-rt/lib/lshrdi3.c index 8af3e0c..6b1ea92 100644 --- a/contrib/compiler-rt/lib/lshrdi3.c +++ b/contrib/compiler-rt/lib/lshrdi3.c @@ -18,7 +18,7 @@ /* Precondition: 0 <= b < bits_in_dword */ -ARM_EABI_FNALIAS(llsr, lshrdi3); +ARM_EABI_FNALIAS(llsr, lshrdi3) COMPILER_RT_ABI di_int __lshrdi3(di_int a, si_int b) diff --git a/contrib/compiler-rt/lib/lshrti3.c b/contrib/compiler-rt/lib/lshrti3.c index 5fdd99e..be76814 100644 --- a/contrib/compiler-rt/lib/lshrti3.c +++ b/contrib/compiler-rt/lib/lshrti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: logical a >> b */ /* Precondition: 0 <= b < bits_in_tword */ diff --git a/contrib/compiler-rt/lib/modti3.c b/contrib/compiler-rt/lib/modti3.c index dbe5e94..752202d 100644 --- a/contrib/compiler-rt/lib/modti3.c +++ b/contrib/compiler-rt/lib/modti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); /*Returns: a % b */ diff --git a/contrib/compiler-rt/lib/muldf3.c b/contrib/compiler-rt/lib/muldf3.c index 86d72d8..c38edba 100644 --- a/contrib/compiler-rt/lib/muldf3.c +++ b/contrib/compiler-rt/lib/muldf3.c @@ -15,7 +15,7 @@ #define DOUBLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(dmul, muldf3); +ARM_EABI_FNALIAS(dmul, muldf3) COMPILER_RT_ABI fp_t __muldf3(fp_t a, fp_t b) { @@ -96,7 +96,7 @@ __muldf3(fp_t a, fp_t b) { // a zero of the appropriate sign. Mathematically there is no need to // handle this case separately, but we make it a special case to // simplify the shift logic. - const int shift = 1 - productExponent; + const unsigned int shift = 1U - (unsigned int)productExponent; if (shift >= typeWidth) return fromRep(productSign); // Otherwise, shift the significand of the result so that the round diff --git a/contrib/compiler-rt/lib/muldi3.c b/contrib/compiler-rt/lib/muldi3.c index 3e99630..2dae44c 100644 --- a/contrib/compiler-rt/lib/muldi3.c +++ b/contrib/compiler-rt/lib/muldi3.c @@ -40,7 +40,7 @@ __muldsi3(su_int a, su_int b) /* Returns: a * b */ -ARM_EABI_FNALIAS(lmul, muldi3); +ARM_EABI_FNALIAS(lmul, muldi3) COMPILER_RT_ABI di_int __muldi3(di_int a, di_int b) diff --git a/contrib/compiler-rt/lib/muloti4.c b/contrib/compiler-rt/lib/muloti4.c index 1fcd0ba..f58dd07 100644 --- a/contrib/compiler-rt/lib/muloti4.c +++ b/contrib/compiler-rt/lib/muloti4.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a * b */ /* Effects: sets *overflow to 1 if a * b overflows */ diff --git a/contrib/compiler-rt/lib/mulsf3.c b/contrib/compiler-rt/lib/mulsf3.c index fce2fd4..861a9ba 100644 --- a/contrib/compiler-rt/lib/mulsf3.c +++ b/contrib/compiler-rt/lib/mulsf3.c @@ -15,7 +15,7 @@ #define SINGLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(fmul, mulsf3); +ARM_EABI_FNALIAS(fmul, mulsf3) COMPILER_RT_ABI fp_t __mulsf3(fp_t a, fp_t b) { @@ -92,7 +92,7 @@ __mulsf3(fp_t a, fp_t b) { if (productExponent <= 0) { // Result is denormal before rounding, the exponent is zero and we // need to shift the significand. - wideRightShiftWithSticky(&productHi, &productLo, 1 - productExponent); + wideRightShiftWithSticky(&productHi, &productLo, 1U - (unsigned)productExponent); } else { diff --git a/contrib/compiler-rt/lib/multi3.c b/contrib/compiler-rt/lib/multi3.c index ad8ab3f..0b8730f 100644 --- a/contrib/compiler-rt/lib/multi3.c +++ b/contrib/compiler-rt/lib/multi3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a * b */ static diff --git a/contrib/compiler-rt/lib/mulvti3.c b/contrib/compiler-rt/lib/mulvti3.c index ae65cf8..31f7d2f 100644 --- a/contrib/compiler-rt/lib/mulvti3.c +++ b/contrib/compiler-rt/lib/mulvti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a * b */ /* Effects: aborts if a * b overflows */ diff --git a/contrib/compiler-rt/lib/negdf2.c b/contrib/compiler-rt/lib/negdf2.c index b11b480..4e17513 100644 --- a/contrib/compiler-rt/lib/negdf2.c +++ b/contrib/compiler-rt/lib/negdf2.c @@ -14,7 +14,7 @@ #define DOUBLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(dneg, negdf2); +ARM_EABI_FNALIAS(dneg, negdf2) fp_t __negdf2(fp_t a) { return fromRep(toRep(a) ^ signBit); diff --git a/contrib/compiler-rt/lib/negsf2.c b/contrib/compiler-rt/lib/negsf2.c index f8ef2d1..29c17be 100644 --- a/contrib/compiler-rt/lib/negsf2.c +++ b/contrib/compiler-rt/lib/negsf2.c @@ -14,7 +14,7 @@ #define SINGLE_PRECISION #include "fp_lib.h" -ARM_EABI_FNALIAS(fneg, negsf2); +ARM_EABI_FNALIAS(fneg, negsf2) COMPILER_RT_ABI fp_t __negsf2(fp_t a) { diff --git a/contrib/compiler-rt/lib/negti2.c b/contrib/compiler-rt/lib/negti2.c index 774e808..f7e4ad3 100644 --- a/contrib/compiler-rt/lib/negti2.c +++ b/contrib/compiler-rt/lib/negti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: -a */ ti_int diff --git a/contrib/compiler-rt/lib/negvti2.c b/contrib/compiler-rt/lib/negvti2.c index ef766bb..05df615 100644 --- a/contrib/compiler-rt/lib/negvti2.c +++ b/contrib/compiler-rt/lib/negvti2.c @@ -12,10 +12,10 @@ *===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: -a */ /* Effects: aborts if -a overflows */ diff --git a/contrib/compiler-rt/lib/parityti2.c b/contrib/compiler-rt/lib/parityti2.c index 8f85745..a1f47b1 100644 --- a/contrib/compiler-rt/lib/parityti2.c +++ b/contrib/compiler-rt/lib/parityti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: 1 if number of bits is odd else returns 0 */ si_int __paritydi2(di_int a); diff --git a/contrib/compiler-rt/lib/popcountti2.c b/contrib/compiler-rt/lib/popcountti2.c index 68d9427..9566673 100644 --- a/contrib/compiler-rt/lib/popcountti2.c +++ b/contrib/compiler-rt/lib/popcountti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: count of 1 bits */ si_int diff --git a/contrib/compiler-rt/lib/powitf2.c b/contrib/compiler-rt/lib/powitf2.c index 189632c..d3b9349 100644 --- a/contrib/compiler-rt/lib/powitf2.c +++ b/contrib/compiler-rt/lib/powitf2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if _ARCH_PPC - #include "int_lib.h" +#if _ARCH_PPC + /* Returns: a ^ b */ long double diff --git a/contrib/compiler-rt/lib/subdf3.c b/contrib/compiler-rt/lib/subdf3.c index 5eb1853..66fb1a5 100644 --- a/contrib/compiler-rt/lib/subdf3.c +++ b/contrib/compiler-rt/lib/subdf3.c @@ -18,7 +18,7 @@ fp_t COMPILER_RT_ABI __adddf3(fp_t a, fp_t b); -ARM_EABI_FNALIAS(dsub, subdf3); +ARM_EABI_FNALIAS(dsub, subdf3) // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t diff --git a/contrib/compiler-rt/lib/subsf3.c b/contrib/compiler-rt/lib/subsf3.c index 351be0ef..3659cd8 100644 --- a/contrib/compiler-rt/lib/subsf3.c +++ b/contrib/compiler-rt/lib/subsf3.c @@ -17,7 +17,7 @@ fp_t COMPILER_RT_ABI __addsf3(fp_t a, fp_t b); -ARM_EABI_FNALIAS(fsub, subsf3); +ARM_EABI_FNALIAS(fsub, subsf3) // Subtraction; flip the sign bit of b and add. COMPILER_RT_ABI fp_t diff --git a/contrib/compiler-rt/lib/subvti3.c b/contrib/compiler-rt/lib/subvti3.c index 44127b7..b32df5e 100644 --- a/contrib/compiler-rt/lib/subvti3.c +++ b/contrib/compiler-rt/lib/subvti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: a - b */ /* Effects: aborts if a - b overflows */ diff --git a/contrib/compiler-rt/lib/truncdfsf2.c b/contrib/compiler-rt/lib/truncdfsf2.c index f57af7e..61c909a 100644 --- a/contrib/compiler-rt/lib/truncdfsf2.c +++ b/contrib/compiler-rt/lib/truncdfsf2.c @@ -64,7 +64,7 @@ static inline dst_t dstFromRep(dst_rep_t x) { // End helper routines. Conversion implementation follows. -ARM_EABI_FNALIAS(d2f, truncdfsf2); +ARM_EABI_FNALIAS(d2f, truncdfsf2) COMPILER_RT_ABI dst_t __truncdfsf2(src_t a) { diff --git a/contrib/compiler-rt/lib/ucmpti2.c b/contrib/compiler-rt/lib/ucmpti2.c index 11137c5..5466d21 100644 --- a/contrib/compiler-rt/lib/ucmpti2.c +++ b/contrib/compiler-rt/lib/ucmpti2.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Returns: if (a < b) returns 0 * if (a == b) returns 1 * if (a > b) returns 2 diff --git a/contrib/compiler-rt/lib/udivmoddi4.c b/contrib/compiler-rt/lib/udivmoddi4.c index 73043d4..57282d5 100644 --- a/contrib/compiler-rt/lib/udivmoddi4.c +++ b/contrib/compiler-rt/lib/udivmoddi4.c @@ -20,8 +20,6 @@ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ -ARM_EABI_FNALIAS(uldivmod, udivmoddi4); - COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem) { diff --git a/contrib/compiler-rt/lib/udivmodti4.c b/contrib/compiler-rt/lib/udivmodti4.c index 427861b..f619c74 100644 --- a/contrib/compiler-rt/lib/udivmodti4.c +++ b/contrib/compiler-rt/lib/udivmodti4.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + /* Effects: if rem != 0, *rem = a % b * Returns: a / b */ diff --git a/contrib/compiler-rt/lib/udivsi3.c b/contrib/compiler-rt/lib/udivsi3.c index 39ef48b..5d0140c 100644 --- a/contrib/compiler-rt/lib/udivsi3.c +++ b/contrib/compiler-rt/lib/udivsi3.c @@ -18,8 +18,9 @@ /* Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide */ -ARM_EABI_FNALIAS(uidiv, udivsi3); +ARM_EABI_FNALIAS(uidiv, udivsi3) +/* This function should not call __divsi3! */ COMPILER_RT_ABI su_int __udivsi3(su_int n, su_int d) { diff --git a/contrib/compiler-rt/lib/udivti3.c b/contrib/compiler-rt/lib/udivti3.c index 7405a0f..d9e1bb4 100644 --- a/contrib/compiler-rt/lib/udivti3.c +++ b/contrib/compiler-rt/lib/udivti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); /* Returns: a / b */ diff --git a/contrib/compiler-rt/lib/umodti3.c b/contrib/compiler-rt/lib/umodti3.c index 8f20c5f..8ebe7f0 100644 --- a/contrib/compiler-rt/lib/umodti3.c +++ b/contrib/compiler-rt/lib/umodti3.c @@ -12,10 +12,10 @@ * ===----------------------------------------------------------------------=== */ -#if __x86_64 - #include "int_lib.h" +#if __x86_64 + tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); /* Returns: a % b */ |