aports/testing/llvm-next/0013-Standalone-libatomic.patch

153 lines
6.9 KiB
Diff

Changes to atomic.c are based on libatomic-chimera
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -270,7 +270,8 @@ function(add_compiler_rt_runtime name type)
endif()
endif()
if(COMPILER_RT_USE_BUILTINS_LIBRARY AND NOT type STREQUAL "OBJECT" AND
- NOT name STREQUAL "clang_rt.builtins")
+ NOT name STREQUAL "clang_rt.builtins" AND
+ NOT name STREQUAL "clang_rt.atomic")
get_compiler_rt_target(${arch} target)
find_compiler_rt_library(builtins builtins_${libname} TARGET ${target})
if(builtins_${libname} STREQUAL "NOTFOUND")
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -959,6 +959,7 @@ option(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC
if(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC)
add_custom_target(builtins-standalone-atomic)
+ add_dependencies(builtins-standalone-atomic builtins)
set(BUILTIN_TYPE SHARED)
if(OS_NAME MATCHES "AIX")
include(CompilerRTAIXUtils)
@@ -969,8 +970,6 @@ if(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC)
# For different versions of cmake, SHARED behaves differently. For some
# versions, we might need MODULE rather than SHARED.
get_aix_libatomic_type(BUILTIN_TYPE)
- else()
- list(APPEND COMPILER_RT_LIBATOMIC_LINK_FLAGS -nodefaultlibs)
endif()
foreach (arch ${BUILTIN_SUPPORTED_ARCH})
if(CAN_TARGET_${arch})
@@ -979,10 +978,15 @@ if(COMPILER_RT_BUILD_STANDALONE_LIBATOMIC)
add_compiler_rt_runtime(clang_rt.atomic
${BUILTIN_TYPE}
ARCHS ${arch}
- SOURCES atomic.c
+ SOURCES "atomic.c;atomic_flag_clear.c;atomic_flag_clear_explicit.c;atomic_flag_test_and_set.c;atomic_flag_test_and_set_explicit.c;atomic_signal_fence.c;atomic_thread_fence.c"
LINK_FLAGS ${COMPILER_RT_LIBATOMIC_LINK_FLAGS}
LINK_LIBS ${COMPILER_RT_LIBATOMIC_LINK_LIBS_${arch}}
PARENT_TARGET builtins-standalone-atomic)
+ set_target_properties(clang_rt.atomic-dynamic-${arch}
+ PROPERTIES
+ OUTPUT_NAME "atomic"
+ SOVERSION "1"
+ )
endif()
endforeach()
# FIXME: On AIX, we have to archive built shared libraries into a static
--- a/compiler-rt/lib/builtins/atomic.c
+++ b/compiler-rt/lib/builtins/atomic.c
@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#include <fenv.h>
#include "assembly.h"
@@ -346,6 +347,18 @@ OPTIMISED_CASES
*ptr = tmp op val; \
unlock(l); \
return tmp; \
+ } \
+ \
+ type __atomic_##opname##_fetch_##n(type *ptr, type val, int model) { \
+ if (lockfree(ptr)) \
+ return __atomic_##opname##_fetch(ptr, val, model); \
+ Lock *l = lock_for_pointer(ptr); \
+ lock(l); \
+ type tmp = *ptr; \
+ tmp = tmp op val; \
+ *ptr = tmp; \
+ unlock(l); \
+ return tmp; \
}
#define ATOMIC_RMW_NAND(n, lockfree, type) \
@@ -358,6 +371,30 @@ OPTIMISED_CASES
*ptr = ~(tmp & val); \
unlock(l); \
return tmp; \
+ } \
+ \
+ type __atomic_nand_fetch_##n(type *ptr, type val, int model) { \
+ if (lockfree(ptr)) \
+ return __atomic_nand_fetch(ptr, val, model); \
+ Lock *l = lock_for_pointer(ptr); \
+ lock(l); \
+ type tmp = *ptr; \
+ tmp = ~(tmp & val); \
+ *ptr = tmp; \
+ unlock(l); \
+ return tmp; \
+ }
+
+#define ATOMIC_TAS(n, lockfree, type) \
+ bool __atomic_test_and_set_##n(type *ptr, int model) { \
+ if (lockfree(ptr)) \
+ return __atomic_test_and_set(ptr, model); \
+ Lock *l = lock_for_pointer(ptr); \
+ lock(l); \
+ type tmp = *ptr; \
+ *ptr = 1; \
+ unlock(l); \
+ return !!tmp; \
}
#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, add, +)
@@ -381,3 +418,42 @@ OPTIMISED_CASES
OPTIMISED_CASES
#undef OPTIMISED_CASE
#endif
+#define OPTIMISED_CASE(n, lockfree, type) ATOMIC_TAS(n, lockfree, type)
+OPTIMISED_CASES
+#undef OPTIMISED_CASE
+
+/* provided by gcc libatomic */
+
+void __atomic_feraiseexcept(int e) {
+ volatile float r __attribute__((unused));
+#ifdef FE_INVALID
+ if (e & FE_INVALID) {
+ volatile float z = 0.0f;
+ r = z / z;
+ }
+#endif
+#ifdef FE_DIVBYZERO
+ if (e & FE_DIVBYZERO) {
+ volatile float z = 0.0f;
+ r = 1.0f / z;
+ }
+#endif
+#ifdef FE_OVERFLOW
+ if (e & FE_OVERFLOW) {
+ volatile float m = __FLT_MAX__;
+ r = m * m;
+ }
+#endif
+#ifdef FE_UNDERFLOW
+ if (e & FE_UNDERFLOW) {
+ volatile float m = __FLT_MIN__;
+ r = m * m;
+ }
+#endif
+#ifdef FE_INEXACT
+ if (e & FE_INEXACT) {
+ volatile float t = 3.0f;
+ r = 1.0f / t;
+ }
+#endif
+}