From patchwork Tue Nov 21 16:06:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Earnshaw X-Patchwork-Id: 167815 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2b07:b0:403:3b70:6f57 with SMTP id io7csp729715vqb; Tue, 21 Nov 2023 08:07:16 -0800 (PST) X-Google-Smtp-Source: AGHT+IE+Ttuj0nLAJFQYIHdwx+ESHqWiXKrhjxAW0pFDn6ZTPFR/urdLJw3bYGR1fSfvszD8QuPb X-Received: by 2002:a05:6214:2341:b0:670:f530:47ee with SMTP id hu1-20020a056214234100b00670f53047eemr14013965qvb.34.1700582836061; Tue, 21 Nov 2023 08:07:16 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1700582836; cv=pass; d=google.com; s=arc-20160816; b=B2NlkAYFIjfuQtwNWApAuQ6Wus+Ul6yxJ8zzF92mRLcviHvK2e7U24vBw3nfmPlS+U rOrPRVLQgDu/Y+46HyF6+u4RK7LCeWGgXVkFTqn3Fv1zUi2JmVNSwcJGWGEgoCHzcoXB gFI94vsM3IffM+1bYrBWk6dps/w+3afjq1hE+LVjrkjkGCiNRQW7jCMwOqC1NA5ho+e7 W89n6tKGJGC4UHrZV3E3biadJpfW3ZYhTxjnF3a7Ln76QYwgQG3TcSohXXZgwMFGDRaS 64xgRKn1aQbxe/HoDKxSxyH2nPTo6j7EMerg/HiI4RZI7gwvJ5Qc0bHxAWNXSFSYHnjc 6Njw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:arc-filter :dmarc-filter:delivered-to; bh=4gcqLYx2JlqI0QcGyEKvcsJHfpYjCzMNAgKfAFBwzi8=; fh=vcPCoAFD9ELdvNMTpDIWpczE2wb0OD9E1jzZw6wSlzw=; b=LHsidMoY8njX40obiz32ibNTwWEAss2hQ94HZncBanre8b8JFbPzD6qdjRsRIBlRa1 KLk5WUUeEFq9XZLmZPo57wIiULvPF/P2dAvJq2SmHml9Sgv8qeiY75xjAUNyCQNEIBkP QyabVSiVRqirbVTlEr0xuVZU/+tT7k7Nj1nSQTzRRjx9OBUDIVvgO2UpZI49vPj030uD NqH0UoNpMpYLGDMxfpIxLpJ/nQPU7PmSEUeV6JiEOX2cE5CkYBC4gHh+quTupMZVHalR Cc4uUlWeBnClItUEKYYLOZju8649wwvSlF01UGnXShNUtCfql5QuzDhtBTW3e2zWiKe6 riSw== ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id u15-20020a0562140b0f00b00679e0d4f303si3152590qvj.500.2023.11.21.08.07.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Nov 2023 08:07:16 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ABD223858428 for ; Tue, 21 Nov 2023 16:07:15 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 134ED3858D33 for ; Tue, 21 Nov 2023 16:06:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 134ED3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 134ED3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700582811; cv=none; b=xOxbyoy/sDbhaVMUJjYZ5EhLCcvVkZxZEsbQuSGgiZRWAo2sCASrie8gIf9/CtTYgME/U62nnU8MHQykvIEcM4ue68vM1Au0WiHoHa1IXmbrNXW9RrN4pi1My3fONtQoNvUtnIgWa9GGXiXkTK4WE2GiIgvr4qQTDQQoEC2wlHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700582811; c=relaxed/simple; bh=FJufL7ZCer3KaJMRRQwCQK2qZcDjIXXfQpI60uMayC8=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=CX4CejbMbIsN1fqgW7vouQ/YWxBzY+DjX7Vs8lqEI8sTYgqGUHobLmuX/oCgKx/UgEgdd9sGRLY7pXnJDiq2B8QgXqSLU9NlD3gXewuCXxJ6cbxA5ESFKhSu/nyFKF1gX8iy8t3SK6L2In5DhZywo4M9HQmaB/jEtZ0c2TrYgp8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 413941FB; Tue, 21 Nov 2023 08:07:36 -0800 (PST) Received: from e126323.arm.com (unknown [10.57.42.111]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F3ECB3F6C4; Tue, 21 Nov 2023 08:06:48 -0800 (PST) From: Richard Earnshaw To: gcc-patches@gcc.gnu.org Cc: Richard Earnshaw Subject: [PATCH] arm: libgcc: provide implementations of __sync_synchronize Date: Tue, 21 Nov 2023 16:06:33 +0000 Message-Id: <20231121160633.2174974-1-rearnsha@arm.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783190347814852498 X-GMAIL-MSGID: 1783190347814852498 I'm going to hold off for 24 hours on this to give some chance for feedback before committing. Is using EXTRA_PARTS in this way acceptable? If not, what method would you recommend? Is there a better way of achieving this than using --defsym (which seems to have the side effect of causing the target function to be included in the image even if the function isn't actually used)? R. 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. --- 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(-) create mode 100644 libgcc/config/arm/sync-cp15dmb.specs create mode 100644 libgcc/config/arm/sync-dmb.specs create mode 100644 libgcc/config/arm/sync-none.specs create mode 100644 libgcc/config/arm/t-sync 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 $< . +