AVR-Libc comes with hand-optimized float support functions written
in assembler.  These functions use the same naming conventions like
libgcc.  There are situations where this name clashed lead to performance
regression because the functions from libgcc are linked.  One example
are the new fixed-point support that convert fixed-point to/from float
and reference float/int conversion functions from within libgcc.

The float implementation in libm.a have been discussed several times
with the only result that it is very unlikely that the code will
ever be integrated into libgcc because the original authors are no
more around.  And is is much less work to add a new configure switch
than to port and integrate the code, given there were no license issues.
One point against such an extension was that such change to the compiler
establishes a dependency between the compiler and AVR-Libc, but this
decision has been made long ago by accepting code that actually should
had been added to libgcc -- but was not for whatever reason.

This patch removes that performance regressions by removing the
doubly implemented functions from libgcc by means of a new configure
option --with-avrlibc.

Moreover, some specs are adjusted so that -lm is treated very much like
-lgcc so that the user need not specify -lm by hand for core float
support like int/float conversions.

Without this patch, LTO compilations also lead to performance regression
because lto adds -plugin-opt=-pass-through=-lgcc etc. prior to the -lm
specified by the user.

Other cases where code is improved are C++ programs, see PR28718 for a
discussion.


There are less fails in gcc.dg/fixed-point, presumably because the rounding
is as expected by the test cases, i.e. there are no rounding errors as
mentioned in the review for PR54222:
http://gcc.gnu.org/ml/gcc-patches/2012-08/msg01586.html

Ok to install?


Johann


        PR target/54461
        * configure.ac (noconfigdirs,target=avr-*-*): Add target-newlib,
        target-libgloss if configured --with-avrlibc.
        * configure: Regenerate.

libgcc/
        PR target/54461
        * config.host (tmake_file,host=avr-*-*): Add avr/t-avrlibc if
        configured --with-avrlibc.
        * config/avr/t-avrlibc: New file.

gcc/
        PR target/54461
        * config.gcc (tm_file,target=avr-*-*): Add avr/avrlibc.h if
        configured --with-avrlibc.
        (tm_defines,target=avr-*-*): Add WITH_AVRLIBC if configured
        --with-avrlibc.
        * config/avr/avrlibc.h: New file.
        * config/avr/avr-c.c: Build-in define __WITH_AVRLIBC__ if
        configured --with-avrlibc.
Index: configure
===================================================================
--- configure	(revision 190887)
+++ configure	(working copy)
@@ -3500,6 +3500,13 @@ case "${target}" in
   arm-*-riscix*)
     noconfigdirs="$noconfigdirs ld target-libgloss"
     ;;
+  avr-*-rtems*)
+    ;;
+  avr-*-*)
+    if test x${with_avrlibc} = xyes; then
+      noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+    fi
+    ;;
   c4x-*-* | tic4x-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"
     ;;
Index: configure.ac
===================================================================
--- configure.ac	(revision 190887)
+++ configure.ac	(working copy)
@@ -891,6 +891,13 @@ case "${target}" in
   arm-*-riscix*)
     noconfigdirs="$noconfigdirs ld target-libgloss"
     ;;
+  avr-*-rtems*)
+    ;;
+  avr-*-*)
+    if test x${with_avrlibc} = xyes; then
+      noconfigdirs="$noconfigdirs target-newlib target-libgloss"
+    fi
+    ;;
   c4x-*-* | tic4x-*-*)
     noconfigdirs="$noconfigdirs target-libgloss"
     ;;
Index: libgcc/config/avr/t-avrlibc
===================================================================
--- libgcc/config/avr/t-avrlibc	(revision 0)
+++ libgcc/config/avr/t-avrlibc	(revision 0)
@@ -0,0 +1,66 @@
+# This file is used with --with-avrlibc=yes
+#
+# AVR-Libc comes with hand-optimized float routines.
+# For historical reasons, these routines live in AVR-Libc
+# and not in libgcc and use the same function names like libgcc.
+# To get the best support, i.e. always use the routines from
+# AVR-Libc, we remove these routines from libgcc.
+#
+# See also PR54461.
+#
+#
+# Arithmetic:
+#     __addsf3 __subsf3 __divsf3 __mulsf3 __negsf2
+#
+# Comparison:
+#     __cmpsf2 __unordsf2
+#     __eqsf2 __lesf2 __ltsf2 __nesf2 __gesf2 __gtsf2
+#
+# Conversion:
+#     __fixsfdi __fixunssfdi __floatdisf __floatundisf
+#     __fixsfsi __fixunssfsi __floatsisf __floatunsisf
+#
+#
+# These functions are contained in modules:
+#
+# _addsub_sf.o:   __addsf3  __subsf3
+# _mul_sf.o:      __mulsf3
+# _div_sf.o:      __divsf3
+# _negate_sf.o:   __negsf2
+#
+# _compare_sf.o:  __cmpsf2
+# _unord_sf.o:    __unordsf2
+# _eq_sf.o:       __eqsf2
+# _ne_sf.o:       __nesf2
+# _ge_sf.o:       __gesf2
+# _gt_sf.o:       __gtsf2
+# _le_sf.o:       __lesf2
+# _lt_sf.o:       __ltsf2
+#
+# _fixsfdi.o:     __fixsfdi
+# _fixunssfdi.o:  __fixunssfdi
+# _fixunssfsi.o:  __fixunssfsi
+# _floatdisf.o:   __floatdisf
+# _floatundisf.o: __floatundisf
+# _sf_to_si.o:    __fixsfsi
+# _si_to_sf.o:    __floatsisf
+# _usi_to_sf.o:   __floatunsisf
+
+
+# SFmode
+LIB2FUNCS_EXCLUDE += \
+	_addsub_sf \
+	_negate_sf \
+	_mul_sf _div_sf \
+	\
+	_compare_sf \
+	_unord_sf \
+	_eq_sf _ne_sf \
+	_gt_sf _ge_sf \
+	_lt_sf _le_sf \
+	\
+	_si_to_sf  _sf_to_si \
+	_usi_to_sf _sf_to_usi \
+	_fixunssfsi _fixsfdi \
+	_fixunssfdi \
+	_floatdisf _floatundisf
Index: libgcc/config.host
===================================================================
--- libgcc/config.host	(revision 190873)
+++ libgcc/config.host	(working copy)
@@ -380,6 +380,9 @@ avr-*-rtems*)
 avr-*-*)
 	# Make HImode functions for AVR
 	tmake_file="${cpu_type}/t-avr t-fpbit"
+	if test x${with_avrlibc} = xyes; then
+	    tmake_file="$tmake_file ${cpu_type}/t-avrlibc"
+	fi
 	tm_file="$tm_file avr/avr-lib.h"
 	;;
 bfin*-elf*)
Index: gcc/config/avr/avr-c.c
===================================================================
--- gcc/config/avr/avr-c.c	(revision 190873)
+++ gcc/config/avr/avr-c.c	(working copy)
@@ -148,6 +148,10 @@ avr_cpu_cpp_builtins (struct cpp_reader
   cpp_define_formatted (pfile, "__AVR_SFR_OFFSET__=0x%x",
                         avr_current_arch->sfr_offset);
     
+#ifdef WITH_AVRLIBC
+  cpp_define (pfile, "__WITH_AVRLIBC__");
+#endif /* WITH_AVRLIBC */
+      
   /* Define builtin macros so that the user can easily query if or if not
      non-generic address spaces (and which) are supported.
      This is only supported for C.  For C++, a language extension is needed
Index: gcc/config/avr/avrlibc.h
===================================================================
--- gcc/config/avr/avrlibc.h	(revision 0)
+++ gcc/config/avr/avrlibc.h	(revision 0)
@@ -0,0 +1,31 @@
+/* Definitions of target machine for the GNU compiler collection
+   for Atmel AVR micro controller.
+   Copyright (C) 2012
+   Free Software Foundation, Inc.
+   Contributed by Georg-Johann Lay (a...@gjlay.de)
+
+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/>.  */
+
+/* AVR-Libc implements functions from libgcc.a in libm.a, see PR54461.  */
+
+#undef  LIBGCC_SPEC
+#define LIBGCC_SPEC                                                     \
+  "%{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:%{!mmcu=attiny15:%{!mmcu=attiny28: -lgcc -lm }}}}}"
+
+#undef  LINK_GCC_C_SEQUENCE_SPEC
+#define LINK_GCC_C_SEQUENCE_SPEC \
+  "--start-group %G %L --end-group"
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 190873)
+++ gcc/config.gcc	(working copy)
@@ -892,6 +892,10 @@ avr-*-rtems*)
 	;;
 avr-*-*)
 	tm_file="elfos.h avr/elf.h avr/avr.h dbxelf.h avr/avr-stdint.h"
+	if test x${with_avrlibc} = xyes; then
+	    tm_file="${tm_file} ${cpu_type}/avrlibc.h"
+	    tm_defines="${tm_defines} WITH_AVRLIBC"
+	fi
 	tmake_file="avr/t-avr avr/t-multilib"
 	use_gcc_stdint=wrap
 	extra_gcc_objs="driver-avr.o avr-devices.o"

Reply via email to