From: Andrei Tatar Date: Fri, 5 May 2023 19:20:40 +0000 (+0200) Subject: Update to LLVM 14.0.6 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=d53cbfe6035f;p=unikraft%2Flibs%2Fcompiler-rt.git Update to LLVM 14.0.6 Co-authored-by: Marco Schlumpp Signed-off-by: Marco Schlumpp Signed-off-by: Andrei Tatar --- diff --git a/Makefile.uk b/Makefile.uk index ff0c73a..4a32fd1 100644 --- a/Makefile.uk +++ b/Makefile.uk @@ -1,8 +1,11 @@ # libcompiler_rt Makefile.uk # # Authors: Vlad-Andrei Badoiu +# Marco Schlumpp +# Andrei Tatar # # Copyright (c) 2019, NEC Europe Ltd., NEC Corporation. All rights reserved. +# Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -44,8 +47,8 @@ endif ################################################################################ # Sources ################################################################################ -LIBCOMPILER_RT_VERSION=7.0.0 -LIBCOMPILER_RT_URL=http://releases.llvm.org/$(LIBCOMPILER_RT_VERSION)/compiler-rt-$(LIBCOMPILER_RT_VERSION).src.tar.xz +LIBCOMPILER_RT_VERSION=14.0.6 +LIBCOMPILER_RT_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-$(LIBCOMPILER_RT_VERSION)/compiler-rt-$(LIBCOMPILER_RT_VERSION).src.tar.xz LIBCOMPILER_RT_PATCHDIR=$(LIBCOMPILER_RT_BASE)/patches $(eval $(call fetch,libcompiler_rt,$(LIBCOMPILER_RT_URL))) $(eval $(call patch,libcompiler_rt,$(LIBCOMPILER_RT_PATCHDIR),compiler-rt-$(LIBCOMPILER_RT_VERSION).src)) @@ -53,25 +56,23 @@ $(eval $(call patch,libcompiler_rt,$(LIBCOMPILER_RT_PATCHDIR),compiler-rt-$(LIBC ################################################################################ # Helpers ################################################################################ -LIBCOMPILER_RT_SUBDIR=compiler-rt-$(LIBCOMPILER_RT_VERSION).src -LIBCOMPILER_RT_SRC=$(LIBCOMPILER_RT_ORIGIN)/$(LIBCOMPILER_RT_SUBDIR) +LIBCOMPILER_RT_SRC=$(LIBCOMPILER_RT_ORIGIN)/compiler-rt-$(LIBCOMPILER_RT_VERSION).src ################################################################################ # Library includes ################################################################################ CINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/lib CINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/lib/builtins -CINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/include CXXINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/lib CXXINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/lib/builtins -CXXINCLUDES-$(CONFIG_LIBCOMPILER_RT) += -I$(LIBCOMPILER_RT_SRC)/include ################################################################################ # Global flags ################################################################################ +LIBCOMPILER_RT_SUPPRESS_FLAGS += -Wno-unused-parameter +LIBCOMPILER_RT_SUPPRESS_FLAGS += -Wno-builtin-declaration-mismatch -LIBCOMPILER_RT_SUPPRESS_FLAGS += -Wno-unused-parameter -Wno-builtin-declaration-mismatch LIBCOMPILER_RT_CFLAGS-y += $(LIBCOMPILER_RT_SUPPRESS_FLAGS) LIBCOMPILER_RT_CXXFLAGS-y += $(LIBCOMPILER_RT_SUPPRESS_FLAGS) @@ -107,17 +108,22 @@ LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ctzdi2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ctzsi2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ctzti2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divdc3.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divdf3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divdi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divmoddi4.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divmodsi4.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divmodti4.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divsc3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divsf3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divsi3.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divtc3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divtf3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divti3.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/divxc3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/enable_execute_stack.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/extenddftf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/extendhfsf2.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/extendhftf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/extendsfdf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/extendsftf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ffsdi2.c @@ -168,11 +174,11 @@ LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/floatuntidf.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/floatuntisf.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/floatuntitf.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/floatuntixf.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/fp_mode.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/gcc_personality_v0.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/int_util.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/lshrdi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/lshrti3.c -LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/mingw_fixfloat.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/moddi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/modsi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/modti3.c @@ -220,6 +226,7 @@ LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/truncdfhf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/truncdfsf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/truncsfhf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/trunctfdf2.c +LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/trunctfhf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/trunctfsf2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ucmpdi2.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/ucmpti2.c @@ -232,12 +239,15 @@ LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/udivti3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/umoddi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/umodsi3.c LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/umodti3.c + LIBCOMPILER_RT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBCOMPILER_RT_SRC)/lib/builtins/cpu_model.c LIBCOMPILER_RT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBCOMPILER_RT_SRC)/lib/builtins/x86_64/chkstk2.S LIBCOMPILER_RT_SRCS-$(CONFIG_ARCH_X86_64) += $(LIBCOMPILER_RT_SRC)/lib/builtins/x86_64/chkstk.S -ifdef CONFIG_LIBCOMPILER_RT_ATOMIC -LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic.c -endif - -LIBCOMPILER_RT_SRCS-y += $(LIBCOMPILER_RT_BASE)/lib/builtins/clrsbdi2.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_flag_clear.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_flag_clear_explicit.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_flag_test_and_set.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_flag_test_and_set_explicit.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_signal_fence.c +LIBCOMPILER_RT_SRCS-$(CONFIG_LIBCOMPILER_RT_ATOMIC) += $(LIBCOMPILER_RT_SRC)/lib/builtins/atomic_thread_fence.c diff --git a/lib/builtins/clrsbdi2.c b/lib/builtins/clrsbdi2.c deleted file mode 100644 index 286d510..0000000 --- a/lib/builtins/clrsbdi2.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2013-2017 Free Software Foundation, Inc. - This file is part of GCC. - GCC is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License as published by the Free - Software Foundation; either version 3, or (at your option) any later - version. - GCC is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . -*/ - -#include - -/* Returns: Number of leading zeroes */ - - -COMPILER_RT_ABI di_int -__clrsbdi2(di_int x) -{ - int ret; - if (x < 0LL) - x = ~x; - if (x == 0LL) - return 8 * sizeof (x) -1; - ret = __builtin_clz((du_int) x); - return ret - 1; -} diff --git a/patches/0001-Modify-atomic.c-to-build-with-GCC.patch b/patches/0001-Modify-atomic.c-to-build-with-GCC.patch deleted file mode 100644 index e9210b0..0000000 --- a/patches/0001-Modify-atomic.c-to-build-with-GCC.patch +++ /dev/null @@ -1,297 +0,0 @@ -From 0a15b98d110b348ebf8d7e02db8b75786e61ffad Mon Sep 17 00:00:00 2001 -From: Vlad-Andrei Badoiu -Date: Thu, 31 Oct 2019 00:07:16 +0200 -Subject: [PATCH 1/1] Modify atomic.c to build with GCC - -Signed-off-by: Vlad-Andrei Badoiu ---- - lib/builtins/atomic.c | 148 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 146 insertions(+), 2 deletions(-) - -diff --git a/lib/builtins/atomic.c b/lib/builtins/atomic.c -index ee35e34..1a78ed0 100644 ---- a/lib/builtins/atomic.c -+++ b/lib/builtins/atomic.c -@@ -64,8 +64,13 @@ __inline static void unlock(Lock *l) { - } - __inline static void lock(Lock *l) { - uint32_t old = 1; -+#ifdef __GNUC__ -+ while (!_atomic_compare_exchange_n((_Atomic(uint32_t)*)&l->_count, &old, -+#endif -+#ifdef __clang__ - while (!__c11_atomic_compare_exchange_weak((_Atomic(uint32_t)*)&l->_count, &old, -- 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { -+#endif -+ 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { - _umtx_op(l, UMTX_OP_SEM_WAIT, 0, 0, 0); - old = 1; - } -@@ -90,13 +95,24 @@ static Lock locks[SPINLOCK_COUNT]; // initialized to OS_SPINLOCK_INIT which is 0 - typedef _Atomic(uintptr_t) Lock; - /// Unlock a lock. This is a release operation. - __inline static void unlock(Lock *l) { -+#ifdef __GNUC__ -+ __atomic_store_n(l, 0, __ATOMIC_RELEASE); -+#endif -+#ifdef __clang__ - __c11_atomic_store(l, 0, __ATOMIC_RELEASE); -+#endif - } - /// 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; -+#ifdef __GNUC__ -+ while (!__atomic_compare_exchange_n(l, &old, 1, 1, __ATOMIC_ACQUIRE, -+#endif -+ -+#ifdef __clang__ - while (!__c11_atomic_compare_exchange_weak(l, &old, 1, __ATOMIC_ACQUIRE, -+#endif - __ATOMIC_RELAXED)) - old = 0; - } -@@ -125,12 +141,21 @@ static __inline Lock *lock_for_pointer(void *ptr) { - /// 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. -+#ifdef __GNUC__ -+#define IS_LOCK_FREE_1 __atomic_is_lock_free(1, 0) -+#define IS_LOCK_FREE_2 __atomic_is_lock_free(2, 0) -+#define IS_LOCK_FREE_4 __atomic_is_lock_free(4, 0) -+#define IS_LOCK_FREE_8 __atomic_is_lock_free(8, 0) -+#define IS_LOCK_FREE_16 0 -+#endif -+ -+#ifdef __clang__ - #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 -- -+#endif - /// Macro that calls the compiler-generated lock-free versions of functions - /// when they exist. - #define LOCK_FREE_CASES() \ -@@ -160,9 +185,17 @@ static __inline Lock *lock_for_pointer(void *ptr) { - /// 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) { -+#ifdef __GNUC__ -+#define LOCK_FREE_ACTION(type) \ -+ *((type*)dest) = __atomic_load_n((_Atomic(type)*)src, model);\ -+ return; -+#endif -+ -+#ifdef __clang__ - #define LOCK_FREE_ACTION(type) \ - *((type*)dest) = __c11_atomic_load((_Atomic(type)*)src, model);\ - return; -+#endif - LOCK_FREE_CASES(); - #undef LOCK_FREE_ACTION - Lock *l = lock_for_pointer(src); -@@ -174,9 +207,17 @@ void __atomic_load_c(int size, void *src, void *dest, int model) { - /// 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) { -+#ifdef __GNUC__ -+#define LOCK_FREE_ACTION(type) \ -+ __atomic_store_n((_Atomic(type)*)dest, *(type*)dest, model);\ -+ return; -+#endif -+ -+#ifdef __clang__ - #define LOCK_FREE_ACTION(type) \ - __c11_atomic_store((_Atomic(type)*)dest, *(type*)dest, model);\ - return; -+#endif - LOCK_FREE_CASES(); - #undef LOCK_FREE_ACTION - Lock *l = lock_for_pointer(dest); -@@ -192,9 +233,17 @@ void __atomic_store_c(int size, void *dest, void *src, int model) { - /// 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) { -+#ifdef __GNUC__ -+#define LOCK_FREE_ACTION(type) \ -+ return __atomic_compare_exchange_n((_Atomic(type)*)ptr, (type*)expected,\ -+ *(type*)desired, 0, success, failure) -+#endif -+ -+#ifdef __clang__ - #define LOCK_FREE_ACTION(type) \ - return __c11_atomic_compare_exchange_strong((_Atomic(type)*)ptr, (type*)expected,\ - *(type*)desired, success, failure) -+#endif - LOCK_FREE_CASES(); - #undef LOCK_FREE_ACTION - Lock *l = lock_for_pointer(ptr); -@@ -212,10 +261,19 @@ int __atomic_compare_exchange_c(int size, void *ptr, void *expected, - /// 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) { -+#ifdef __GNUC__ -+#define LOCK_FREE_ACTION(type) \ -+ *(type*)old = __atomic_exchange_n((_Atomic(type)*)ptr, *(type*)val,\ -+ model);\ -+ return; -+#endif -+ -+#ifdef __clang__ - #define LOCK_FREE_ACTION(type) \ - *(type*)old = __c11_atomic_exchange((_Atomic(type)*)ptr, *(type*)val,\ - model);\ - return; -+#endif - LOCK_FREE_CASES(); - #undef LOCK_FREE_ACTION - Lock *l = lock_for_pointer(ptr); -@@ -244,6 +302,20 @@ void __atomic_exchange_c(int size, void *ptr, void *val, void *old, int model) { - OPTIMISED_CASE(8, IS_LOCK_FREE_8, uint64_t) - #endif - -+#ifdef __GNUC__ -+#define OPTIMISED_CASE(n, lockfree, type)\ -+type __atomic_load_##n(type *src, int model) {\ -+ if (lockfree)\ -+ return __atomic_load_n((_Atomic(type)*)src, model);\ -+ Lock *l = lock_for_pointer(src);\ -+ lock(l);\ -+ type val = *src;\ -+ unlock(l);\ -+ return val;\ -+} -+#endif -+ -+#ifdef __clang__ - #define OPTIMISED_CASE(n, lockfree, type)\ - type __atomic_load_##n(type *src, int model) {\ - if (lockfree)\ -@@ -254,9 +326,26 @@ type __atomic_load_##n(type *src, int model) {\ - unlock(l);\ - return val;\ - } -+#endif - OPTIMISED_CASES - #undef OPTIMISED_CASE - -+#ifdef __GNUC__ -+#define OPTIMISED_CASE(n, lockfree, type)\ -+void __atomic_store_##n(type *dest, type val, int model) {\ -+ if (lockfree) {\ -+ __atomic_store_n((_Atomic(type)*)dest, val, model);\ -+ return;\ -+ }\ -+ Lock *l = lock_for_pointer(dest);\ -+ lock(l);\ -+ *dest = val;\ -+ unlock(l);\ -+ return;\ -+} -+#endif -+ -+#ifdef __clang__ - #define OPTIMISED_CASE(n, lockfree, type)\ - void __atomic_store_##n(type *dest, type val, int model) {\ - if (lockfree) {\ -@@ -269,9 +358,25 @@ void __atomic_store_##n(type *dest, type val, int model) {\ - unlock(l);\ - return;\ - } -+#endif - OPTIMISED_CASES - #undef OPTIMISED_CASE - -+#ifdef __GNUC__ -+#define OPTIMISED_CASE(n, lockfree, type)\ -+type __atomic_exchange_##n(type *dest, type val, int model) {\ -+ if (lockfree)\ -+ return __atomic_exchange_n((_Atomic(type)*)dest, val, model);\ -+ Lock *l = lock_for_pointer(dest);\ -+ lock(l);\ -+ type tmp = *dest;\ -+ *dest = val;\ -+ unlock(l);\ -+ return tmp;\ -+} -+#endif -+ -+#ifdef __clang__ - #define OPTIMISED_CASE(n, lockfree, type)\ - type __atomic_exchange_##n(type *dest, type val, int model) {\ - if (lockfree)\ -@@ -283,9 +388,31 @@ type __atomic_exchange_##n(type *dest, type val, int model) {\ - unlock(l);\ - return tmp;\ - } -+#endif - OPTIMISED_CASES - #undef OPTIMISED_CASE - -+#ifdef __GNUC__ -+#define OPTIMISED_CASE(n, lockfree, type)\ -+int __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\ -+ int success, int failure) {\ -+ if (lockfree)\ -+ return __atomic_compare_exchange_n((_Atomic(type)*)ptr, expected, desired,\ -+ 0, 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;\ -+} -+#endif -+ -+#ifdef __clang__ - #define OPTIMISED_CASE(n, lockfree, type)\ - int __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\ - int success, int failure) {\ -@@ -303,12 +430,28 @@ int __atomic_compare_exchange_##n(type *ptr, type *expected, type desired,\ - unlock(l);\ - return 0;\ - } -+#endif - OPTIMISED_CASES - #undef OPTIMISED_CASE - - //////////////////////////////////////////////////////////////////////////////// - // Atomic read-modify-write operations for integers of various sizes. - //////////////////////////////////////////////////////////////////////////////// -+#ifdef __GNUC__ -+#define ATOMIC_RMW(n, lockfree, type, opname, op) \ -+type __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\ -+ if (lockfree) \ -+ return __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;\ -+} -+#endif -+ -+#ifdef __clang__ - #define ATOMIC_RMW(n, lockfree, type, opname, op) \ - type __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\ - if (lockfree) \ -@@ -320,6 +463,7 @@ type __atomic_fetch_##opname##_##n(type *ptr, type val, int model) {\ - unlock(l);\ - return tmp;\ - } -+#endif - - #define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, add, +) - OPTIMISED_CASES --- -2.20.1 -