diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2008-07-02 15:59:19 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2008-07-02 08:59:19 -0700 |
commit | ff473280054c876499089772cea1a5fc56970d64 (patch) | |
tree | 819f63abca489ef0ba829bffcc7e52b44128bb73 /libgcc | |
parent | b12285bdfc30eeefc48555bc6aa4e571248ee14d (diff) | |
download | gcc-ff473280054c876499089772cea1a5fc56970d64.zip gcc-ff473280054c876499089772cea1a5fc56970d64.tar.gz gcc-ff473280054c876499089772cea1a5fc56970d64.tar.bz2 |
re PR target/36669 (Wrong versioning for __float128)
gcc/
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.
libgcc/
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.
Co-Authored-By: Uros Bizjak <ubizjak@gmail.com>
From-SVN: r137369
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 35 | ||||
-rw-r--r-- | libgcc/Makefile.in | 2 | ||||
-rw-r--r-- | libgcc/config.host | 7 | ||||
-rw-r--r-- | libgcc/config/i386/32/sfp-machine.h | 217 | ||||
-rw-r--r-- | libgcc/config/i386/32/t-fprules-softfp | 8 | ||||
-rw-r--r-- | libgcc/config/i386/32/tf-signs.c | 64 | ||||
-rw-r--r-- | libgcc/config/i386/64/_divtc3-compat.c | 14 | ||||
-rw-r--r-- | libgcc/config/i386/64/_multc3-compat.c | 14 | ||||
-rw-r--r-- | libgcc/config/i386/64/_powitf2-compat.c | 14 | ||||
-rw-r--r-- | libgcc/config/i386/64/eqtf2.c | 13 | ||||
-rw-r--r-- | libgcc/config/i386/64/getf2.c | 13 | ||||
-rw-r--r-- | libgcc/config/i386/64/letf2.c | 13 | ||||
-rw-r--r-- | libgcc/config/i386/64/sfp-machine.h | 143 | ||||
-rw-r--r-- | libgcc/config/i386/64/t-fprules-softfp | 12 | ||||
-rw-r--r-- | libgcc/configure | 15 | ||||
-rw-r--r-- | libgcc/configure.ac | 15 | ||||
-rw-r--r-- | libgcc/shared-object.mk | 4 |
17 files changed, 600 insertions, 3 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 0bcffff..fa055e9c 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 94b6440..369c7fe 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 da652de..ca07a07 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 0000000..256bdeb --- /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 0000000..8e7f323 --- /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 0000000..1b19b60 --- /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 0000000..57ee350 --- /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 0000000..49141a9 --- /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 0000000..3bc3c90 --- /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 0000000..d9baba6 --- /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 0000000..30885cc --- /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 0000000..231f981 --- /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 0000000..190e3cb --- /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 0000000..e8cda29 --- /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 80cbebb..75bf903 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 e3eb80a..1238d74 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 65171b6..5c0abb3 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 |