From patchwork Tue Feb 4 18:35:48 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 316711 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 78D072C0097 for ; Wed, 5 Feb 2014 05:36:05 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; q=dns; s=default; b=ewp8GB1qCl8hBS+r S5cpOsfFlaBP1WQ/L6H4TRhZd6FvV1nNA7+bSCuGExgGFYVBoQx2YZV7I6SSube9 aUFsDqiWlvNqUYAyA/NxA59MLve6rq+c3YZCn78je97kFm8z96Ruzj8fzbs/gtM6 vd3CZohy5tWTK2YiE54UfMXDo4I= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; s=default; bh=uy9ja3AuH61cnlWssxA1ba L9YxU=; b=syTBNj7B/RDdzYsppf2tCSNFvxB/G/r6c3dcpXOSFow65w3AU9vF/M LPJzOetWVUKt40iUi8RuIkCV+NBuDTmHdm2wnEH3VQt2iloz4piBxl2WTJnxeFZc ndx9bwhOxX8iJsxpo4tka7uLuTDUB4gdkD9oD4uE2YSQLfloC6Ahg= Received: (qmail 14464 invoked by alias); 4 Feb 2014 18:35:57 -0000 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 Received: (qmail 14450 invoked by uid 89); 4 Feb 2014 18:35:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_50, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wg0-f50.google.com Received: from mail-wg0-f50.google.com (HELO mail-wg0-f50.google.com) (74.125.82.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 04 Feb 2014 18:35:53 +0000 Received: by mail-wg0-f50.google.com with SMTP id l18so13030011wgh.17 for ; Tue, 04 Feb 2014 10:35:50 -0800 (PST) X-Received: by 10.181.13.82 with SMTP id ew18mr11429576wid.22.1391538950462; Tue, 04 Feb 2014 10:35:50 -0800 (PST) Received: from localhost ([2.28.234.162]) by mx.google.com with ESMTPSA id eo4sm38167901wib.9.2014.02.04.10.35.48 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Feb 2014 10:35:49 -0800 (PST) From: Richard Sandiford To: "Joseph S. Myers" Mail-Followup-To: "Joseph S. Myers" , , rdsandiford@googlemail.com Cc: Subject: Re: [MIPS] Use soft-fp for libgcc floating-point routines References: <87vbwx8p27.fsf@talisman.default> Date: Tue, 04 Feb 2014 18:35:48 +0000 In-Reply-To: (Joseph S. Myers's message of "Sun, 2 Feb 2014 19:08:52 +0000") Message-ID: <87d2j2914r.fsf@talisman.default> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 "Joseph S. Myers" writes: > I note that you're not using t-softfp-excl. Logically, it's best to use > the libgcc2.c functions in the cases where hardware floating point is > involved (when they are providing conversions to/from DImode/TImode, and > to/from unsigned, based on conversions to/from a narrower type or to/from > signed, and the floating-point type involved is a hardware type), because > that will be more efficient than a fully software implementation. But > when building for a soft-float multilib, and in any case when TFmode is > involved, it's best to use the soft-fp functions rather than the libgcc2.c > versions. Thanks, I'd missed that. > Thus: > > * For soft-float, what you have seems optimal. > > * For hard-float o32, using t-softfp-excl would be best. > > * For hard-float n32 and n64, what's optimal would be a hybrid the > makefile code doesn't yet support, so would need custom handling in MIPS > fragments; see above, and the t-softfp comment "This list is taken from > mklibgcc.in and doesn't presently allow for 64-bit targets where si should > become di and di should become ti.". How much this matters (and indeed > how much it matters for hard-float o32) depends on which of the > conversions involving SFmode / DFmode do actually end up using a libgcc > function (for which the libgcc2.c version would be better than the soft-fp > version). I agree that would work but in the end I went for a slightly different approach. The main reason was that although libgcc2.c provides those good di and ti conversion routines you mentioned, it doesn't AFAICT provide any si routines; they used to come from fpbit.c instead. So if we're going to provide fast di and ti routines we should probably try to do the same for si. TBH, I also didn't fancy trying to change anything as sensitive as that list of exclusions in t-softfp. As you say, most of the functions with hard-float support should be used rarely if at all. I think the only reason we ended up providing a full set of routines for hard-float was because, back in the bad old days when libgcc was in gcc/, it was very difficult to tailor it to individual multilibs. That includes the set of exported symbols. So here I just provide simple C functions for each operation that has hard-float support. We can then restrict the softfp stuff to functions that really do need softfp support, meaning that softfp_exclude_libgcc2 := n should always be OK. As an added bonus it reduces the footprint of libgcc_s.so on hard-float targets. Tested on mips64-linux-gnu and mipsisa64-sde-elf. I checked all the new o32, n32 and n64 functions to make sure that they produced the expected asm and (in particular) didn't have any recursive calls. I also rechecked the list of exported symbols in each case. Does this look OK? Thanks, Richard libgcc/ * configure.ac (libgcc_cv_mips_hard_float): New. * configure: Regenerate. * config.host (mips*-*-*): Use t-hardfp-sfdf rather than t-softfp-sfdf for hard-float targets. * config/mips/t-mips (LIB2_SIDITI_CONV_FUNCS): Reinstate. (softfp_float_modes, softfp_int_modes, softfp_extensions) (softfp_truncations, softfp_exclude_libgcc2): New. * config/mips/t-hardfp-sfdf: New file. * config/mips/hardfp.c: Likewise. Index: libgcc/configure.ac =================================================================== --- libgcc/configure.ac 2014-02-04 18:11:37.078922650 +0000 +++ libgcc/configure.ac 2014-02-04 18:11:41.534950708 +0000 @@ -292,6 +292,18 @@ EOF eval `${CC-cc} -E conftest.c | grep host_address=` rm -f conftest.c +case ${host} in +mips*-*-*) + AC_CACHE_CHECK([whether the target is hard-float], + [libgcc_cv_mips_hard_float], + [AC_COMPILE_IFELSE( + [#ifndef __mips_hard_float + #error FOO + #endif], + [libgcc_cv_mips_hard_float=yes], + [libgcc_cv_mips_hard_float=no])]) +esac + # Collect host-machine-specific information. . ${srcdir}/config.host Index: libgcc/config.host =================================================================== --- libgcc/config.host 2014-02-04 18:11:37.077922644 +0000 +++ libgcc/config.host 2014-02-04 18:11:41.434950078 +0000 @@ -142,7 +142,12 @@ microblaze*-*-*) mips*-*-*) # All MIPS targets provide a full set of FP routines. cpu_type=mips - tmake_file="mips/t-mips t-softfp-sfdf" + tmake_file="mips/t-mips" + if test "${libgcc_cv_mips_hard_float}" = yes; then + tmake_file="${tmake_file} mips/t-hardfp-sfdf" + else + tmake_file="${tmake_file} t-softfp-sfdf" + fi if test "${ac_cv_sizeof_long_double}" = 16; then tmake_file="${tmake_file} mips/t-softfp-tf" fi Index: libgcc/config/mips/t-mips =================================================================== --- libgcc/config/mips/t-mips 2014-02-04 18:11:37.077922644 +0000 +++ libgcc/config/mips/t-mips 2014-02-04 18:11:41.443950135 +0000 @@ -1,1 +1,9 @@ +LIB2_SIDITI_CONV_FUNCS = yes + +softfp_float_modes := +softfp_int_modes := si di +softfp_extensions := +softfp_truncations := +softfp_exclude_libgcc2 := n + LIB2ADD_ST += $(srcdir)/config/mips/lib2funcs.c Index: libgcc/config/mips/t-hardfp-sfdf =================================================================== --- /dev/null 2014-01-30 08:06:21.701666182 +0000 +++ libgcc/config/mips/t-hardfp-sfdf 2014-02-04 18:11:41.534950708 +0000 @@ -0,0 +1,26 @@ +# We need to provide a full set of FP routines for backward-compatibility. +mips-hf-bases := \ + addM3 subM3 negM2 mulM3 divM3 \ + eqM2 neM2 geM2 gtM2 leM2 ltM2 unordM2 \ + fixMsi floatsiM floatunsiM +mips-hf-modes := sf df + +mips-hf-funcs := $(foreach m, $(mips-hf-modes), \ + $(subst M,$(m),$(mips-hf-bases))) +mips-hf-funcs += extendsfdf2 truncdfsf2 + +mips-hf-defines-for = \ + $(shell echo $1 | \ + sed "s/\(.*\)\(sf\|df\)\(si\|2\|3\|\)$$/-DFUNC=__& -DOP_\1\3 -DTYPE=\2/") + +mips-hf-o = $(patsubst %,%$(objext),$(mips-hf-funcs)) +$(mips-hf-o): %$(objext): $(srcdir)/config/mips/hardfp.c + $(gcc_compile) $(call mips-hf-defines-for, $*) -c $< $(vis_hide) -Wno-missing-prototypes +libgcc-objects += $(mips-hf-o) + +ifeq ($(enable_shared),yes) +mips-hf-s-o = $(patsubst %,%_s$(objext),$(mips-hf-funcs)) +$(mips-hf-s-o): %_s$(objext): $(srcdir)/config/mips/hardfp.c + $(gcc_s_compile) $(call mips-hf-defines-for, $*) -c $< -Wno-missing-prototypes +libgcc-s-objects += $(mips-hf-s-o) +endif Index: libgcc/config/mips/hardfp.c =================================================================== --- /dev/null 2014-01-30 08:06:21.701666182 +0000 +++ libgcc/config/mips/hardfp.c 2014-02-04 18:11:41.534950708 +0000 @@ -0,0 +1,64 @@ +/* Dummy floating-point routines for MIPS hard-float code. + Copyright (C) 2014 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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. + +GCC 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 +. */ + +#define sf float +#define df double + +#if defined (OP_add3) +TYPE FUNC (TYPE x, TYPE y) { return x + y; } +#elif defined (OP_sub3) +TYPE FUNC (TYPE x, TYPE y) { return x - y; } +#elif defined (OP_neg2) +TYPE FUNC (TYPE x) { return -x; } +#elif defined (OP_mul3) +TYPE FUNC (TYPE x, TYPE y) { return x * y; } +#elif defined (OP_div3) +TYPE FUNC (TYPE x, TYPE y) { return x / y; } +#elif defined (OP_eq2) +int FUNC (TYPE x, TYPE y) { return x == y; } +#elif defined (OP_ne2) +int FUNC (TYPE x, TYPE y) { return x != y; } +#elif defined (OP_ge2) +int FUNC (TYPE x, TYPE y) { return x >= y; } +#elif defined (OP_gt2) +int FUNC (TYPE x, TYPE y) { return x > y; } +#elif defined (OP_le2) +int FUNC (TYPE x, TYPE y) { return x <= y; } +#elif defined (OP_lt2) +int FUNC (TYPE x, TYPE y) { return x < y; } +#elif defined (OP_unord2) +int FUNC (TYPE x, TYPE y) { return __builtin_isunordered (x, y); } +#elif defined (OP_fixsi) +int FUNC (TYPE x) { return (int) x; } +#elif defined (OP_floatsi) +TYPE FUNC (int x) { return (TYPE) x; } +#elif defined (OP_floatunsi) +TYPE FUNC (unsigned int x) { return (TYPE) x; } +#elif defined (OP_extendsf2) +TYPE FUNC (float x) { return (TYPE) x; } +#elif defined (OP_truncdf2) +TYPE FUNC (double x) { return (TYPE) x; } +#else +#error Unknown operation +#endif