From patchwork Mon Oct 31 15:45:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Engel X-Patchwork-Id: 59678 X-Patchwork-Delegate: rearnsha@gcc.gnu.org Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6219D3AA9421 for ; Mon, 31 Oct 2022 15:50:36 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from wout3-smtp.messagingengine.com (wout3-smtp.messagingengine.com [64.147.123.19]) by sourceware.org (Postfix) with ESMTPS id 20ECE3852774 for ; Mon, 31 Oct 2022 15:47:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 20ECE3852774 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=danielengel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=danielengel.com Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.west.internal (Postfix) with ESMTP id 0C4AF3200945; Mon, 31 Oct 2022 11:47:28 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Mon, 31 Oct 2022 11:47:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=danielengel.com; h=cc:cc:content-transfer-encoding:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm1; t=1667231248; x= 1667317648; bh=P8+jBTtuJo1MEu0gFEtVOWtzYyNZ73jHQYh3RLnTTGA=; b=b yc/PqIxGzi9CJ+XEp2lmbI+HUG7znz12QvHQ6dgojSVSXj2rHCKXzWs7VC9cl3Nd Hz2BZ2Sdh0gD+5pRJ8xCN0aIhAeLzowayAIwK3il0L0Cw03lpAppYBk715/R/gLr /3omgt/uuj4RUjaN3MgAFXHtujD15li1fjWsm4egNkNny4p26Lr2Ue2PEM62E5ey anJv5ugJtNH5xXrV8wJXLR5i6lEO8UO01tfU3noSujOm6KAfvBxIBmX0jHlPRZ1h p86nS31e7FXdTmDiTaG+RRP7wVxgSWR/+m1s+D4m5FmWSDTcyyZkz6J5KSknEPbF 8YZ7Kq0Pea9xLOmfA+HcA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:sender:subject :subject:to:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1667231248; x=1667317648; bh=P8+jBTtuJo1ME u0gFEtVOWtzYyNZ73jHQYh3RLnTTGA=; b=r99lMQ05ieI2F78SMk4/p20Vygidh 0aief92ADXqymYebSVhgW8BP5QVGBYoLcOXnCBY7imbw2n3xDBCJAY2rRG/Nsity S8Zofnv4mai/W5Dn7RLsunHzXUMH7AbDPhYBJX5ae+iGF7YZg6GO8tj+hFzmC2r6 uQcwFpVL5sluKvo/5MukSqwXphfb4VDIylBvyZqivL1WSWLOx/WARb0rsM5LA04X MvHBMk6xAZQkiGrlzBEMMhH7Xd8ZLnWaS5JVfEDLT0C3nIip1QviN85PZJpVzcpu CcclxrnafmcW686nu4j8YJPld+OGhejCRNGYArBq3OeILj+mKuXZz0Zeg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrudefgdektdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgv lhcugfhnghgvlhcuoehgnhhusegurghnihgvlhgvnhhgvghlrdgtohhmqeenucggtffrrg htthgvrhhnpeefffevgffhuedvvddvleetveelgeetffffieeihfffjeejgfetgfeifefg jeetteenucffohhmrghinheplhhisgdufhhunhgtshdrshgspdhprghrihhthidrshgspd hgnhhurdhorhhgnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhf rhhomhepghhnuhesuggrnhhivghlvghnghgvlhdrtghomh X-ME-Proxy: Feedback-ID: i791144d6:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 31 Oct 2022 11:47:27 -0400 (EDT) Received: from ubuntu.lorien.danielengel.com (ubuntu.lorien.danielengel.com [10.0.0.96]) by sendmail.lorien.danielengel.com (8.15.2/8.15.2) with ESMTP id 29VFlIjc087271; Mon, 31 Oct 2022 08:47:19 -0700 (PDT) (envelope-from gnu@danielengel.com) From: Daniel Engel To: Richard Earnshaw , gcc-patches@gcc.gnu.org Subject: [PATCH v7 14/34] Import 'parity' functions from the CM0 library Date: Mon, 31 Oct 2022 08:45:09 -0700 Message-Id: <20221031154529.3627576-15-gnu@danielengel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221031154529.3627576-1-gnu@danielengel.com> References: <20221031154529.3627576-1-gnu@danielengel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_SHORT, RCVD_IN_DNSWL_LOW, SCC_5_SHORT_WORD_LINES, SPF_HELO_PASS, SPF_PASS, TXREP 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Engel , Christophe Lyon Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" The functional overlap between the single- and double-word functions makes functions makes this implementation about half the size of the C functions if both functions are linked in the same application. gcc/libgcc/ChangeLog: 2022-10-09 Daniel Engel * config/arm/parity.S: New file for __paritysi2/di2(). * config/arm/lib1funcs.S: #include bit/parity.S * config/arm/t-elf (LIB1ASMFUNCS): Added _paritysi2/di2. --- libgcc/config/arm/lib1funcs.S | 1 + libgcc/config/arm/parity.S | 120 ++++++++++++++++++++++++++++++++++ libgcc/config/arm/t-elf | 2 + 3 files changed, 123 insertions(+) create mode 100644 libgcc/config/arm/parity.S diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S index aa5957b8399..3f7b9e739f0 100644 --- a/libgcc/config/arm/lib1funcs.S +++ b/libgcc/config/arm/lib1funcs.S @@ -1704,6 +1704,7 @@ LSYM(Lover12): #include "clz2.S" #include "ctz2.S" +#include "parity.S" /* ------------------------------------------------------------------------ */ /* These next two sections are here despite the fact that they contain Thumb diff --git a/libgcc/config/arm/parity.S b/libgcc/config/arm/parity.S new file mode 100644 index 00000000000..1405bea93a3 --- /dev/null +++ b/libgcc/config/arm/parity.S @@ -0,0 +1,120 @@ +/* parity.S: ARM optimized parity functions + + Copyright (C) 2020-2022 Free Software Foundation, Inc. + Contributed by Daniel Engel (gnu@danielengel.com) + + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + + +#ifdef L_paritydi2 + +// int __paritydi2(int) +// Returns '0' if the number of bits set in $r1:r0 is even, and '1' otherwise. +// Returns the result in $r0. +FUNC_START_SECTION paritydi2 .text.sorted.libgcc.paritydi2 + CFI_START_FUNCTION + + // Combine the upper and lower words, then fall through. + // Byte-endianness does not matter for this function. + eors r0, r1 + +#endif /* L_paritydi2 */ + + +// The implementation of __paritydi2() tightly couples with __paritysi2(), +// such that instructions must appear consecutively in the same memory +// section for proper flow control. However, this construction inhibits +// the ability to discard __paritydi2() when only using __paritysi2(). +// Therefore, this block configures __paritysi2() for compilation twice. +// The first version is a minimal standalone implementation, and the second +// version is the continuation of __paritydi2(). The standalone version must +// be declared WEAK, so that the combined version can supersede it and +// provide both symbols when required. +// '_paritysi2' should appear before '_paritydi2' in LIB1ASMFUNCS. +#if defined(L_paritysi2) || defined(L_paritydi2) + +#ifdef L_paritysi2 +// int __paritysi2(int) +// Returns '0' if the number of bits set in $r0 is even, and '1' otherwise. +// Returns the result in $r0. +// Uses $r2 as scratch space. +WEAK_START_SECTION paritysi2 .text.sorted.libgcc.paritysi2 + CFI_START_FUNCTION + +#else /* L_paritydi2 */ +FUNC_ENTRY paritysi2 + +#endif + + #if defined(__thumb__) && __thumb__ + #if defined(__OPTIMIZE_SIZE__) && __OPTIMIZE_SIZE__ + + // Size optimized: 16 bytes, 40 cycles + // Speed optimized: 24 bytes, 14 cycles + movs r2, #16 + + LLSYM(__parity_loop): + // Calculate the parity of successively smaller half-words into the MSB. + movs r1, r0 + lsls r1, r2 + eors r0, r1 + lsrs r2, #1 + bne LLSYM(__parity_loop) + + #else /* !__OPTIMIZE_SIZE__ */ + + // Unroll the loop. The 'libgcc' reference C implementation replaces + // the x2 and the x1 shifts with a constant. However, since it takes + // 4 cycles to load, index, and mask the constant result, it doesn't + // cost anything to keep shifting (and saves a few bytes). + lsls r1, r0, #16 + eors r0, r1 + lsls r1, r0, #8 + eors r0, r1 + lsls r1, r0, #4 + eors r0, r1 + lsls r1, r0, #2 + eors r0, r1 + lsls r1, r0, #1 + eors r0, r1 + + #endif /* !__OPTIMIZE_SIZE__ */ + #else /* !__thumb__ */ + + eors r0, r0, r0, lsl #16 + eors r0, r0, r0, lsl #8 + eors r0, r0, r0, lsl #4 + eors r0, r0, r0, lsl #2 + eors r0, r0, r0, lsl #1 + + #endif /* !__thumb__ */ + + lsrs r0, #31 + RET + + CFI_END_FUNCTION +FUNC_END paritysi2 + +#ifdef L_paritydi2 +FUNC_END paritydi2 +#endif + +#endif /* L_paritysi2 || L_paritydi2 */ + diff --git a/libgcc/config/arm/t-elf b/libgcc/config/arm/t-elf index 346fc766f17..0e9b9ce21af 100644 --- a/libgcc/config/arm/t-elf +++ b/libgcc/config/arm/t-elf @@ -24,6 +24,7 @@ endif # !__symbian__ LIB1ASMFUNCS += \ _clzsi2 \ _ctzsi2 \ + _paritysi2 \ # Group 1: Integer function objects. @@ -37,6 +38,7 @@ LIB1ASMFUNCS += \ _ctzdi2 \ _ffssi2 \ _ffsdi2 \ + _paritydi2 \ _dvmd_tls \ _divsi3 \ _modsi3 \