Hello,
> > > > Fixes for high level libraries should also be
> > > > high level (dmult vs __FLT_MAX_EXP__); i.e. there should be no change in
> > a
> > > > different package which is specific for MIPS. The type double should
> > stay
> > > > double and is handled without a problem when the FPU is 32 bit in ABI
> > o32.
> > > > The problem is only with the single/double conversion functions and the
> > ABI
> > > > n32.
> > >
> > > I didn't quite follow why you specifically say n32 in the last sentence...
> > > What is harder to fix about n32 than o32?
> >
> > "-msingle-float" with n32 creates 64 bit FPU instructions like dmtc1 and
> > dmfc1. So I can't compile it for r5900. When I disable it, I get internal
> > compiler errors.
>
> That certainly seems like a bug. Can you file a bug report for that with
> a test case? I'll try and handle it when I next work on the single-float
> support in GCC.
I added the bug report:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61983
> Did you manage to get the libgcc patch reworked to be independent of r5900?
I needed to get my build environment in a state where I can change the code. I
needed to test building the toolchain for 14 different MIPS configurations. I
tested that 7 configurations build something where floating point calculations
are correct. I needed to use my own tests for this, because I didn't find any
testsuite which does it correctly.
I attached the new version of the patch which I tested with and without the FPU
emulation on the MIPS r5900; i.e. I didn't tested with a normal MIPS, just what
my Linux kernel emulates on r5900.
When I compile for mipsel ABI o32 with -mhard-float and -msingle-fpu, It get
the warning:
Warning: float register should be even, was 1.
I would say the warning is wrong, because odd FPU registers are available.
Best regards
Jürgen Urban
diff -Nurp gcc-4.9.0/libgcc/config/t-hardfp-sf gcc-4.9.0-patched/libgcc/config/t-hardfp-sf
--- gcc-4.9.0/libgcc/config/t-hardfp-sf 1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.9.0-patched/libgcc/config/t-hardfp-sf 2014-07-31 22:05:24.177280902 +0200
@@ -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/>.
+
+hardfp_float_modes := sf
+# di and ti are provided by libgcc2.c where needed.
+hardfp_int_modes := si
+hardfp_extensions :=
+hardfp_truncations :=
+
+# Emulate 64 bit float:
+FPBIT = true
+DPBIT = true
+# Don't build functions handled by 32 bit hardware:
+LIB2FUNCS_EXCLUDE = _addsub_sf _mul_sf _div_sf \
+ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
+ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf \
+ _thenan_sf _sf_to_usi _usi_to_sf
diff -Nurp gcc-4.9.0/libgcc/config.host gcc-4.9.0-patched/libgcc/config.host
--- gcc-4.9.0/libgcc/config.host 2014-03-27 16:40:31.000000000 +0100
+++ gcc-4.9.0-patched/libgcc/config.host 2014-07-31 23:21:42.093280358 +0200
@@ -144,7 +144,11 @@ mips*-*-*)
cpu_type=mips
tmake_file="mips/t-mips"
if test "${libgcc_cv_mips_hard_float}" = yes; then
- tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp"
+ if test "${libgcc_cv_mips_single_float}" = yes; then
+ tmake_file="${tmake_file} t-hardfp-sf t-hardfp"
+ else
+ tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp"
+ fi
else
tmake_file="${tmake_file} t-softfp-sfdf"
fi
@@ -794,13 +798,18 @@ mips*-*-linux*) # Linux MIPS, either
# instructions that are not supported on r5900.
;;
*)
- tmake_file="${tmake_file} mips/t-mips16 t-slibgcc-libgcc"
+ if test x$with_arch != xr5900; then
+ tmake_file="${tmake_file} mips/t-mips16 t-slibgcc-libgcc"
+ fi
;;
esac
md_unwind_header=mips/linux-unwind.h
;;
mips*-sde-elf*)
- tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16"
+ tmake_file="$tmake_file mips/t-crtstuff"
+ if test x$with_arch != xr5900; then
+ tmake_file="$tmake_file mips/t-mips16"
+ fi
case "${with_newlib}" in
yes)
# newlib / libgloss.
@@ -828,7 +837,10 @@ mipsisa64sb1-*-elf* | mipsisa64sb1el-*-e
extra_parts="$extra_parts crti.o crtn.o"
;;
mips-*-elf* | mipsel-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
+ tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+ if test x$with_arch != xr5900; then
+ tmake_file="$tmake_file mips/t-mips16"
+ fi
extra_parts="$extra_parts crti.o crtn.o"
;;
mipsr5900-*-elf* | mipsr5900el-*-elf*)
@@ -836,7 +848,10 @@ mipsr5900-*-elf* | mipsr5900el-*-elf*)
extra_parts="$extra_parts crti.o crtn.o"
;;
mips64-*-elf* | mips64el-*-elf*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
+ tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+ if test x$with_arch != xr5900; then
+ tmake_file="$tmake_file mips/t-mips16"
+ fi
extra_parts="$extra_parts crti.o crtn.o"
;;
mips64r5900-*-elf* | mips64r5900el-*-elf*)
@@ -852,7 +867,10 @@ mips64orion-*-elf* | mips64orionel-*-elf
extra_parts="$extra_parts crti.o crtn.o"
;;
mips*-*-rtems*)
- tmake_file="$tmake_file mips/t-elf mips/t-crtstuff mips/t-mips16"
+ tmake_file="$tmake_file mips/t-elf mips/t-crtstuff"
+ if test x$with_arch != xr5900; then
+ tmake_file="$tmake_file mips/t-mips16"
+ fi
extra_parts="$extra_parts crti.o crtn.o"
;;
mips-wrs-vxworks)
diff -Nurp gcc-4.9.0/libgcc/configure.ac gcc-4.9.0-patched/libgcc/configure.ac
--- gcc-4.9.0/libgcc/configure.ac 2014-02-07 08:46:34.000000000 +0100
+++ gcc-4.9.0-patched/libgcc/configure.ac 2014-07-31 23:07:46.401280455 +0200
@@ -302,6 +302,14 @@ mips*-*-*)
#endif],
[libgcc_cv_mips_hard_float=yes],
[libgcc_cv_mips_hard_float=no])])
+ AC_CACHE_CHECK([whether the target is single-float],
+ [libgcc_cv_mips_single_float],
+ [AC_COMPILE_IFELSE(
+ [#ifndef __mips_single_float
+ #error FOO
+ #endif],
+ [libgcc_cv_mips_single_float=yes],
+ [libgcc_cv_mips_single_float=no])])
esac
# Collect host-machine-specific information.
--- gcc-4.9.0/libgcc/configure 2014-08-03 15:54:04.089096533 +0200
+++ gcc-4.9.0/libgcc/configure 2014-08-03 15:54:17.641096787 +0200
@@ -4352,6 +4352,26 @@ rm -f core conftest.err conftest.$ac_obj
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_mips_hard_float" >&5
$as_echo "$libgcc_cv_mips_hard_float" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target is single-float" >&5
+$as_echo_n "checking whether the target is single-float... " >&6; }
+if test "${libgcc_cv_mips_single_float+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __mips_single_float
+ #error FOO
+ #endif
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ libgcc_cv_mips_single_float=yes
+else
+ libgcc_cv_mips_single_float=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgcc_cv_mips_single_float" >&5
+$as_echo "$libgcc_cv_mips_single_float" >&6; }
esac
# Collect host-machine-specific information.