public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-5828] arm: libgcc: provide implementations of __sync_synchronize
@ 2023-11-24 14:16 Richard Earnshaw
  0 siblings, 0 replies; only message in thread
From: Richard Earnshaw @ 2023-11-24 14:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:439779bacee869643c93a4710a29f89ad031ee4a

commit r14-5828-g439779bacee869643c93a4710a29f89ad031ee4a
Author: Richard Earnshaw <rearnsha@arm.com>
Date:   Mon Nov 20 14:04:17 2023 +0000

    arm: libgcc: provide implementations of __sync_synchronize
    
    Prior to Armv6 there was no architected method to synchronize data
    across processors.  Armv6 saw the first introduction of
    multi-processor support, using a CP15 operation; but this was
    deprecated in Armv7 and is not supported on m-profile devices of any
    form.  Armv7 (and armv6-m) and later support data synchronization via
    the DMB instruction.
    
    This all leads to difficulties when linking programs as the user
    generally needs to know which synchronization method is needed, but
    there seems no easy way around this, when there are no OS-related
    primitives available.
    
    I've addressed this by adding multiple variants of __sync_synchronize
    to libgcc, one for each of the above use cases.  I've named these
    __sync_synchronize_none, __sync_synchronize_cp15dmb and
    __sync_synchronize_dmb.  I've also added three specs files that can be
    used to direct the linker to pick the appropriate implementation.
    Using specs fragments for this is preferable to directing the user to
    directly use --defsym as the latter has to be placed at the correct
    position on the command line to be effective and the spec rule ensures
    this automatically.
    
    I've also added a default implementation of __sync_synchronize.  The
    default implementation will use DMB if that is available in the target
    ISA, or fall back to a nul-implementation if it isn't.  In the latter
    case it will cause the linker (GNU LD) to emit a warning that
    specifies how to pick a specific implementation.  I've chosen not to
    permit this default to use the CP15 solution as that has been
    deprecated.
    
    libgcc:
    
            * config.host (arm*-*-eabi* | arm*-*-rtems*):
            Add arm/t-sync to the makefile rules.
            * config/arm/lib1funcs.S (__sync_synchronize_none)
            (__sync_synchronize_cp15dmb, __sync_synchronize_dmb)
            (__sync_synchronize): New functions.
            * config/arm/t-sync: New file.
            * config/arm/sync-none.specs: Likewise.
            * config/arm/sync-dmb.specs: Likewise.
            * config/arm/sync-cp15dmb.specs: Likewise.

Diff:
---
 libgcc/config.host                   |  2 +-
 libgcc/config/arm/lib1funcs.S        | 72 ++++++++++++++++++++++++++++++++++++
 libgcc/config/arm/sync-cp15dmb.specs |  4 ++
 libgcc/config/arm/sync-dmb.specs     |  4 ++
 libgcc/config/arm/sync-none.specs    |  4 ++
 libgcc/config/arm/t-sync             | 13 +++++++
 6 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/libgcc/config.host b/libgcc/config.host
index 6afe8e56f7e..694e3e9f54c 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 d02a57c4564..78887861616 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 00000000000..0bb64b97a0d
--- /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 00000000000..13e59bdd22d
--- /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 00000000000..0aa49602c8b
--- /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 00000000000..5fd050ec997
--- /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 $< .
+

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-24 14:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-24 14:16 [gcc r14-5828] arm: libgcc: provide implementations of __sync_synchronize Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).