summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog53
-rw-r--r--gcc/config.gcc15
-rw-r--r--gcc/config/i386/i386.c25
-rw-r--r--gcc/config/i386/libgcc-glibc.ver (renamed from gcc/config/i386/libgcc-x86_64-glibc.ver)85
-rw-r--r--gcc/config/i386/linux.h6
-rw-r--r--gcc/config/i386/linux64.h2
-rw-r--r--gcc/config/i386/sfp-machine.h144
-rw-r--r--gcc/config/i386/t-darwin3
-rw-r--r--gcc/config/i386/t-darwin643
-rw-r--r--gcc/config/i386/t-fprules-softfp (renamed from gcc/config/i386/t-fprules-softfp64)0
-rw-r--r--gcc/config/i386/t-linux5
-rw-r--r--gcc/config/i386/t-linux649
-rw-r--r--gcc/config/libgcc-glibc.ver14
-rw-r--r--gcc/config/m32r/libgcc-glibc.ver10
-rw-r--r--gcc/config/s390/libgcc-glibc.ver24
-rw-r--r--gcc/config/sh/libgcc-glibc.ver11
-rw-r--r--gcc/config/sparc/libgcc-sparc-glibc.ver14
-rw-r--r--gcc/libgcc-std.ver4
-rw-r--r--gcc/mkmap-symver.awk16
-rw-r--r--libgcc/ChangeLog35
-rw-r--r--libgcc/Makefile.in2
-rw-r--r--libgcc/config.host7
-rw-r--r--libgcc/config/i386/32/sfp-machine.h217
-rw-r--r--libgcc/config/i386/32/t-fprules-softfp8
-rw-r--r--libgcc/config/i386/32/tf-signs.c64
-rw-r--r--libgcc/config/i386/64/_divtc3-compat.c14
-rw-r--r--libgcc/config/i386/64/_multc3-compat.c14
-rw-r--r--libgcc/config/i386/64/_powitf2-compat.c14
-rw-r--r--libgcc/config/i386/64/eqtf2.c13
-rw-r--r--libgcc/config/i386/64/getf2.c13
-rw-r--r--libgcc/config/i386/64/letf2.c13
-rw-r--r--libgcc/config/i386/64/sfp-machine.h143
-rw-r--r--libgcc/config/i386/64/t-fprules-softfp12
-rw-r--r--libgcc/configure15
-rw-r--r--libgcc/configure.ac15
-rw-r--r--libgcc/shared-object.mk4
36 files changed, 869 insertions, 177 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fad92a66f41..c1bbc252c54 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,56 @@
+2008-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/36669
+ * config/libgcc-glibc.ver: Add %exclude.
+ * config/m32r/libgcc-glibc.ver: Likwise.
+ * config/s390/libgcc-glibc.ver: Likwise.
+ * config/sh/libgcc-glibc.ver: Likwise.
+ * config/sparc/libgcc-sparc-glibc.ver: Likwise.
+
+ * config/i386/libgcc-glibc.ver: New.
+
+ * config/i386/libgcc-x86_64-glibc.ver: Removed.
+
+2008-07-02 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/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.
+
2008-07-02 Jason Merrill <jason@redhat.com>
* tree.c (ctor_to_list): New fn.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index f4f171e0c02..b29a762895c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -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-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu)
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-*-knetbsd*-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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5a2c0c870a7..58c3dba1e8c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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 target, rtx subtarget ATTRIBUTE_UNUSED,
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)
diff --git a/gcc/config/i386/libgcc-x86_64-glibc.ver b/gcc/config/i386/libgcc-glibc.ver
index fa5d1a6dba2..be791745b43 100644
--- a/gcc/config/i386/libgcc-x86_64-glibc.ver
+++ b/gcc/config/i386/libgcc-glibc.ver
@@ -5,6 +5,20 @@
# 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.
@@ -24,16 +38,18 @@ GLIBC_2.0 {
}
%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.
+# 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.
-%ifdef __x86_64__
%exclude {
__addtf3
+ __divtc3
__divtf3
__eqtf2
__extenddftf2
__extendsftf2
+ __extendxftf2
__fixtfdi
__fixtfsi
__fixtfti
@@ -47,21 +63,45 @@ GLIBC_2.0 {
__floatunsitf
__floatuntitf
__getf2
+ __gttf2
__letf2
+ __lttf2
+ __multc3
__multf3
__negtf2
+ __netf2
+ __powitf2
__subtf3
__trunctfdf2
__trunctfsf2
+ __trunctfxf2
__unordtf2
}
+%ifdef __x86_64__
+# Those symbols had improper versions when they were added to gcc 4.3.0.
+# We corrected the default version to GCC_4.3.0. But we keep the old
+# version for backward binary compatibility.
+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
@@ -75,12 +115,51 @@ GCC_4.3.0 {
__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
diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
index ec5dc4e2230..78326b05ec0 100644
--- a/gcc/config/i386/linux.h
+++ b/gcc/config/i386/linux.h
@@ -189,6 +189,12 @@ along with GCC; see the file COPYING3. If not see
: "=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
diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h
index 37ede613e7d..04d12cadada 100644
--- a/gcc/config/i386/linux64.h
+++ b/gcc/config/i386/linux64.h
@@ -91,7 +91,7 @@ along with GCC; see the file COPYING3. If not see
/* 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
diff --git a/gcc/config/i386/sfp-machine.h b/gcc/config/i386/sfp-machine.h
index 190e3cb0e81..f2df869653f 100644
--- a/gcc/config/i386/sfp-machine.h
+++ b/gcc/config/i386/sfp-machine.h
@@ -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
diff --git a/gcc/config/i386/t-darwin b/gcc/config/i386/t-darwin
index 6feb48a20a4..fb5bbe78c04 100644
--- a/gcc/config/i386/t-darwin
+++ b/gcc/config/i386/t-darwin
@@ -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'
diff --git a/gcc/config/i386/t-darwin64 b/gcc/config/i386/t-darwin64
index 2e55cb786d7..5143e3819dc 100644
--- a/gcc/config/i386/t-darwin64
+++ b/gcc/config/i386/t-darwin64
@@ -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'
diff --git a/gcc/config/i386/t-fprules-softfp64 b/gcc/config/i386/t-fprules-softfp
index 0b0068f9053..0b0068f9053 100644
--- a/gcc/config/i386/t-fprules-softfp64
+++ b/gcc/config/i386/t-fprules-softfp
diff --git a/gcc/config/i386/t-linux b/gcc/config/i386/t-linux
new file mode 100644
index 00000000000..4c6bb51e3b8
--- /dev/null
+++ b/gcc/config/i386/t-linux
@@ -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
diff --git a/gcc/config/i386/t-linux64 b/gcc/config/i386/t-linux64
index 0490d7812e1..36378d87e0b 100644
--- a/gcc/config/i386/t-linux64
+++ b/gcc/config/i386/t-linux64
@@ -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'
diff --git a/gcc/config/libgcc-glibc.ver b/gcc/config/libgcc-glibc.ver
index 837c1a7ee56..264828b17c0 100644
--- a/gcc/config/libgcc-glibc.ver
+++ b/gcc/config/libgcc-glibc.ver
@@ -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.
diff --git a/gcc/config/m32r/libgcc-glibc.ver b/gcc/config/m32r/libgcc-glibc.ver
index 450c4b60e92..977c3346604 100644
--- a/gcc/config/m32r/libgcc-glibc.ver
+++ b/gcc/config/m32r/libgcc-glibc.ver
@@ -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
diff --git a/gcc/config/s390/libgcc-glibc.ver b/gcc/config/s390/libgcc-glibc.ver
index e9413d0fff1..ab6eedcf683 100644
--- a/gcc/config/s390/libgcc-glibc.ver
+++ b/gcc/config/s390/libgcc-glibc.ver
@@ -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
diff --git a/gcc/config/sh/libgcc-glibc.ver b/gcc/config/sh/libgcc-glibc.ver
index 734d3d6bfe1..11ef379effa 100644
--- a/gcc/config/sh/libgcc-glibc.ver
+++ b/gcc/config/sh/libgcc-glibc.ver
@@ -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
}
-
diff --git a/gcc/config/sparc/libgcc-sparc-glibc.ver b/gcc/config/sparc/libgcc-sparc-glibc.ver
index ed280fe05a7..8f50c0d5886 100644
--- a/gcc/config/sparc/libgcc-sparc-glibc.ver
+++ b/gcc/config/sparc/libgcc-sparc-glibc.ver
@@ -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
diff --git a/gcc/libgcc-std.ver b/gcc/libgcc-std.ver
index 89be00cf3be..1df9ab1b3f9 100644
--- a/gcc/libgcc-std.ver
+++ b/gcc/libgcc-std.ver
@@ -1800,3 +1800,7 @@ GCC_4.3.0 {
__satfractunstiuda
__satfractunstiuta
}
+
+%inherit GCC_4.4.0 GCC_4.3.0
+GCC_4.4.0 {
+}
diff --git a/gcc/mkmap-symver.awk b/gcc/mkmap-symver.awk
index 855043f7e6c..4877e905147 100644
--- a/gcc/mkmap-symver.awk
+++ b/gcc/mkmap-symver.awk
@@ -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)
{
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 0bcffffc56a..fa055e9c510 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,38 @@
+2008-07-02 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-02 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-02 H.J. Lu <hongjiu.lu@intel.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/32/sfp-machine.h: New.
+
2008-06-26 Nathan Froyd <froydnj@codesourcery.com>
* config/rs6000/t-ppccomm: Remove rules that conflict with
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 94b6440f011..369c7fecb58 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -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
diff --git a/libgcc/config.host b/libgcc/config.host
index da652de0ed8..ca07a07fadc 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -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
diff --git a/libgcc/config/i386/32/sfp-machine.h b/libgcc/config/i386/32/sfp-machine.h
new file mode 100644
index 00000000000..256bdeb4a48
--- /dev/null
+++ b/libgcc/config/i386/32/sfp-machine.h
@@ -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
diff --git a/libgcc/config/i386/32/t-fprules-softfp b/libgcc/config/i386/32/t-fprules-softfp
new file mode 100644
index 00000000000..8e7f3233b71
--- /dev/null
+++ b/libgcc/config/i386/32/t-fprules-softfp
@@ -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
diff --git a/libgcc/config/i386/32/tf-signs.c b/libgcc/config/i386/32/tf-signs.c
new file mode 100644
index 00000000000..1b19b601269
--- /dev/null
+++ b/libgcc/config/i386/32/tf-signs.c
@@ -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;
+}
diff --git a/libgcc/config/i386/64/_divtc3-compat.c b/libgcc/config/i386/64/_divtc3-compat.c
new file mode 100644
index 00000000000..57ee350b7cd
--- /dev/null
+++ b/libgcc/config/i386/64/_divtc3-compat.c
@@ -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
diff --git a/libgcc/config/i386/64/_multc3-compat.c b/libgcc/config/i386/64/_multc3-compat.c
new file mode 100644
index 00000000000..49141a9384f
--- /dev/null
+++ b/libgcc/config/i386/64/_multc3-compat.c
@@ -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
diff --git a/libgcc/config/i386/64/_powitf2-compat.c b/libgcc/config/i386/64/_powitf2-compat.c
new file mode 100644
index 00000000000..3bc3c904de7
--- /dev/null
+++ b/libgcc/config/i386/64/_powitf2-compat.c
@@ -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
diff --git a/libgcc/config/i386/64/eqtf2.c b/libgcc/config/i386/64/eqtf2.c
new file mode 100644
index 00000000000..d9baba689be
--- /dev/null
+++ b/libgcc/config/i386/64/eqtf2.c
@@ -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
diff --git a/libgcc/config/i386/64/getf2.c b/libgcc/config/i386/64/getf2.c
new file mode 100644
index 00000000000..30885cc0caf
--- /dev/null
+++ b/libgcc/config/i386/64/getf2.c
@@ -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
diff --git a/libgcc/config/i386/64/letf2.c b/libgcc/config/i386/64/letf2.c
new file mode 100644
index 00000000000..231f981c84c
--- /dev/null
+++ b/libgcc/config/i386/64/letf2.c
@@ -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
diff --git a/libgcc/config/i386/64/sfp-machine.h b/libgcc/config/i386/64/sfp-machine.h
new file mode 100644
index 00000000000..190e3cb0e81
--- /dev/null
+++ b/libgcc/config/i386/64/sfp-machine.h
@@ -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
diff --git a/libgcc/config/i386/64/t-fprules-softfp b/libgcc/config/i386/64/t-fprules-softfp
new file mode 100644
index 00000000000..e8cda296cbd
--- /dev/null
+++ b/libgcc/config/i386/64/t-fprules-softfp
@@ -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))
diff --git a/libgcc/configure b/libgcc/configure
index 80cbebbb426..75bf9034b1a 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -3402,6 +3402,21 @@ echo "${ECHO_T}$libgcc_cv_fixed_point" >&6
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
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index e3eb80a2148..1238d742450 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -153,6 +153,21 @@ AC_CACHE_CHECK([whether fixed-point is supported], [libgcc_cv_fixed_point],
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
diff --git a/libgcc/shared-object.mk b/libgcc/shared-object.mk
index 65171b6aa32..5c0abb32624 100644
--- a/libgcc/shared-object.mk
+++ b/libgcc/shared-object.mk
@@ -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