aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/arm/lib1funcs.S72
-rw-r--r--libgcc/config/arm/sync-cp15dmb.specs4
-rw-r--r--libgcc/config/arm/sync-dmb.specs4
-rw-r--r--libgcc/config/arm/sync-none.specs4
-rw-r--r--libgcc/config/arm/t-sync13
6 files changed, 98 insertions, 1 deletions
diff --git a/libgcc/config.host b/libgcc/config.host
index 6afe8e5..694e3e9 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -554,7 +554,7 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
tm_file="$tm_file arm/bpabi-lib.h"
case ${host} in
arm*-*-eabi* | arm*-*-rtems*)
- tmake_file="${tmake_file} arm/t-bpabi t-crtfm"
+ tmake_file="${tmake_file} arm/t-bpabi arm/t-sync t-crtfm"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
;;
arm*-*-symbianelf*)
diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
index d02a57c..7888786 100644
--- a/libgcc/config/arm/lib1funcs.S
+++ b/libgcc/config/arm/lib1funcs.S
@@ -2147,6 +2147,78 @@ LSYM(Lchange_\register):
SIZE (__gnu_thumb1_case_uhi)
#endif
+#ifdef L_sync_none
+ /* Null implementation of __sync_synchronize, for use when
+ it is known that the system is single threaded. */
+ .text
+ .align 0
+ FUNC_START sync_synchronize_none
+ bx lr
+ FUNC_END sync_synchronize_none
+#endif
+
+#ifdef L_sync_dmb
+ /* Full memory barrier using DMB. Requires Armv7 (all profiles)
+ or armv6-m, or later. */
+ .text
+ .align 0
+#if __ARM_ARCH_PROFILE == 'M'
+ .arch armv6-m
+#else
+ .arch armv7-a
+#endif
+ FUNC_START sync_synchronize_dmb
+ /* M-profile devices only support SY as the synchronization level,
+ but that's probably what we want here anyway. */
+ dmb
+ RET
+ FUNC_END sync_synchronize_dmb
+#endif
+
+#ifdef L_sync_cp15dmb
+#ifndef NOT_ISA_TARGET_32BIT
+ /* Implementation of DMB using CP15 operations. This was first
+ defined in Armv6, but deprecated in Armv7 and can give
+ sub-optimal performance. */
+ .text
+ .align 0
+ ARM_FUNC_START sync_synchronize_cp15dmb
+ mcr p15, 0, r0, c7, c10, 5
+ RET
+ FUNC_END sync_synchronize_cp15dmb
+#endif
+#endif
+
+#ifdef L_sync_synchronize
+ /* Generic version of the synchronization primitive. If we know
+ that DMB exists, then use it. Otherwise, arrange for a link
+ time warning explaining how to pick a suitable alternative.
+ We choose not to use CP15DMB because it is performance
+ deprecated. We only define this function if generating
+ ELF binaries as otherwise we can't rely on the warning being
+ generated. */
+
+#ifdef __ELF__
+ .text
+ .align 0
+ FUNC_START sync_synchronize
+#if __ARM_ARCH >= 7 || __ARM_ARCH_PROFILE == 'M'
+ dmb
+#endif
+ RET
+ FUNC_END sync_synchronize
+#if !(__ARM_ARCH >= 7 || __ARM_ARCH_PROFILE == 'M')
+ .section .gnu.warning.__sync_synchronize
+ .align 0
+ .ascii "This implementation of __sync_synchronize is a stub with "
+ .ascii "no effect. Relink with\n"
+ .ascii " -specs=sync-{none,dmb,cp15dmb}.specs\n"
+ .ascii "to specify exactly which barrier format to use and avoid "
+ .ascii "this warning.\n\0"
+#endif
+#endif
+#endif
+
#ifdef L_thumb1_case_si
.text
diff --git a/libgcc/config/arm/sync-cp15dmb.specs b/libgcc/config/arm/sync-cp15dmb.specs
new file mode 100644
index 0000000..0bb64b9
--- /dev/null
+++ b/libgcc/config/arm/sync-cp15dmb.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_cp15dmb %(sync_sync_link)
diff --git a/libgcc/config/arm/sync-dmb.specs b/libgcc/config/arm/sync-dmb.specs
new file mode 100644
index 0000000..13e59bd
--- /dev/null
+++ b/libgcc/config/arm/sync-dmb.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_dmb %(sync_sync_link)
diff --git a/libgcc/config/arm/sync-none.specs b/libgcc/config/arm/sync-none.specs
new file mode 100644
index 0000000..0aa4960
--- /dev/null
+++ b/libgcc/config/arm/sync-none.specs
@@ -0,0 +1,4 @@
+%rename link sync_sync_link
+
+*link:
+--defsym=__sync_synchronize=__sync_synchronize_none %(sync_sync_link)
diff --git a/libgcc/config/arm/t-sync b/libgcc/config/arm/t-sync
new file mode 100644
index 0000000..5fd050e
--- /dev/null
+++ b/libgcc/config/arm/t-sync
@@ -0,0 +1,13 @@
+LIB1ASMFUNCS += _sync_none _sync_dmb _sync_cp15dmb _sync_synchronize
+
+EXTRA_PARTS += sync-none.specs sync-dmb.specs sync-cp15dmb.specs
+
+sync-none.specs: $(srcdir)/config/arm/sync-none.specs
+ cp $< .
+
+sync-dmb.specs: $(srcdir)/config/arm/sync-dmb.specs
+ cp $< .
+
+sync-cp15dmb.specs: $(srcdir)/config/arm/sync-cp15dmb.specs
+ cp $< .
+