This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]