This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] MIPS/libgcc: Add soft-fp support for SDE bare-iron targets
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Cc: Catherine Moore <clm at codesourcery dot com>
- Date: Thu, 28 Jun 2012 13:30:15 +0100
- Subject: [PATCH] MIPS/libgcc: Add soft-fp support for SDE bare-iron targets
Hello,
This change adds soft-fp support for SDE bare-iron targets.
The settings have been mostly based on the version already present in
glibc, except that the ABI variations have been merged into a single file
and conditionalised on preprocessor macros (and the file reformatted to
follow the GNU coding standard that the glibc variants don't). Only n32
has to be treated somewhat specially as it is ILP32 but its "long long"
type is 64-bit with native support (using single registers rather than
pairs). The rest is handled generically, based on the width of the types
chosen.
This has been regression tested for the mips-sde-elf target with no new
failures, using the o32 and n64 ABI multilibs, with and without
-msoft-float, o32 also with MIPS16 variants.
There's currently no SDE runtime support for n32, however despite the
unability to test I decided the configuration shouldn't be pessimised by
default (by avoiding the special exception and using the 32-bit "long"
type) as glibc already uses such an arrangement so it's been verified
elsewhere and if a platform that supports the n32 ABI decides later on to
enable soft-fp too, it will be verified in libgcc anyway. I believe this
is reasonable and avoids the risk of someone chooing the "long" type by
omission.
Comments or questions are welcome, otherwise OK to apply?
2012-06-28 Catherine Moore <clm@codesourcery.com>
Maciej W. Rozycki <macro@codesourcery.com>
libgcc/
* config/mips/sfp-machine.h: New file.
* config.host <mips*-sde-elf*>: Enable soft-fp.
Maciej
gcc-mips-softfp.diff
Index: gcc-trunk-4.6/libgcc/config/mips/sfp-machine.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc-trunk-4.6/libgcc/config/mips/sfp-machine.h 2012-06-24 14:38:40.083663725 +0100
@@ -0,0 +1,101 @@
+#if defined _ABIN32 && _MIPS_SIM == _ABIN32
+
+#define _FP_W_TYPE_SIZE 64
+#define _FP_W_TYPE unsigned long long
+#define _FP_WS_TYPE signed long long
+#define _FP_I_TYPE long long
+
+#else
+
+#define _FP_W_TYPE_SIZE _MIPS_SZLONG
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+
+#define _FP_MUL_MEAT_S(R, X, Y) \
+ _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_S, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_D(R, X, Y) \
+ _FP_MUL_MEAT_2_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_Q(R, X, Y) \
+ _FP_MUL_MEAT_4_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R, X, Y) \
+ _FP_DIV_MEAT_1_udiv_norm (S, R, X, Y)
+#define _FP_DIV_MEAT_D(R, X, Y) \
+ _FP_DIV_MEAT_2_udiv (D, R, X, Y)
+#define _FP_DIV_MEAT_Q(R, X, Y) \
+ _FP_DIV_MEAT_4_udiv (Q, R, X, Y)
+
+#else
+
+#define _FP_MUL_MEAT_S(R, X, Y) \
+ _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y)
+#define _FP_MUL_MEAT_D(R, X, Y) \
+ _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm)
+#define _FP_MUL_MEAT_Q(R, X, Y) \
+ _FP_MUL_MEAT_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R, X, Y) \
+ _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R, X, Y) \
+ _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y)
+#define _FP_DIV_MEAT_Q(R, X, Y) \
+ _FP_DIV_MEAT_2_udiv (Q, R, X, Y)
+
+#endif
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+/* From my experiments it seems X is chosen unless one of the
+ NaNs is sNaN, in which case the result is NANSIGN/NANFRAC. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs (X) \
+ | _FP_FRAC_HIGH_RAW_##fs (Y)) & _FP_QNANBIT_##fs) \
+ { \
+ R##_s = _FP_NANSIGN_##fs; \
+ _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc (R, X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define FP_EX_INVALID (1 << 4)
+#define FP_EX_DIVZERO (1 << 3)
+#define FP_EX_OVERFLOW (1 << 2)
+#define FP_EX_UNDERFLOW (1 << 1)
+#define FP_EX_INEXACT (1 << 0)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+#if defined MIPS_EB || defined __MIPSEB__ || defined MIPSEB || defined _MIPSEB
+# if defined MIPS_EL || defined __MIPSEL__ || defined MIPSEL || defined _MIPSEL
+# error "Both BIG_ENDIAN and LITTLE_ENDIAN defined!"
+# endif
+# define __BYTE_ORDER __BIG_ENDIAN
+#elif defined MIPS_EL || defined __MIPSEL__ || defined MIPSEL || defined _MIPSEL
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+# error "Cannot determine current byte order"
+#endif
+
+
+/* Define ALIASNAME as a strong alias for NAME. */
+#define strong_alias(name, aliasname) _strong_alias (name, aliasname)
+#define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
Index: gcc-trunk-4.6/libgcc/config.host
===================================================================
--- gcc-trunk-4.6.orig/libgcc/config.host 2012-06-22 20:31:35.000000000 +0100
+++ gcc-trunk-4.6/libgcc/config.host 2012-06-22 20:31:37.654759477 +0100
@@ -737,7 +737,7 @@ mips*-*-linux*) # Linux MIPS, either
fi
;;
mips*-sde-elf*)
- tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16"
+ tmake_file="$tmake_file mips/t-crtstuff mips/t-mips16 t-softfp-sfdf t-softfp-excl t-softfp"
case "${with_newlib}" in
yes)
# newlib / libgloss.