Optimize powerpc*-*-linux* e500 hardfp/soft-fp use.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 29 Oct 2014 12:59:16 +0000 (12:59 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 29 Oct 2014 12:59:16 +0000 (12:59 +0000)
Continuing the cleanups of libgcc soft-fp configuration for
powerpc*-*-linux* in preparation for implementing
TARGET_ATOMIC_ASSIGN_EXPAND_FENV for soft-float and e500, this patch
optimizes the choice of which functions to build for the e500 cases.

For e500v2, use of hardfp is generally right, except that calls to
__unordsf2 and __unorddf2 are actually generated by GCC from
__builtin_isunordered and so they need to be implemented with soft-fp
to avoid recursively calling themselves.  For e500v1, hardfp is right
for SFmode (except for __unordsf2) but soft-fp for DFmode (and when
using soft-fp, as usual it's best for the conversions between DFmode
and integers all to come directly from soft-fp rather than some coming
from libgcc2.c).  Thus, new variables hardfp_exclusions and
softfp_extras are added that configurations using t-hardfp and
t-softfp can use to achieve the desired effect of selectively mixing
the two sources of functions.

Tested with no regressions for crosses to powerpc-linux-gnuspe (both
e500v1 and e500v2); also checked that the same set of symbols and
versions is exported from shared libgcc before and after the patch.

* config/t-hardfp (hardfp_exclusions): Document new variable for
user to define.
(hardfp_func_list): Exclude functions from $(hardfp_exclusions).
* config/t-softfp (softfp_extras): Document new variable for user
to define.
(softfp_func_list): Add functions from $(softfp_extras).
* config/rs6000/t-e500v1-fp, config/rs6000/t-e500v2-fp: New files.
* config.host (powerpc*-*-linux*): For e500v1, use
rs6000/t-e500v1-fp and t-hardfp; do not use t-softfp-sfdf and
t-softfp-excl.  For e500v2, use t-hardfp-sfdf, rs6000/t-e500v2-fp
and t-hardfp; do not use t-softfp-sfdf and t-softfp-excl.

From-SVN: r216835

libgcc/ChangeLog
libgcc/config.host
libgcc/config/rs6000/t-e500v1-fp [new file with mode: 0644]
libgcc/config/rs6000/t-e500v2-fp [new file with mode: 0644]
libgcc/config/t-hardfp
libgcc/config/t-softfp

index 36a63bc..eb83460 100644 (file)
@@ -1,3 +1,17 @@
+2014-10-29  Joseph Myers  <joseph@codesourcery.com>
+
+       * config/t-hardfp (hardfp_exclusions): Document new variable for
+       user to define.
+       (hardfp_func_list): Exclude functions from $(hardfp_exclusions).
+       * config/t-softfp (softfp_extras): Document new variable for user
+       to define.
+       (softfp_func_list): Add functions from $(softfp_extras).
+       * config/rs6000/t-e500v1-fp, config/rs6000/t-e500v2-fp: New files.
+       * config.host (powerpc*-*-linux*): For e500v1, use
+       rs6000/t-e500v1-fp and t-hardfp; do not use t-softfp-sfdf and
+       t-softfp-excl.  For e500v2, use t-hardfp-sfdf, rs6000/t-e500v2-fp
+       and t-hardfp; do not use t-softfp-sfdf and t-softfp-excl.
+
 2014-10-26  John David Anglin  <danglin@gcc.gnu.org>
 
        * config/pa/linux-unwind.h (pa32_read_access_ok): New function.
index d6c7df7..6d0fccd 100644 (file)
@@ -1000,8 +1000,11 @@ powerpc*-*-linux*)
        soft)
                tmake_file="${tmake_file} t-softfp-sfdf t-softfp"
                ;;
-       e500v1|e500v2)
-               tmake_file="${tmake_file} t-softfp-sfdf t-softfp-excl t-softfp"
+       e500v1)
+               tmake_file="${tmake_file} rs6000/t-e500v1-fp t-softfp t-hardfp"
+               ;;
+       e500v2)
+               tmake_file="${tmake_file} t-hardfp-sfdf rs6000/t-e500v2-fp t-softfp t-hardfp"
                ;;
        *)
                echo "Unknown ppc_fp_type $ppc_fp_type" 1>&2
diff --git a/libgcc/config/rs6000/t-e500v1-fp b/libgcc/config/rs6000/t-e500v1-fp
new file mode 100644 (file)
index 0000000..c1f7a0c
--- /dev/null
@@ -0,0 +1,32 @@
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Use hardfp.c for SFmode (except __unordsf2), soft-fp for DFmode.
+# For SFmode, libgcc2.c functions are used where applicable; for
+# DFmode, they are excluded.
+hardfp_float_modes := sf
+hardfp_int_modes := si
+hardfp_extensions :=
+hardfp_truncations :=
+hardfp_exclusions := unordsf2
+softfp_float_modes := df
+softfp_int_modes := si di
+softfp_extensions := sfdf
+softfp_truncations := dfsf
+softfp_exclude_libgcc2 := n
+softfp_extras := unordsf2
diff --git a/libgcc/config/rs6000/t-e500v2-fp b/libgcc/config/rs6000/t-e500v2-fp
new file mode 100644 (file)
index 0000000..636b28f
--- /dev/null
@@ -0,0 +1,26 @@
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# All operations except __unordsf2 and __unorddf2 can come from hardfp.c.
+hardfp_exclusions := unordsf2 unorddf2
+softfp_float_modes :=
+softfp_int_modes :=
+softfp_extensions :=
+softfp_truncations :=
+softfp_exclude_libgcc2 := n
+softfp_extras := unordsf2 unorddf2
index fe02f8e..019a6ab 100644 (file)
 #                    e.g. sfdf
 # hardfp_truncations: a list of truncations between hardware floating-point
 #                     modes, e.g. dfsf
+#
+# If some functions that would otherwise be defined should not be
+# defined by this file (typically because the target would compile
+# certain operations into a call to the libgcc function, which thus
+# needs to be defined elsewhere to use software floating point), also
+# define hardfp_exclusions to be a list of those functions,
+# e.g. unorddf2.
 
 # Functions parameterized by a floating-point mode M.
 hardfp_func_bases := addM3 subM3 negM2 mulM3 divM3
@@ -50,6 +57,8 @@ hardfp_func_list += $(foreach pair, $(hardfp_extensions), \
 hardfp_func_list += $(foreach pair, $(hardfp_truncations), \
                              $(subst M,$(pair),truncM2))
 
+hardfp_func_list := $(filter-out $(hardfp_exclusions),$(hardfp_func_list))
+
 # Regexp for matching a floating-point mode.
 hardfp_mode_regexp := $(shell echo $(hardfp_float_modes) | sed 's/ /\\|/g')
 
index 456fdce..43e0b4d 100644 (file)
 # is a soft-float mode; for example, sftf where sf is hard-float and
 # tf is soft-float.
 #
+# If some additional functions should be built that are not implied by
+# the above settings, also define softfp_extras as a list of those
+# functions, e.g. unorddf2.
+#
 # If the libgcc2.c functions should not be replaced, also define:
 #
 # softfp_exclude_libgcc2 := y
@@ -61,7 +65,8 @@ softfp_func_list := \
               $(foreach i,$(softfp_int_modes), \
                           $(softfp_floatint_funcs))) \
   $(foreach e,$(softfp_extensions),extend$(e)2) \
-  $(foreach t,$(softfp_truncations),trunc$(t)2)
+  $(foreach t,$(softfp_truncations),trunc$(t)2) \
+  $(softfp_extras)
 
 ifeq ($(softfp_exclude_libgcc2),y)
 # This list is taken from mklibgcc.in and doesn't presently allow for