From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19867 invoked by alias); 27 May 2011 16:33:02 -0000 Received: (qmail 19709 invoked by uid 22791); 27 May 2011 16:33:00 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 27 May 2011 16:32:46 +0000 Received: (qmail 19200 invoked from network); 27 May 2011 16:32:45 -0000 Received: from unknown (HELO rex.config) (julian@127.0.0.2) by mail.codesourcery.com with ESMTPA; 27 May 2011 16:32:45 -0000 Date: Fri, 27 May 2011 17:50:00 -0000 From: Julian Brown To: gcc-patches@gcc.gnu.org Cc: paul@codesourcery.com, rearnsha@arm.com, Ramana Radhakrishnan Subject: [PATCH, ARM] Fix ABI for double-precision helpers on single-float-only CPUs Message-ID: <20110527173238.630c95b8@rex.config> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/Rty+y5doR0mxLlcLUgLgZI3" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-05/txt/msg02183.txt.bz2 --MP_/Rty+y5doR0mxLlcLUgLgZI3 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 795 The helper functions used to implement double-precision arithmetic on ARM processors that only support single-precision arithmetic in hardware should use the soft-float ABI (i.e. passing and returning floating-point arguments in core registers), even when -mfloat-abi=hard is in effect. This patch tweaks the ABI for the affected functions so that is true. Tested with cross to ARM EABI, and by manually observing compiler output. We've also been carrying this patch in our local tree for some time without issue. OK to apply? Thanks, Julian ChangeLog gcc/ * config/arm/arm.c (arm_libcall_uses_aapcs_base) (arm_init_cumulative_args): Use correct ABI for double-precision helper functions in hard-float mode if only single-precision arithmetic is supported in hardware. --MP_/Rty+y5doR0mxLlcLUgLgZI3 Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=hard-float-double-prec-abi-fix-2.diff Content-length: 3551 commit 829dab1d743604e6025b929be7287c3215a57d21 Author: Julian Brown Date: Fri May 27 04:49:33 2011 -0700 Fix hard-float ABI for double-precision helpers on single-precision CPUs. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5a62802..47fba2c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -3472,6 +3472,28 @@ arm_libcall_uses_aapcs_base (const_rtx libcall) convert_optab_libfunc (sfix_optab, DImode, SFmode)); add_libcall (libcall_htab, convert_optab_libfunc (ufix_optab, DImode, SFmode)); + + /* Values from double-precision helper functions are returned in core + registers if the selected core only supports single-precision + arithmetic, even if we are using the hard-float ABI. */ + if (TARGET_VFP) + { + add_libcall (libcall_htab, optab_libfunc (add_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (sdiv_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (smul_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (neg_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (sub_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (eq_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (lt_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (le_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (ge_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (gt_optab, DFmode)); + add_libcall (libcall_htab, optab_libfunc (unord_optab, DFmode)); + add_libcall (libcall_htab, + convert_optab_libfunc (sext_optab, DFmode, SFmode)); + add_libcall (libcall_htab, + convert_optab_libfunc (trunc_optab, SFmode, DFmode)); + } } return libcall && htab_find (libcall_htab, libcall) != NULL; @@ -4438,6 +4460,31 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, if (arm_libcall_uses_aapcs_base (libname)) pcum->pcs_variant = ARM_PCS_AAPCS; + /* We must pass arguments to double-precision helper functions in core + registers if we only have hardware support for single-precision + arithmetic, even if we are using the hard-float ABI. */ + if (TARGET_VFP + && (rtx_equal_p (libname, optab_libfunc (add_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (sdiv_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (smul_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (neg_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (sub_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (eq_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (lt_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (le_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (ge_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (gt_optab, DFmode)) + || rtx_equal_p (libname, optab_libfunc (unord_optab, DFmode)) + || rtx_equal_p (libname, convert_optab_libfunc (sext_optab, + DFmode, SFmode)) + || rtx_equal_p (libname, convert_optab_libfunc (trunc_optab, + SFmode, DFmode)) + || rtx_equal_p (libname, convert_optab_libfunc (sfix_optab, + SImode, DFmode)) + || rtx_equal_p (libname, convert_optab_libfunc (ufix_optab, + SImode, DFmode)))) + pcum->pcs_variant = ARM_PCS_AAPCS; + pcum->aapcs_ncrn = pcum->aapcs_next_ncrn = 0; pcum->aapcs_reg = NULL_RTX; pcum->aapcs_partial = 0; --MP_/Rty+y5doR0mxLlcLUgLgZI3--