From patchwork Tue Nov 15 16:17:43 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Gretton-Dann X-Patchwork-Id: 125817 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 66F6AB71E2 for ; Wed, 16 Nov 2011 03:18:36 +1100 (EST) Received: (qmail 3065 invoked by alias); 15 Nov 2011 16:18:25 -0000 Received: (qmail 3037 invoked by uid 22791); 15 Nov 2011 16:18:19 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, TW_IV X-Spam-Check-By: sourceware.org Received: from service87.mimecast.com (HELO service87.mimecast.com) (91.220.42.44) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 Nov 2011 16:17:47 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 15 Nov 2011 16:17:44 +0000 Received: from [10.1.69.27] ([10.1.255.212]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 15 Nov 2011 16:17:43 +0000 Message-ID: <4EC290A7.5030909@arm.com> Date: Tue, 15 Nov 2011 16:17:43 +0000 From: Matthew Gretton-Dann User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110928 Thunderbird/7.0 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Richard Earnshaw Subject: [RFA/ARM] Make libgcc use UDIV/SDIV instructions when they are available. X-MC-Unique: 111111516174405201 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org All, The attached patch causes libgcc to use the UDIV and SDIV instructions when possible in the implementation of the ARM div/mod functions in libgcc. This will benefit Cortex-M3, Cortex-M4, all Cortex-R* CPUs, Cortex-A7, and Cortex-A15. The special case of some Cortex-R* CPUs where the UDIV/SDIV instructions are only available in Thumb mode, making it beneficial to force these library functions into Thumb mode to make use of those instructions, is not handled. This was tested by configuring GCC --with-cpu cortex-a15, and then running the testsuite with -mcpu=cortex-a9. I've also manually inspected libgcc to make sure the functions are being built as expected. Please can someone review? Thanks, Matt libgcc/ChangeLog: 2011-11-15 Matthew Gretton-Dann * config/arm/lib1funcs.asm (udivsi3): Add support for divide functions. (aeabi_uidivmod): Likewise. (umodsi3): Likewise. (divsi3): Likewise. (aeabi_idivmod): Likewise. (modsi3): Likewise. Thanks, Matt diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S index 2e76c01..094d79a 100644 --- a/libgcc/config/arm/lib1funcs.S +++ b/libgcc/config/arm/lib1funcs.S @@ -951,6 +951,17 @@ LSYM(udivsi3_skip_div0_test): pop { work } RET +#elif defined(__ARM_ARCH_EXT_IDIV__) + + ARM_FUNC_START udivsi3 + ARM_FUNC_ALIAS aeabi_uidiv udivsi3 + + cmp r1, #0 + beq LSYM(Ldiv0) + + udiv r0, r0, r1 + RET + #else /* ARM version/Thumb-2. */ ARM_FUNC_START udivsi3 @@ -997,6 +1008,14 @@ FUNC_START aeabi_uidivmod mul r2, r0 sub r1, r1, r2 bx r3 +#elif defined(__ARM_ARCH_EXT_IDIV__) +ARM_FUNC_START aeabi_uidivmod + cmp r1, #0 + beq LSYM(Ldiv0) + mov r2, r0 + udiv r0, r0, r1 + mls r1, r0, r1, r2 + RET #else ARM_FUNC_START aeabi_uidivmod cmp r1, #0 @@ -1014,9 +1033,19 @@ ARM_FUNC_START aeabi_uidivmod /* ------------------------------------------------------------------------ */ #ifdef L_umodsi3 - FUNC_START umodsi3 +#ifdef __ARM_ARCH_EXT_IDIV__ -#ifdef __thumb__ + ARM_FUNC_START umodsi3 + + cmp r1, #0 + beq LSYM(Ldiv0) + udiv r2, r0, r1 + mls r0, r1, r2, r0 + RET + +#elif defined(__thumb__) + + FUNC_START umodsi3 cmp divisor, #0 beq LSYM(Ldiv0) @@ -1035,6 +1064,8 @@ LSYM(Lover10): #else /* ARM version. */ + FUNC_START umodsi3 + subs r2, r1, #1 @ compare divisor with 1 bcc LSYM(Ldiv0) cmpne r0, r1 @ compare dividend with divisor @@ -1091,6 +1122,16 @@ LSYM(Lover12): pop { work } RET +#elif defined(__ARM_ARCH_EXT_IDIV__) + + ARM_FUNC_START divsi3 + ARM_FUNC_ALIAS aeabi_idiv divsi3 + + cmp r1, #0 + beq LSYM(Ldiv0) + sdiv r0, r0, r1 + RET + #else /* ARM/Thumb-2 version. */ ARM_FUNC_START divsi3 @@ -1153,6 +1194,14 @@ FUNC_START aeabi_idivmod mul r2, r0 sub r1, r1, r2 bx r3 +#elif defined(__ARM_ARCH_EXT_IDIV__) +ARM_FUNC_START aeabi_idivmod + cmp r1, #0 + beq LSYM(Ldiv0) + mov r2, r0 + sdiv r0, r0, r1 + mls r1, r0, r1, r2 + RET #else ARM_FUNC_START aeabi_idivmod cmp r1, #0 @@ -1170,9 +1219,20 @@ ARM_FUNC_START aeabi_idivmod /* ------------------------------------------------------------------------ */ #ifdef L_modsi3 - FUNC_START modsi3 +#if defined(__ARM_ARCH_EXT_IDIV__) -#ifdef __thumb__ + ARM_FUNC_START modsi3 + + cmp r1, #0 + beq LSYM(Ldiv0) + + sdiv r2, r0, r1 + mls r0, r1, r2, r0 + RET + +#elif defined(__thumb__) + + FUNC_START modsi3 mov curbit, #1 cmp divisor, #0 @@ -1204,6 +1264,8 @@ LSYM(Lover12): #else /* ARM version. */ + FUNC_START modsi3 + cmp r1, #0 beq LSYM(Ldiv0) rsbmi r1, r1, #0 @ loops below use unsigned.