Hi, The attached patch is a temporary workaround for PR 29366. We've been having support for various atomics on SH for a while, but libstdc++'s configury makes it impossible to use when doing a cross build (PR 53579). Even if that worked, if I'm not mistaken, config/cpu/sh/atomicity.h overrides all of that and replaces it with its own SH4A atomics or a lock based implementation for everything non-SH4A. The patch works OK on sh-elf, and as far as I can see there should be no problems on sh*-linux configs, too. I will commit the patch if there are no objections in 48h.
Cheers, Oleg libstdc++-v4/ChangeLog: PR target/29366 * config/cpu/sh/atomicity.h (__exchange_and_add, __atomic_add): Remove SH4A inline asm and lock based implementations and use the defaults from ext/atomicity.h.
Index: libstdc++-v3/config/cpu/sh/atomicity.h =================================================================== --- libstdc++-v3/config/cpu/sh/atomicity.h (revision 219824) +++ libstdc++-v3/config/cpu/sh/atomicity.h (working copy) @@ -22,87 +22,14 @@ // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. -#ifdef __SH4A__ +// Use the default atomicity stuff, which will use __atomic* builtins +// if threads are available, or the *_single functions on single-thread +// configurations. +// Actually we wouldn't need this header at all, but because of PR 53579 +// libstdc++'s configury will not pickup the -matomic-model= option when +// set in the environment. This makes it impossible to enable the proper +// atomic model on SH without modifying GCC itself, because libstdc++ always +// thinks the target doesn't do any atomics and uses the default mutex based +// implementation from cpu/generic/atomicity/mutex. #include <ext/atomicity.h> - -namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - typedef int _Atomic_word; - - _Atomic_word - __attribute__ ((__unused__)) - __exchange_and_add (volatile _Atomic_word* __mem, int __val) throw () - { - _Atomic_word __result; - - __asm__ __volatile__ - ("0:\n" - "\tmovli.l\t@%2,r0\n" - "\tmov\tr0,%1\n" - "\tadd\t%3,r0\n" - "\tmovco.l\tr0,@%2\n" - "\tbf\t0b" - : "+m" (*__mem), "=&r" (__result) - : "r" (__mem), "rI08" (__val) - : "r0"); - - return __result; - } - - - void - __attribute__ ((__unused__)) - __atomic_add (volatile _Atomic_word* __mem, int __val) throw () - { - asm("0:\n" - "\tmovli.l\t@%1,r0\n" - "\tadd\t%2,r0\n" - "\tmovco.l\tr0,@%1\n" - "\tbf\t0b" - : "+m" (*__mem) - : "r" (__mem), "rI08" (__val) - : "r0"); - } - -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace - -#else /* !__SH4A__ */ - -/* This is generic/atomicity.h */ - -#include <ext/atomicity.h> -#include <ext/concurrence.h> - -namespace -{ - __gnu_cxx::__mutex atomic_mutex; -} // anonymous namespace - -namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - _Atomic_word - __attribute__ ((__unused__)) - __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw () - { - __gnu_cxx::__scoped_lock sentry(atomic_mutex); - _Atomic_word __result; - __result = *__mem; - *__mem += __val; - return __result; - } - - void - __attribute__ ((__unused__)) - __atomic_add(volatile _Atomic_word* __mem, int __val) throw () - { __exchange_and_add(__mem, __val); } - -_GLIBCXX_END_NAMESPACE_VERSION -} // namespace - -#endif /* !__SH4A__ */