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__ */