Hi, for historical reasons, AVR-Libc implements functions that GCC expects to live in libgcc, namely float functions like __fixsfsi.
Currently, avr-gcc is not configurable to accommodate that situation which leads to performance problems if the float support functions from libgcc are used. This happens at least in the following situations: * The user does not specify -lm. -lm should only be needed if function from math.h are used, not for language core features like int i = (int) float. * The application is LTO compiled, i.e. linked with -flto. The plugin machinery passes lgcc -lc lgcc through to the linker by means of -plugin-opt=-pass-through=-lgcc etc. so that -lgcc is linked prior to -lm. * The user uses fixed <-> float conversion routines from libgcc. These routines refer float functions, and the linker resolves these function in libgcc if they are there. * avr-g++ is used as linker driver. In order to fix all of these cases, at least two changes are needed in the compiler. 1) Remove respective functions from libgcc 2) libm.a is not a "math library", it is a "libgcc supplement". Thus, -lm has to be treated like libgcc. avr.h currently has: #define LIBGCC_SPEC "\ %{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:\ %{!mmcu=attiny15:%{!mmcu=attiny28: -lgcc }}}}}" LINK_GCC_C_SEQUENCE_SPEC is defined and defaults to "%G %L %G" Together with 1) which is already contained in the proposed patch for libgcc, a reasonable spec layout would be #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" Could a AVR-Libc maintainer test this setup? To test the attached patch, use avr-gcc from trunk SVN 190644 or newer and configure --with-avrlibc=yes To test the new specs, you can $ avr-gcc -dumpspecs > my.specs and then $ avr-gcc -specs my.specs ... The specs in question are libgcc and link_gcc_c_sequence. This means that the option makes avr-gcc assume that AVR-Libc comes with a specific layout: -lm is available and comes with libgcc-like support and fills out the gaps introduced by LIB2FUNCS_EXCLUDE from t-avrlibc. Just like the t-avrlibc in libgcc, there would be a t-avrlibc Makefile snip in gcc that takes care of the specs and (re)defines them if configured for AVR-Libc cooperation. Moreover, it must be ensured that no function causes ABI clashes. For example, libgcc brings ffs with optimized ABI similar to __divmodxx4: The compiler knows what registers are clobbered and what are not, and/or it may pass values in non-ABI registers. Functions in question are, in all available modes: ffs, ctz, clz, bswap, popcount, parity BTW: The last point is an issue already present in the current releases and not related to a new configure option. Thanks, Johann
Index: libgcc/config.host =================================================================== --- libgcc/config.host (revision 190644) +++ 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: libgcc/Makefile.in =================================================================== --- libgcc/Makefile.in (revision 190644) +++ libgcc/Makefile.in (working copy) @@ -516,6 +516,10 @@ FPBIT_FUNCS := $(filter-out _sf_to_tf,$( DPBIT_FUNCS := $(filter-out _df_to_tf,$(DPBIT_FUNCS)) endif +FPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(FPBIT_FUNCS)) +DPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(DPBIT_FUNCS)) +TPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(TPBIT_FUNCS)) + fpbit-src := $(srcdir)/fp-bit.c # Build FPBIT. Index: libgcc/config/avr/t-avrlibc =================================================================== --- libgcc/config/avr/t-avrlibc (revision 0) +++ libgcc/config/avr/t-avrlibc (revision 0) @@ -0,0 +1,36 @@ +LIB2FUNCS_EXCLUDE += \ + _compare_sf \ + _eq_sf \ + _ne_sf \ + _gt_sf \ + _ge_sf \ + _lt_sf \ + _le_sf \ + _unord_sf \ + \ + _negate_sf \ + _addsub_sf \ + _mul_sf \ + _div_sf \ + \ + _si_to_sf _sf_to_si \ + _usi_to_sf _sf_to_usi + +# DF +LIB2FUNCS_EXCLUDE += \ + _sf_to_df + +LIB2FUNCS_EXCLUDE += \ + _fixunssfsi \ + _fixsfdi \ + _fixunssfdi \ + _floatdisf \ + _floatundisf + +# DF +LIB2FUNCS_EXCLUDE += \ + _fixdfdi \ + _fixunsdfsi \ + _fixunsdfdi \ + _floatdidf \ + _floatundidf
_______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list