From patchwork Mon Oct 31 15:45:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Engel X-Patchwork-Id: 59670 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 A8AA5395447D for ; Mon, 31 Oct 2022 15:49:05 +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 AEB223895FC9 for ; Mon, 31 Oct 2022 15:47:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AEB223895FC9 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 compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 2F0EE3200974; Mon, 31 Oct 2022 11:47:44 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 31 Oct 2022 11:47:44 -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=1667231263; x= 1667317663; bh=tQrBo31Z5cT8vV3BZaQU7syldrdJnkhzZl0mnkod1oU=; b=r WwpKS3NhlhK3SAbkSm5Mdn3zTHNHNARf8oMHJ3y4el2DVo0kbPrabBoholOT0aGD LaG+oSpw7Nd6hfCOKo7CVRL+y3FDC8tAv0Bsm4MT18pPpF8V8qQUKmkPiiILGcvV pqB3F1F5xVk0M01zExCw1tbrO2NVAv0HCEsb6YPPLkCJqcdihJQsrJEX9LDMcZu0 SoaYRnsWK3yfTGGO7icGIiUMoHTp3xAlUqTGEOmVqWqB468Iwms1du8HA2/U8UOR HFA8rCGlfxiqes4uOl4RRQ153RTIFMEPoORArD1H/M29YEWVNl0hovNdf8PM/AP6 DO1QQWEq71K0vmUm6L2qw== 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=1667231263; x=1667317663; bh=tQrBo31Z5cT8v V3BZaQU7syldrdJnkhzZl0mnkod1oU=; b=VbVnJ/b7D+SkcDI+8ty9rw3NUujvk f90l9ANAr96vBFyPj9gGiIz8YscC73mlh6M6sAQuTyT00biLhw0LfS8UqHTQ7cqH bwoXZo2gSpD++bpQ67Ofa0u/Wdnm0qzovz1K7VnKofIMFWaqpWnxOr+gQzUkpERT 7Xcj7cmIRWIfjowhW0xv13GT1RlMk22YcLhgBQI81c0ynh1rdimqvTBIiUvIcCzI XJHiWuSJUCqgsnrJ2NUPn+Ljd8KQiw5SUqGUkttjWJ47MVu8Ddrqdhvcya1sFbWu 4Wc8QvFNv5rqw16uXhxanR6uOQKPQCgRQ98SPP+AceIMDRT5CyvfgIisQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrudefgdektdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeffrghnihgv lhcugfhnghgvlhcuoehgnhhusegurghnihgvlhgvnhhgvghlrdgtohhmqeenucggtffrrg htthgvrhhnpeeihedvieegkeduteejheeuteekieeiffduudekgfdtueeuieekvdeukeff gfelleenucffohhmrghinheplhgtmhhprdhssgdpghhnuhdrohhrghenucevlhhushhtvg hrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehgnhhusegurghnihgvlhgv nhhgvghlrdgtohhm X-ME-Proxy: Feedback-ID: i791144d6:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 31 Oct 2022 11:47:43 -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 29VFlZYS087280; Mon, 31 Oct 2022 08:47:35 -0700 (PDT) (envelope-from gnu@danielengel.com) From: Daniel Engel To: Richard Earnshaw , gcc-patches@gcc.gnu.org Subject: [PATCH v7 17/34] Import 64-bit comparison from CM0 library Date: Mon, 31 Oct 2022 08:45:12 -0700 Message-Id: <20221031154529.3627576-18-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=-13.4 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, 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" These are 2-5 instructions smaller and just as fast. Branches are minimized, which will allow easier adaptation to Thumb-2/ARM mode. gcc/libgcc/ChangeLog: 2022-10-09 Daniel Engel * config/arm/eabi/lcmp.S (__aeabi_lcmp, __aeabi_ulcmp): Replaced; add macro configuration to build __cmpdi2() and __ucmpdi2(). * config/arm/t-elf (LIB1ASMFUNCS): Added _cmpdi2 and _ucmpdi2. --- libgcc/config/arm/eabi/lcmp.S | 151 +++++++++++++++++++++++++--------- libgcc/config/arm/t-elf | 2 + 2 files changed, 112 insertions(+), 41 deletions(-) diff --git a/libgcc/config/arm/eabi/lcmp.S b/libgcc/config/arm/eabi/lcmp.S index 336db1d398c..99c7970ecba 100644 --- a/libgcc/config/arm/eabi/lcmp.S +++ b/libgcc/config/arm/eabi/lcmp.S @@ -1,8 +1,7 @@ -/* Miscellaneous BPABI functions. Thumb-1 implementation, suitable for ARMv4T, - ARMv6-M and ARMv8-M Baseline like ISA variants. +/* lcmp.S: Thumb-1 optimized 64-bit integer comparison - Copyright (C) 2006-2020 Free Software Foundation, Inc. - Contributed by CodeSourcery. + Copyright (C) 2018-2022 Free Software Foundation, Inc. + Contributed by Daniel Engel, Senva Inc (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 @@ -24,50 +23,120 @@ . */ +#if defined(L_aeabi_lcmp) || defined(L_cmpdi2) + #ifdef L_aeabi_lcmp + #define LCMP_NAME aeabi_lcmp + #define LCMP_SECTION .text.sorted.libgcc.lcmp +#else + #define LCMP_NAME cmpdi2 + #define LCMP_SECTION .text.sorted.libgcc.cmpdi2 +#endif + +// int __aeabi_lcmp(long long, long long) +// int __cmpdi2(long long, long long) +// Compares the 64 bit signed values in $r1:$r0 and $r3:$r2. +// lcmp() returns $r0 = { -1, 0, +1 } for orderings { <, ==, > } respectively. +// cmpdi2() returns $r0 = { 0, 1, 2 } for orderings { <, ==, > } respectively. +// Object file duplication assumes typical programs follow one runtime ABI. +FUNC_START_SECTION LCMP_NAME LCMP_SECTION + CFI_START_FUNCTION + + // Calculate the difference $r1:$r0 - $r3:$r2. + subs xxl, yyl + sbcs xxh, yyh + + // With $r2 free, create a known offset value without affecting + // the N or Z flags. + // BUG? The originally unified instruction for v6m was 'mov r2, r3'. + // However, this resulted in a compile error with -mthumb: + // "MOV Rd, Rs with two low registers not permitted". + // Since unified syntax deprecates the "cpy" instruction, shouldn't + // there be a backwards-compatible tranlation available? + cpy r2, r3 + + // Evaluate the comparison result. + blt LLSYM(__lcmp_lt) + + // The reference offset ($r2 - $r3) will be +2 iff the first + // argument is larger, otherwise the offset value remains 0. + adds r2, #2 + + // Check for zero (equality in 64 bits). + // It doesn't matter which register was originally "hi". + orrs r0, r1 + + // The result is already 0 on equality. + beq LLSYM(__lcmp_return) + + LLSYM(__lcmp_lt): + // Create +1 or -1 from the offset value defined earlier. + adds r3, #1 + subs r0, r2, r3 + + LLSYM(__lcmp_return): + #ifdef L_cmpdi2 + // Offset to the correct output specification. + adds r0, #1 + #endif -FUNC_START aeabi_lcmp - cmp xxh, yyh - beq 1f - bgt 2f - movs r0, #1 - negs r0, r0 - RET -2: - movs r0, #1 - RET -1: - subs r0, xxl, yyl - beq 1f - bhi 2f - movs r0, #1 - negs r0, r0 - RET -2: - movs r0, #1 -1: RET - FUNC_END aeabi_lcmp -#endif /* L_aeabi_lcmp */ + CFI_END_FUNCTION +FUNC_END LCMP_NAME + +#endif /* L_aeabi_lcmp || L_cmpdi2 */ + + +#if defined(L_aeabi_ulcmp) || defined(L_ucmpdi2) #ifdef L_aeabi_ulcmp + #define ULCMP_NAME aeabi_ulcmp + #define ULCMP_SECTION .text.sorted.libgcc.ulcmp +#else + #define ULCMP_NAME ucmpdi2 + #define ULCMP_SECTION .text.sorted.libgcc.ucmpdi2 +#endif + +// int __aeabi_ulcmp(unsigned long long, unsigned long long) +// int __ucmpdi2(unsigned long long, unsigned long long) +// Compares the 64 bit unsigned values in $r1:$r0 and $r3:$r2. +// ulcmp() returns $r0 = { -1, 0, +1 } for orderings { <, ==, > } respectively. +// ucmpdi2() returns $r0 = { 0, 1, 2 } for orderings { <, ==, > } respectively. +// Object file duplication assumes typical programs follow one runtime ABI. +FUNC_START_SECTION ULCMP_NAME ULCMP_SECTION + CFI_START_FUNCTION + + // Calculate the 'C' flag. + subs xxl, yyl + sbcs xxh, yyh + + // Capture the carry flg. + // $r2 will contain -1 if the first value is smaller, + // 0 if the first value is larger or equal. + sbcs r2, r2 + + // Check for zero (equality in 64 bits). + // It doesn't matter which register was originally "hi". + orrs r0, r1 + + // The result is already 0 on equality. + beq LLSYM(__ulcmp_return) + + // Assume +1. If -1 is correct, $r2 will override. + movs r0, #1 + orrs r0, r2 + + LLSYM(__ulcmp_return): + #ifdef L_ucmpdi2 + // Offset to the correct output specification. + adds r0, #1 + #endif -FUNC_START aeabi_ulcmp - cmp xxh, yyh - bne 1f - subs r0, xxl, yyl - beq 2f -1: - bcs 1f - movs r0, #1 - negs r0, r0 - RET -1: - movs r0, #1 -2: RET - FUNC_END aeabi_ulcmp -#endif /* L_aeabi_ulcmp */ + CFI_END_FUNCTION +FUNC_END ULCMP_NAME + +#endif /* L_aeabi_ulcmp || L_ucmpdi2 */ diff --git a/libgcc/config/arm/t-elf b/libgcc/config/arm/t-elf index 2e3f04aa2f0..83325410097 100644 --- a/libgcc/config/arm/t-elf +++ b/libgcc/config/arm/t-elf @@ -41,6 +41,8 @@ LIB1ASMFUNCS += \ _ffsdi2 \ _paritydi2 \ _popcountdi2 \ + _cmpdi2 \ + _ucmpdi2 \ _dvmd_tls \ _divsi3 \ _modsi3 \