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]

Re: PATCH: Enable TFmode for x86


On Wed, Jul 02, 2008 at 09:15:16AM +0200, Uros Bizjak wrote:
> On Wed, Jul 2, 2008 at 5:14 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> > On Tue, Jul 01, 2008 at 09:57:01PM +0000, Joseph S. Myers wrote:
> >> On Tue, 1 Jul 2008, H.J. Lu wrote:
> >>
> >> > while keeping the old version. It turns out that mkmap-symver.awk only
> >> > supports one version per symbol. My patch extends to multiple versions.
> >> > Since symbol version is only needed for shared library. I need to a way to
> >> > tell if we are compiling for shared library. I added -DSHARED to
> >> > shared-object.mk and provided backward compatibility for x86-64.
> >>
> >> This requires specific testing:
> >>
> >> * A binary (64-bit) built with current 4.3 branch with references to the
> >> symbols in question at GCC_3.0 in shared libgcc should continue to run
> >> with libgcc built with the patched compiler.
> >>
> >> * Such a binary built with the patched compiler should request the symbols
> >> in question at version GCC_4.3.0 and not GCC_3.0 (and so not work if run
> >> against the old libgcc).
> >>
> >> If that works and the patch is approved for trunk then the 4.3.0 version
> >> should also be added on 4.3 branch.
> >>
> >
> > I noticed a few issues:
> >
> > 1. __divtc3 and __multc3 should have GCC_4.3.0.
> > 2. config/libgcc-glibc.ver should use %exclude before redefining
> > version.
> >
> > This patch fixes those issues. There are no regressions on Linux/ia32,
> > Linux/ia64 and Linux/x86-64. I will post 4.4 vs. 4.3 results at
> >
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36669
> >
> > OK for trunk.
> 
> 386 backend (modulo library) parts are OK with a few nits below,
> however libgcc parts should be approved by Ian, since I have no deep
> knowledge in this area.

Ian, is this OK for trunk?

> > +            "im" ((USItype) (y0)))
> 
> Please add a %%% comment that "im" constraint is due to reload
> problems in the asm above. The correct constraint is "g".
> 
> > +
> > +# Provide fallbacks for  __builtin_copysignq nor __builtin_fabsq.
> 
> __builtin_copysignq _and_ __builtin_fabsq.
> 

Here is the updated patch. Since now libgcc can now more than one
version per symbol, define a new version for a symbol won't
automatically remove the old one.  We need to exclude the old version
first if it is invalid. I visiually inspected all libgcc-glibc version
files and added %exclude to

config/m32r/libgcc-glibc.ver
config/s390/libgcc-glibc.ver
config/sh/libgcc-glibc.ver
config/sparc/libgcc-sparc-glibc.ver

Could sparc, rs6000, sh, m32r and s390 also review this patch?

Thanks.


H.J.
---
gcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* config/i386/libgcc-glibc.ver: New.

	* config/i386/libgcc-x86_64-glibc.ver: Removed.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Remove i386/t-fprules-softfp64 soft-fp/t-softfp
	from tmake_file from i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*.  Add
	i386/t-fprules-softfp and soft-fp/t-softfp to tmake_file for
	i[34567]86-*-darwin*, x86_64-*-darwin*, i[34567]86-*-linux*,
	x86_64-*-linux*.  Add i386/t-linux to tmake_file for
	i[34567]86-*-linux*, x86_64-*-linux*.

	* libgcc-std.ver: Add empty GCC_4.4.0.

	* mkmap-symver.awk: Support multiple versions per symbol.

	* config/libgcc-glibc.ver: Add %exclude.

	* config/i386/i386.c (ix86_init_builtins): Always define
	__builtin_fabsq and __builtin_copysignq with fallbacks.
	(ix86_expand_builtin): Emit normal call for __builtin_fabsq
	and __builtin_copysignq if SSE2 isn't available.

	* config/i386/linux.h (LIBGCC2_HAS_TF_MODE): Defined.
	(LIBGCC2_TF_CEXT): Likwise.
	(TF_SIZE): Likwise.

	* config/i386/linux64.h (LIBGCC2_HAS_TF_MODE): Defined as 1.

	* config/i386/sfp-machine.h: Moved to libgcc.

	* config/i386/sfp-machine.h: New.
	* config/i386/t-linux: Likwise.

	* config/i386/t-darwin: Remove softfp_wrap_start and
	softfp_wrap_end.
	* config/i386/t-darwin64: Likewise.

	* config/i386/t-fprules-softfp64: Renamed to ...
	* config/i386/t-fprules-softfp: This.

	* config/i386/t-linux64: Remove SHLIB_MAPFILES, softfp_wrap_start
	and softfp_wrap_end.

	* config/m32r/libgcc-glibc.ver: Add %exclude.
	* config/s390/libgcc-glibc.ver: Likwise.
	* config/sh/libgcc-glibc.ver: Likwise.
	* config/sparc/libgcc-sparc-glibc.ver: Likwise.

libgcc/

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/36669
	* shared-object.mk ($(base)_s$(objext)): Add -DSHARED.

	* config/i386/64/_divtc3-compat.c: New.
	* config/i386/64/_multc3-compat.c: Likewise.
	* config/i386/64/_powitf2-compat.c: Likewise.
	* config/i386/64/eqtf2.c: Likewise.
	* config/i386/64/getf2.c: Likewise.
	* config/i386/64/letf2.c: Likewise.
	* config/i386/64/t-fprules-softfp: Likewise.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>

	* config.host: Add i386/${host_address}/t-fprules-softfp to
	tmake_file for i[34567]86-*-darwin*, x86_64-*-darwin*,
	i[34567]86-*-linux*, x86_64-*-linux*. 

	* configure.ac: Set host_address to 64 or 32 for x86.
	* configure: Regenerated.

	* Makefile.in (config.status): Also depend on
	$(srcdir)/config.host.

	* config/i386/32/t-fprules-softfp: New.
	* config/i386/32/tf-signs.c: Likewise.

	* config/i386/64/sfp-machine.h: New. Moved from gcc.

2008-07-01  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config/i386/32/sfp-machine.h: New.

--- gcc/gcc/config.gcc.quad	2008-06-27 18:43:07.000000000 -0700
+++ gcc/gcc/config.gcc	2008-07-02 06:36:59.000000000 -0700
@@ -1006,11 +1006,11 @@ i[34567]86-*-darwin*)
 	# then this file using that to set --with-cpu=i386 which has no -m64
 	# support.
 	with_cpu=${with_cpu:-generic}
-	tmake_file="${tmake_file} i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="${tmake_file} i386/t-crtpc i386/t-crtfm"
 	;;
 x86_64-*-darwin*)
 	with_cpu=${with_cpu:-generic}
-	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-fprules-softfp64 soft-fp/t-softfp i386/t-crtpc i386/t-crtfm"
+	tmake_file="t-darwin ${cpu_type}/t-darwin64 t-slibgcc-darwin i386/t-crtpc i386/t-crtfm"
 	tm_file="${tm_file} ${cpu_type}/darwin64.h"
 	;;
 i[34567]86-*-elf*)
@@ -1069,7 +1069,7 @@ i[34567]86-*-linux* | i[34567]86-*-kfree
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
-			tmake_file="${tmake_file} i386/t-linux64 i386/t-fprules-softfp64 soft-fp/t-softfp"
+			tmake_file="${tmake_file} i386/t-linux64"
 			need_64bit_hwint=yes
 			case X"${with_cpu}" in
 			Xgeneric|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx)
@@ -1101,7 +1101,7 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
-	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm i386/t-fprules-softfp64 soft-fp/t-softfp t-dfprules"
+	tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules"
 	;;
 i[34567]86-*-gnu*)
 	;;
@@ -2973,6 +2973,13 @@ case ${target} in
 		fi
 		;;
 
+	i[34567]86-*-darwin* | x86_64-*-darwin*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+		;;
+	i[34567]86-*-linux* | x86_64-*-linux*)
+		tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
+		;;
+
 	mips*-*-*)
 		if test x$gnu_ld = xyes
 		then
--- gcc/gcc/config/i386/i386.c.quad	2008-07-01 19:01:42.000000000 -0700
+++ gcc/gcc/config/i386/i386.c	2008-07-02 06:37:00.000000000 -0700
@@ -20247,16 +20247,26 @@ ix86_init_builtins (void)
 			       NULL, NULL_TREE);
   ix86_builtins[(int) IX86_BUILTIN_INFQ] = decl;
 
+  /* We will expand them to normal call if SSE2 isn't available since
+     they are used by libgcc. */
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ);
+  decl = add_builtin_function ("__builtin_fabsq", ftype,
+			       IX86_BUILTIN_FABSQ, BUILT_IN_MD,
+			       "__fabstf2", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   ftype = build_function_type_list (float128_type_node,
 				    float128_type_node,
 				    float128_type_node,
 				    NULL_TREE);
-  def_builtin_const (OPTION_MASK_ISA_SSE2, "__builtin_copysignq", ftype, IX86_BUILTIN_COPYSIGNQ);
+  decl = add_builtin_function ("__builtin_copysignq", ftype,
+			       IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
+			       "__copysigntf3", NULL_TREE);
+  ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
+  TREE_READONLY (decl) = 1;
 
   if (TARGET_MMX)
     ix86_init_mmx_sse_builtins ();
@@ -21610,7 +21620,16 @@ ix86_expand_builtin (tree exp, rtx targe
        i < ARRAY_SIZE (bdesc_args);
        i++, d++)
     if (d->code == fcode)
-      return ix86_expand_args_builtin (d, exp, target);
+      switch (fcode)
+	{
+	case IX86_BUILTIN_FABSQ:
+	case IX86_BUILTIN_COPYSIGNQ:
+	  if (!TARGET_SSE2)
+	    /* Emit a normal call if SSE2 isn't available.  */
+	    return expand_call (exp, target, ignore);
+	default:
+	  return ix86_expand_args_builtin (d, exp, target);
+	}
 
   for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
     if (d->code == fcode)
--- gcc/gcc/config/i386/libgcc-glibc.ver.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-glibc.ver	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,162 @@
+# In order to work around the very problems that force us to now generally
+# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
+# By now choosing the same version tags for these specific routines, we
+# maintain enough binary compatibility to allow future versions of glibc
+# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
+
+%ifndef __x86_64__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
+%inherit GCC_3.0 GLIBC_2.0
+GLIBC_2.0 {
+  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+
+  # Exception handling support functions used by most everyone.
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+%endif
+
+% 128 bit long double support was introduced with GCC 4.3.0 to 64bit
+% and with GCC 4.4.0 to 32bit.  These lines make the symbols to get
+% a @@GCC_4.3.0 or @@GCC_4.4.0 attached.
+
+%exclude {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+
+%ifdef __x86_64__
+GCC_3.0 {
+  __gttf2
+  __lttf2
+  __netf2
+}
+
+GCC_4.0.0 {
+  __divtc3
+  __multc3
+  __powitf2
+}
+
+GCC_4.3.0 {
+  __addtf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __extendxftf2
+  __fixtfdi
+  __fixtfsi
+  __fixtfti
+  __fixunstfdi
+  __fixunstfsi
+  __fixunstfti
+  __floatditf
+  __floatsitf
+  __floattitf
+  __floatunditf
+  __floatunsitf
+  __floatuntitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%else
+GCC_4.4.0 {
+  __addtf3
+  __copysigntf3
+  __divtc3
+  __divtf3
+  __eqtf2
+  __extenddftf2
+  __extendsftf2
+  __fabstf2
+  __fixtfdi
+  __fixtfsi
+  __fixunstfdi
+  __fixunstfsi
+  __floatditf
+  __floatsitf
+  __floatunditf
+  __floatunsitf
+  __getf2
+  __gttf2
+  __letf2
+  __lttf2
+  __multc3
+  __multf3
+  __negtf2
+  __netf2
+  __powitf2
+  __subtf3
+  __trunctfdf2
+  __trunctfsf2
+  __trunctfxf2
+  __unordtf2
+}
+%endif
--- gcc/gcc/config/i386/libgcc-x86_64-glibc.ver.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/libgcc-x86_64-glibc.ver	2008-07-02 06:59:34.000000000 -0700
@@ -1,86 +0,0 @@
-# In order to work around the very problems that force us to now generally
-# create a libgcc.so, glibc reexported a number of routines from libgcc.a.
-# By now choosing the same version tags for these specific routines, we
-# maintain enough binary compatibility to allow future versions of glibc
-# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
-
-%ifndef __x86_64__
-%inherit GCC_3.0 GLIBC_2.0
-GLIBC_2.0 {
-  # Sampling of DImode arithmetic used by (at least) i386 and m68k.
-  __divdi3
-  __moddi3
-  __udivdi3
-  __umoddi3
-
-  # Exception handling support functions used by most everyone.
-  __register_frame
-  __register_frame_table
-  __deregister_frame
-  __register_frame_info
-  __deregister_frame_info
-  __frame_state_for
-  __register_frame_info_table
-}
-%endif
-
-% 128 bit long double support was introduced with GCC 4.3.0.
-% These lines make the symbols to get a @@GCC_4.3.0 attached.
-
-%ifdef __x86_64__
-%exclude {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-
-GCC_4.3.0 {
-  __addtf3
-  __divtf3
-  __eqtf2
-  __extenddftf2
-  __extendsftf2
-  __fixtfdi
-  __fixtfsi
-  __fixtfti
-  __fixunstfdi
-  __fixunstfsi
-  __fixunstfti
-  __floatditf
-  __floatsitf
-  __floattitf
-  __floatunditf
-  __floatunsitf
-  __floatuntitf
-  __getf2
-  __letf2
-  __multf3
-  __negtf2
-  __subtf3
-  __trunctfdf2
-  __trunctfsf2
-  __unordtf2
-}
-%endif
--- gcc/gcc/config/i386/linux.h.quad	2008-04-25 18:36:32.000000000 -0700
+++ gcc/gcc/config/i386/linux.h	2008-07-02 06:37:00.000000000 -0700
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3.  
 	   : "=d"(BASE))
 #endif
 
+/* Put all *tf routines in libgcc.  */
+#undef LIBGCC2_HAS_TF_MODE
+#define LIBGCC2_HAS_TF_MODE 1
+#define LIBGCC2_TF_CEXT q
+#define TF_SIZE 113
+
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
--- gcc/gcc/config/i386/linux64.h.quad	2007-08-03 06:25:42.000000000 -0700
+++ gcc/gcc/config/i386/linux64.h	2008-07-02 06:37:00.000000000 -0700
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3.  
 
 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE
-#define LIBGCC2_HAS_TF_MODE TARGET_64BIT
+#define LIBGCC2_HAS_TF_MODE 1
 #define LIBGCC2_TF_CEXT q
 #define TF_SIZE 113
 
--- gcc/gcc/config/i386/sfp-machine.h.quad	2008-02-19 20:52:26.000000000 -0800
+++ gcc/gcc/config/i386/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -1,143 +1,5 @@
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-typedef int TItype __attribute__ ((mode (TI)));
-typedef unsigned int UTItype __attribute__ ((mode (TI)));
-
-#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
-
-/* The type of the result of a floating point comparison.  This must
-   match `__libgcc_cmp_return__' in GCC for the target.  */
-typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
-#define CMPtype __gcc_CMPtype
-
-#define _FP_MUL_MEAT_Q(R,X,Y)                           \
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		_FP_QNANBIT_S
-#define _FP_NANFRAC_D		_FP_QNANBIT_D
-#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
-#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
-#define _FP_NANSIGN_S		1
-#define _FP_NANSIGN_D		1
-#define _FP_NANSIGN_E		1
-#define _FP_NANSIGN_Q		1
-
-#define _FP_KEEPNANFRACP 1
-
-/* Here is something Intel misdesigned: the specs don't define
-   the case where we have two NaNs with same mantissas, but
-   different sign. Different operations pick up different NaNs.  */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if (_FP_FRAC_GT_##wc(X, Y)					\
-	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
-      {								\
-	R##_s = X##_s;						\
-        _FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-        _FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-#define FP_EX_INVALID		0x01
-#define FP_EX_DENORM		0x02
-#define FP_EX_DIVZERO		0x04
-#define FP_EX_OVERFLOW		0x08
-#define FP_EX_UNDERFLOW		0x10
-#define FP_EX_INEXACT		0x20
-
-struct fenv
-{
-  unsigned short int __control_word;
-  unsigned short int __unused1;
-  unsigned short int __status_word;
-  unsigned short int __unused2;
-  unsigned short int __tags;
-  unsigned short int __unused3;
-  unsigned int __eip;
-  unsigned short int __cs_selector;
-  unsigned int __opcode:11;
-  unsigned int __unused4:5;
-  unsigned int __data_offset;
-  unsigned short int __data_selector;
-  unsigned short int __unused5;
-};
-
-#define FP_HANDLE_EXCEPTIONS						\
-  do {									\
-    if (_fex & FP_EX_INVALID)						\
-      {									\
-	float f = 0.0;							\
-	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
-      }									\
-    if (_fex & FP_EX_DIVZERO)						\
-      {									\
-	float f = 1.0, g = 0.0;						\
-	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
-      }									\
-    if (_fex & FP_EX_OVERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_OVERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_UNDERFLOW)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_UNDERFLOW;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-    if (_fex & FP_EX_INEXACT)						\
-      {									\
-	struct fenv temp;						\
-	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
-	temp.__status_word |= FP_EX_INEXACT;				\
-	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
-	__asm__ __volatile__ ("fwait");					\
-      }									\
-  } while (0)
-
-#define FP_RND_NEAREST		0
-#define FP_RND_ZERO		0xc00
-#define FP_RND_PINF		0x800
-#define FP_RND_MINF		0x400
-
-#define _FP_DECL_EX \
-  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
-
-#define FP_INIT_ROUNDMODE			\
-  do {						\
-    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
-  } while (0)
-
-#define FP_ROUNDMODE		(_fcw & 0xc00)
-
-#define	__LITTLE_ENDIAN	1234
-#define	__BIG_ENDIAN	4321
-
-#define __BYTE_ORDER __LITTLE_ENDIAN
-
-/* Define ALIASNAME as a strong alias for NAME.  */
-#if defined __MACH__
-/* Mach-O doesn't support aliasing.  If these functions ever return
-   anything but CMPtype we need to revisit this... */
-#define strong_alias(name, aliasname) \
-  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#ifdef __x86_64__
+#include "config/i386/64/sfp-machine.h"
 #else
-# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
-# define _strong_alias(name, aliasname) \
-  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#include "config/i386/32/sfp-machine.h"
 #endif
--- gcc/gcc/config/i386/t-darwin.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin	2008-07-02 06:37:00.000000000 -0700
@@ -2,6 +2,3 @@ MULTILIB_OPTIONS = m64
 MULTILIB_DIRNAMES = x86_64
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-darwin64.quad	2007-05-26 07:35:21.000000000 -0700
+++ gcc/gcc/config/i386/t-darwin64	2008-07-02 06:37:00.000000000 -0700
@@ -1,5 +1,2 @@
 LIB2_SIDITI_CONV_FUNCS=yes
 LIB2FUNCS_EXTRA = $(srcdir)/config/darwin-64.c
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/i386/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,6 @@
+softfp_float_modes := tf
+softfp_int_modes := si di ti
+softfp_extensions := sftf dftf xftf
+softfp_truncations := tfsf tfdf tfxf
+softfp_machine_header := i386/sfp-machine.h
+softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-fprules-softfp64.quad	2007-05-18 07:10:43.000000000 -0700
+++ gcc/gcc/config/i386/t-fprules-softfp64	2008-07-02 06:59:34.000000000 -0700
@@ -1,6 +0,0 @@
-softfp_float_modes := tf
-softfp_int_modes := si di ti
-softfp_extensions := sftf dftf xftf
-softfp_truncations := tfsf tfdf tfxf
-softfp_machine_header := i386/sfp-machine.h
-softfp_exclude_libgcc2 := n
--- gcc/gcc/config/i386/t-linux.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/gcc/config/i386/t-linux	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,5 @@
+# On 64bit we do not need any exports for glibc for 64-bit libgcc_s.
+# Need to support TImode for x86.  Override the settings from
+# t-slibgcc-elf-ver and t-linux
+SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
+		 $(srcdir)/config/i386/libgcc-glibc.ver
--- gcc/gcc/config/i386/t-linux64.quad	2008-06-29 12:02:20.000000000 -0700
+++ gcc/gcc/config/i386/t-linux64	2008-07-02 06:37:00.000000000 -0700
@@ -1,9 +1,3 @@
-# On x86-64 we do not need any exports for glibc for 64-bit libgcc_s,
-# override the settings
-# from t-slibgcc-elf-ver and t-linux
-SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver \
-		 $(srcdir)/config/i386/libgcc-x86_64-glibc.ver
-
 # On Debian, Ubuntu and other derivative distributions, the 32bit libraries
 # are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to
 # /lib and /usr/lib, while other distributions install libraries into /lib64
@@ -21,6 +15,3 @@ INSTALL_LIBGCC = install-multilib
 EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \
 		     crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \
 		     crtfastmath.o
-
-softfp_wrap_start := '\#ifdef __x86_64__'
-softfp_wrap_end := '\#endif'
--- gcc/gcc/config/libgcc-glibc.ver.quad	2008-07-01 19:05:44.000000000 -0700
+++ gcc/gcc/config/libgcc-glibc.ver	2008-07-02 06:37:00.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   # Sampling of DImode arithmetic used by (at least) i386 and m68k.
--- gcc/gcc/config/m32r/libgcc-glibc.ver.quad	2006-09-27 22:37:56.000000000 -0700
+++ gcc/gcc/config/m32r/libgcc-glibc.ver	2008-07-02 06:52:15.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.3.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.3
 GLIBC_2.3 {
   __register_frame
--- gcc/gcc/config/s390/libgcc-glibc.ver.quad	2006-09-27 22:37:54.000000000 -0700
+++ gcc/gcc/config/s390/libgcc-glibc.ver	2008-07-02 06:58:44.000000000 -0700
@@ -9,6 +9,20 @@
 # ever glibc release on the platform was GLIBC_2.2.
 
 %ifndef __s390x__
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.0
 GLIBC_2.0 {
   __divdi3
@@ -27,6 +41,16 @@ GLIBC_2.0 {
 %endif
 
 %ifdef __s390x__
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
--- gcc/gcc/config/sh/libgcc-glibc.ver.quad	2006-09-27 22:38:01.000000000 -0700
+++ gcc/gcc/config/sh/libgcc-glibc.ver	2008-07-02 06:51:14.000000000 -0700
@@ -8,6 +8,16 @@
 # because GLIBC_2.0 does not exist on this architecture, as the first 
 # ever glibc release on the platform was GLIBC_2.2.
 
+%exclude {
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %inherit GCC_3.0 GLIBC_2.2
 GLIBC_2.2 {
   __register_frame
@@ -18,4 +28,3 @@ GLIBC_2.2 {
   __frame_state_for
   __register_frame_info_table
 }
-
--- gcc/gcc/config/sparc/libgcc-sparc-glibc.ver.quad	2006-09-27 22:37:56.000000000 -0700
+++ gcc/gcc/config/sparc/libgcc-sparc-glibc.ver	2008-07-02 06:57:38.000000000 -0700
@@ -4,6 +4,20 @@
 # maintain enough binary compatibility to allow future versions of glibc
 # to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
 
+%exclude {
+  __divdi3
+  __moddi3
+  __udivdi3
+  __umoddi3
+  __register_frame
+  __register_frame_table
+  __deregister_frame
+  __register_frame_info
+  __deregister_frame_info
+  __frame_state_for
+  __register_frame_info_table
+}
+
 %ifdef __arch64__
 %define GLIBC_VER GLIBC_2.2
 %else
--- gcc/gcc/libgcc-std.ver.quad	2007-09-29 07:58:29.000000000 -0700
+++ gcc/gcc/libgcc-std.ver	2008-07-02 06:37:00.000000000 -0700
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
   __satfractunstiuda
   __satfractunstiuta
 }
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
--- gcc/gcc/mkmap-symver.awk.quad	2008-06-06 19:41:18.000000000 -0700
+++ gcc/gcc/mkmap-symver.awk	2008-07-02 06:37:00.000000000 -0700
@@ -46,7 +46,8 @@ state == "nm" && ($1 == "U" || $2 == "U"
 }
 
 state == "nm" && NF == 3 {
-  def[$3] = 1;
+  split ($3, s, "@")
+  def[s[1]] = 1;
   sawsymbol = 1;
   next;
 }
@@ -82,10 +83,13 @@ $1 == "}" {
 
 {
   sym = prefix $1;
+  symbols[sym] = 1
   if (thislib != "%exclude")
-    ver[sym] = thislib;
-  else
-    delete ver[sym];
+    ver[sym, thislib] = 1;
+  else {
+    for (l in libs)
+      ver[sym, l] = 0;
+  }
   next;
 }
 
@@ -107,8 +111,8 @@ function output(lib) {
     output(inherit[lib]);
 
   empty=1
-  for (sym in ver)
-    if ((ver[sym] == lib) && (sym in def))
+  for (sym in symbols)
+    if ((ver[sym, lib] != 0) && (sym in def))
       {
 	if (empty)
 	  {
--- gcc/libgcc/Makefile.in.quad	2008-06-11 06:40:45.000000000 -0700
+++ gcc/libgcc/Makefile.in	2008-07-02 06:37:00.000000000 -0700
@@ -138,7 +138,7 @@ config.h: stamp-h ; @true
 stamp-h: $(srcdir)/config.in config.status Makefile
 	CONFIG_FILES= CONFIG_HEADERS=config.h:$(srcdir)/config.in $(SHELL) ./config.status
 
-config.status: $(srcdir)/configure
+config.status: $(srcdir)/configure $(srcdir)/config.host
 	$(SHELL) ./config.status --recheck
 
 include $(gcc_objdir)/libgcc.mvars
--- gcc/libgcc/config.host.quad	2008-06-08 08:48:36.000000000 -0700
+++ gcc/libgcc/config.host	2008-07-02 06:37:00.000000000 -0700
@@ -578,3 +578,10 @@ i[34567]86-*-linux* | x86_64-*-linux*)
 	tmake_file="${tmake_file} t-tls"
 	;;
 esac
+
+case ${host} in
+i[34567]86-*-darwin* | x86_64-*-darwin* | \
+  i[34567]86-*-linux* | x86_64-*-linux*)
+	tmake_file="${tmake_file} i386/${host_address}/t-fprules-softfp"
+	;;
+esac
--- gcc/libgcc/config/i386/32/sfp-machine.h.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,217 @@
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned int
+#define _FP_WS_TYPE		signed int
+#define _FP_I_TYPE		int
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("add{l} {%11,%3|%3,%11}\n\t"					\
+	   "adc{l} {%9,%2|%2,%9}\n\t"					\
+	   "adc{l} {%7,%1|%1,%7}\n\t"					\
+	   "adc{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "%1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%3" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("add{l} {%8,%2|%2,%8}\n\t"					\
+	   "adc{l} {%6,%1|%1,%6}\n\t"					\
+	   "adc{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "%0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "%1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "%2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+/* FIXME: The last constraint should be "g" instead of "im" if reload
+   works properly.  */
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  __asm__ ("sub{l} {%11,%3|%3,%11}\n\t"					\
+	   "sbb{l} {%9,%2|%2,%9}\n\t"					\
+	   "sbb{l} {%7,%1|%1,%7}\n\t"					\
+	   "sbb{l} {%5,%0|%0,%5}"					\
+	   : "=r" ((USItype) (r3)),					\
+	     "=&r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x3)),					\
+	     "g" ((USItype) (y3)),					\
+	     "1" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "2" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "3" ((USItype) (x0)),					\
+	     "im" ((USItype) (y0)))
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("sub{l} {%8,%2|%2,%8}\n\t"					\
+	   "sbb{l} {%6,%1|%1,%6}\n\t"					\
+	   "sbb{l} {%4,%0|%0,%4}"					\
+	   : "=r" ((USItype) (r2)),					\
+	     "=&r" ((USItype) (r1)),					\
+	     "=&r" ((USItype) (r0))					\
+	   : "0" ((USItype) (x2)),					\
+	     "g" ((USItype) (y2)),					\
+	     "1" ((USItype) (x1)),					\
+	     "g" ((USItype) (y1)),					\
+	     "2" ((USItype) (x0)),					\
+	     "g" ((USItype) (y0)))
+
+
+#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(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)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D, 0
+/* Even if XFmode is 12byte,  we have to pad it to 16byte since soft-fp
+   emulation is done in 16byte.  */
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0, 0, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f;							\
+	__asm__ __volatile__ ("fdiv %0" : "+t" (f));			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("fdivp" : "=t" (f)			\
+			      	      : "0" (f), "u" (g)		\
+				      : "st(1)");			\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/32/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,8 @@
+# Filter out TImode functions
+tifunctions = fixtfti.c fixunstfti.c floattitf.c floatuntitf.c
+tifunctions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tifunctions))
+
+LIB2ADD := $(filter-out $(tifunctions), $(LIB2ADD))
+
+# Provide fallbacks for __builtin_copysignq and __builtin_fabsq.
+LIB2ADD += $(srcdir)/config/i386/32/tf-signs.c
--- gcc/libgcc/config/i386/32/tf-signs.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/32/tf-signs.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,64 @@
+/* Copyright (C) 2008 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+union _FP_UNION_Q
+{
+   __float128 flt;
+   struct 
+   {
+      unsigned long frac0 : 32;
+      unsigned long frac1 : 32;
+      unsigned long frac2 : 32;
+      unsigned long frac3 : 16;
+      unsigned exp : 15;
+      unsigned sign : 1;
+   } bits __attribute__((packed));
+};
+
+__float128
+__copysigntf3 (__float128 a, __float128 b)
+{
+  union _FP_UNION_Q A, B;
+
+  A.flt = a;
+  B.flt = b;
+  A.bits.sign = B.bits.sign;
+
+  return A.flt;
+}
+
+__float128
+__fabstf2 (__float128 a)
+{
+  union _FP_UNION_Q A;
+
+  A.flt = a;
+  A.bits.sign = 0;
+
+  return A.flt;
+}
--- gcc/libgcc/config/i386/64/_divtc3-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_divtc3-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __divtc3 __divtc3_shared
+#endif
+
+#define L_divtc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __divtc3
+extern __typeof__ (__divtc3_shared) __divtc3_compat __attribute__((alias ("__divtc3_shared")));
+
+asm (".symver __divtc3_compat,__divtc3@GCC_4.0.0");
+asm (".symver __divtc3_shared,__divtc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_multc3-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_multc3-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __multc3 __multc3_shared
+#endif
+
+#define L_multc3
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __multc3
+extern __typeof__ (__multc3_shared) __multc3_compat __attribute__((alias ("__multc3_shared")));
+
+asm (".symver __multc3_compat,__multc3@GCC_4.0.0");
+asm (".symver __multc3_shared,__multc3@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/_powitf2-compat.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/_powitf2-compat.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,14 @@
+#ifdef SHARED
+#define __powitf2 __powitf2_shared
+#endif
+
+#define L_powitf2
+#include "libgcc2.c"
+
+#ifdef SHARED
+#undef __powitf2
+extern __typeof__ (__powitf2_shared) __powitf2_compat __attribute__((alias ("__powitf2_shared")));
+
+asm (".symver __powitf2_compat,__powitf2@GCC_4.0.0");
+asm (".symver __powitf2_shared,__powitf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/eqtf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/eqtf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __netf2 __netf2_shared
+#endif
+
+#include "config/soft-fp/eqtf2.c"
+
+#ifdef SHARED
+#undef __netf2
+strong_alias (__netf2_shared, __netf2_compat);
+
+asm (".symver __netf2_compat,__netf2@GCC_3.0");
+asm (".symver __netf2_shared,__netf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/getf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/getf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __gttf2 __gttf2_shared
+#endif
+
+#include "config/soft-fp/getf2.c"
+
+#ifdef SHARED
+#undef __gttf2
+strong_alias (__gttf2_shared, __gttf2_compat);
+
+asm (".symver __gttf2_compat,__gttf2@GCC_3.0");
+asm (".symver __gttf2_shared,__gttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/letf2.c.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/letf2.c	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,13 @@
+#ifdef SHARED
+#define __lttf2 __lttf2_shared
+#endif
+
+#include "config/soft-fp/letf2.c"
+
+#ifdef SHARED
+#undef __lttf2
+strong_alias (__lttf2_shared, __lttf2_compat);
+
+asm (".symver __lttf2_compat,__lttf2@GCC_3.0");
+asm (".symver __lttf2_shared,__lttf2@@GCC_4.3.0");
+#endif
--- gcc/libgcc/config/i386/64/sfp-machine.h.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/sfp-machine.h	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,143 @@
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+typedef int TItype __attribute__ ((mode (TI)));
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+
+#define TI_BITS (__CHAR_BIT__ * (int)sizeof(TItype))
+
+/* The type of the result of a floating point comparison.  This must
+   match `__libgcc_cmp_return__' in GCC for the target.  */
+typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#define CMPtype __gcc_CMPtype
+
+#define _FP_MUL_MEAT_Q(R,X,Y)                           \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_Q(R,X,Y)   _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_E		_FP_QNANBIT_E, 0
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q, 0
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_E		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if (_FP_FRAC_GT_##wc(X, Y)					\
+	|| (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*')))	\
+      {								\
+	R##_s = X##_s;						\
+        _FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+        _FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+#define FP_EX_INVALID		0x01
+#define FP_EX_DENORM		0x02
+#define FP_EX_DIVZERO		0x04
+#define FP_EX_OVERFLOW		0x08
+#define FP_EX_UNDERFLOW		0x10
+#define FP_EX_INEXACT		0x20
+
+struct fenv
+{
+  unsigned short int __control_word;
+  unsigned short int __unused1;
+  unsigned short int __status_word;
+  unsigned short int __unused2;
+  unsigned short int __tags;
+  unsigned short int __unused3;
+  unsigned int __eip;
+  unsigned short int __cs_selector;
+  unsigned int __opcode:11;
+  unsigned int __unused4:5;
+  unsigned int __data_offset;
+  unsigned short int __data_selector;
+  unsigned short int __unused5;
+};
+
+#define FP_HANDLE_EXCEPTIONS						\
+  do {									\
+    if (_fex & FP_EX_INVALID)						\
+      {									\
+	float f = 0.0;							\
+	__asm__ __volatile__ ("divss %0, %0 " : : "x" (f));		\
+      }									\
+    if (_fex & FP_EX_DIVZERO)						\
+      {									\
+	float f = 1.0, g = 0.0;						\
+	__asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));	\
+      }									\
+    if (_fex & FP_EX_OVERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_OVERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_UNDERFLOW)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_UNDERFLOW;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+    if (_fex & FP_EX_INEXACT)						\
+      {									\
+	struct fenv temp;						\
+	__asm__ __volatile__ ("fnstenv %0" : "=m" (temp));		\
+	temp.__status_word |= FP_EX_INEXACT;				\
+	__asm__ __volatile__ ("fldenv %0" : : "m" (temp));		\
+	__asm__ __volatile__ ("fwait");					\
+      }									\
+  } while (0)
+
+#define FP_RND_NEAREST		0
+#define FP_RND_ZERO		0xc00
+#define FP_RND_PINF		0x800
+#define FP_RND_MINF		0x400
+
+#define _FP_DECL_EX \
+  unsigned short _fcw __attribute__ ((unused)) = FP_RND_NEAREST
+
+#define FP_INIT_ROUNDMODE			\
+  do {						\
+    __asm__ ("fnstcw %0" : "=m" (_fcw));	\
+  } while (0)
+
+#define FP_ROUNDMODE		(_fcw & 0xc00)
+
+#define	__LITTLE_ENDIAN	1234
+#define	__BIG_ENDIAN	4321
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+#if defined __MACH__
+/* Mach-O doesn't support aliasing.  If these functions ever return
+   anything but CMPtype we need to revisit this... */
+#define strong_alias(name, aliasname) \
+  CMPtype aliasname (TFtype a, TFtype b) { return name(a, b); }
+#else
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#endif
--- gcc/libgcc/config/i386/64/t-fprules-softfp.quad	2008-07-02 06:37:00.000000000 -0700
+++ gcc/libgcc/config/i386/64/t-fprules-softfp	2008-07-02 06:37:00.000000000 -0700
@@ -0,0 +1,12 @@
+# Filter out the following TImode functions and provide backward binary
+# compatibility.
+tf-compats = getf2.c letf2.c eqtf2.c
+tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats))
+LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats))
+
+# Replace _divtc3, _multc3 and _powitf2.
+libgcc2-tf-functions = _divtc3 _multc3 _powitf2
+LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions)
+libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions))
+LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats))
--- gcc/libgcc/configure.ac.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure.ac	2008-07-02 06:37:00.000000000 -0700
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is s
 fixed_point=$libgcc_cv_fixed_point
 AC_SUBST(fixed_point)
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/configure.quad	2008-06-21 07:10:37.000000000 -0700
+++ gcc/libgcc/configure	2008-07-02 06:37:38.000000000 -0700
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >
 fixed_point=$libgcc_cv_fixed_point
 
 
+# Check 32bit or 64bit for x86.
+case ${host} in
+i?86*-*-* | x86_64*-*-*)
+  cat > conftest.c <<EOF
+#ifdef __x86_64__
+host_address=64
+#else
+host_address=32
+#endif
+EOF
+    eval `${CC-cc} -E conftest.c | grep host_address=`
+    rm -f conftest.c
+    ;;
+esac
+
 # Collect host-machine-specific information.
 . ${srcdir}/config.host
 
--- gcc/libgcc/shared-object.mk.quad	2007-01-03 21:41:23.000000000 -0800
+++ gcc/libgcc/shared-object.mk	2008-07-02 06:37:00.000000000 -0700
@@ -12,7 +12,7 @@ $(base)$(objext): $o
 	$(gcc_compile) $(c_flags) -c $< $(vis_hide)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) $(c_flags) -c $<
+	$(gcc_s_compile) -DSHARED $(c_flags) -c $<
 
 else
 
@@ -29,6 +29,6 @@ $(base).vis: $(base)_s$(objext)
 	$(gen-hide-list)
 
 $(base)_s$(objext): $o
-	$(gcc_s_compile) -c -xassembler-with-cpp $<
+	$(gcc_s_compile) -DSHARED -c -xassembler-with-cpp $<
 
 endif


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