From: H.J. Lu Date: Wed, 2 Jul 2008 15:59:19 +0000 (+0000) Subject: re PR target/36669 (Wrong versioning for __float128) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ff473280054c876499089772cea1a5fc56970d64;p=gcc.git re PR target/36669 (Wrong versioning for __float128) gcc/ 2008-07-02 H.J. Lu 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 * 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. libgcc/ 2008-07-02 H.J. Lu 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 * 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 Uros Bizjak * config/i386/32/sfp-machine.h: New. Co-Authored-By: Uros Bizjak From-SVN: r137369 --- 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 + + 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 + + * 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 * 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-glibc.ver b/gcc/config/i386/libgcc-glibc.ver new file mode 100644 index 00000000000..be791745b43 --- /dev/null +++ b/gcc/config/i386/libgcc-glibc.ver @@ -0,0 +1,165 @@ +# 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__ +# 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 + __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 diff --git a/gcc/config/i386/libgcc-x86_64-glibc.ver b/gcc/config/i386/libgcc-x86_64-glibc.ver deleted file mode 100644 index fa5d1a6dba2..00000000000 --- a/gcc/config/i386/libgcc-x86_64-glibc.ver +++ /dev/null @@ -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 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-softfp b/gcc/config/i386/t-fprules-softfp new file mode 100644 index 00000000000..0b0068f9053 --- /dev/null +++ b/gcc/config/i386/t-fprules-softfp @@ -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 diff --git a/gcc/config/i386/t-fprules-softfp64 b/gcc/config/i386/t-fprules-softfp64 deleted file mode 100644 index 0b0068f9053..00000000000 --- a/gcc/config/i386/t-fprules-softfp64 +++ /dev/null @@ -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 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 + + 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 + + * 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 + Uros Bizjak + + * config/i386/32/sfp-machine.h: New. + 2008-06-26 Nathan Froyd * 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 < conftest.c <