summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorro <ro@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-05 14:53:09 +0000
committerro <ro@138bc75d-0d04-0410-961f-82ee72b054a4>2011-08-05 14:53:09 +0000
commita23b9c51a0b27c4507a2fb82275b725b6d6fc8eb (patch)
tree24104c84aafe6bb8ace23e951f7e0950cbc3d4fa /libgcc
parente59be7e3775cce7a65bfac5c9aeb5f76d42f539b (diff)
downloadgcc-a23b9c51a0b27c4507a2fb82275b725b6d6fc8eb.tar.gz
gcc:
* Makefile.in (FPBIT_FUNCS, DPBIT_FUNCS, TPBIT_FUNCS): Remove. (libgcc-support): Remove $(FPBIT), $(DPBIT), $(TPBIT) dependencies. (libgcc.mvars): Remove FPBIT, FPBIT_FUNCS, DPBIT, DPBIT_FUNCS, TPBIT, TPBIT_FUNCS. * config/fp-bit.c, config/fp-bit.h: Move to ../libgcc. * config/arm/t-strongarm-elf (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/arm/t-vxworks: Likewise. * config/arm/t-wince-pe: Likewise. * config/avr/t-avr (fp-bit.c, FPBIT): Remove. * config/bfin/t-bfin (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/bfin/t-bfin-elf: Likewise. * config/bfin/t-bfin-linux: Likewise. * config/bfin/t-bfin-uclinux: Likewise. * config/cris/t-cris (FPBIT, DPBIT, dp-bit.c, tmplibgcc_fp_bit.c): Remove. * config/fr30/t-fr30: Likewise. * config/frv/t-frv: Likewise. * config/h8300/t-h8300 (FPBIT, fp-bit.c): Remove. * config/iq2000/t-iq2000 (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/m32c/t-m32c: Likewise. * config/m32r/t-linux: (LIB2FUNCS_EXTRA, fp-bit.c, dp-bit.c): Remove. * config/m32r/t-m32r (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/mcore/t-mcore: Likewise. * config/mep/t-mep: Likewise. * config/microblaze/t-microblaze: Likewise. * config/mips/t-linux64 (TPBIT, tp-bit.c): Remove. * config/mips/t-mips (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/mips/t-sdemtk (FPBIT, DPBIT): Remove. * config/mips/t-sr71k (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/mn10300/t-linux: Remove. * config/mn10300/t-mn10300 (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/pdp11/t-pdp11: Likewise. * config/picochip/t-picochip (FPBIT, fp-bit.c): Remove. * config/rs6000/ppc64-fp.c: Move to ../libgcc/config/rs6000. * config/rs6000/t-aix43 (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. (LIB2FUNCS_EXTRA): Remove $(srcdir)/config/rs6000/ppc64-fp.c. * config/rs6000/t-aix52: Likewise. * config/rs6000/t-darwin (LIB2FUNCS_EXTRA): Remove $(srcdir)/config/rs6000/ppc64-fp.c. * config/rs6000/t-fprules-fpbit: Remove. * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Remove. * config/rs6000/t-lynx (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/sh/t-netbsd (FPBIT, DPBIT): Remove. * config/sh/t-sh (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/sparc/t-elf: Likewise. * config/sparc/t-leon: Likewise. * config/sparc/t-leon3: Likewise. * config/spu/t-spu-elf: Likewise. (DPBIT_FUNCS): Remove. * config/stormy16/t-stormy16 (FPBIT, DPBIT, dp-bit.c, fp-bit.c): Remove. * config/v850/t-v850: Likewise. * config.gcc (avr-*-rtems*): Add avr/avr-lib.h to libgcc_tm_file. (avr-*-*): Likewise. (h8300-*-rtems*): Set libgcc_tm_file. (h8300-*-elf*): Likewise. (powerpc-*-eabisimaltivec*): Remove rs6000/t-fprules-fpbit from tmake_file. (powerpc-*-eabisim*): Likewise. (powerpc-*-elf*): Likewise. (powerpc-*-eabialtivec*): Likewise. (powerpc-xilinx-eabi*): Likewise. (powerpc-*-eabi*): Likewise. (powerpc-*-rtems*): Likewise. (powerpc-wrs-vxworks, powerpc-wrs-vxworksae): Likewise. (powerpcle-*-elf*): Likewise. (powerpcle-*-eabisim*): Likewise. (powerpcle-*-eabi*): Likewise. (rx-*-elf*): Add rx/rx-lib.h to libgcc_tm_file. (am33_2.0-*-linux*): Remove mn10300/t-linux from tmake_file. * doc/fragments.texi (Target Fragment, Floating Point Emulation): Remove. gcc/po: * EXCLUDES (config/fp-bit.c, config/fp-bit.h): Remove. libgcc: * Makefile.in (double_type_size, long_double_type_size): Set. Remove $(fpbit-in-libgcc) support. (FPBIT_FUNCS, DPBIT_FUNCS, TPBIT_FUNCS): New variables. (fpbit-src): New variable. ($(fpbit-o), $(fpbit-s-o)): Use $(fpbit-src) instead of $(FPBIT). Compile with -DFLOAT $(FPBIT_CFLAGS). Use $<. ($(dpbit-o), $(dpbit-s-o)): Use $(fpbit-src) instead of $(DPBIT). Compile with $(FPBIT_CFLAGS). Use $<. ($(tpbit-o), $(tpbit-s-o): Use $(fpbit-src) instead of $(TPBIT). Compile with -DFLOAT $(TPBIT_CFLAGS). Use $<. * configure.ac (double_type_size, long_double_type_size): Determine and substitute. * configure: Regenerate. * fp-bit.c, fp-bit.h: New files. * config/avr/avr-lib.h, config/h8300/h8300-lib.h: New files. * config/mips/t-irix6 (TPBIT, $(gcc_objdir)/tp-bit.c): Remove. * config/mips/t-mips: New file. * config/mips/t-sdemtk: New file. * config/rs6000/ppc64-fp.c: New file. * config/rs6000/t-darwin (LIB2ADD): Add $(srcdir)/config/rs6000/ppc64-fp.c. * config/rs6000/t-ppc64-fp: New file. * config/rx/rx-lib.h: New file. * config/rx/t-rx (FPBIT): Set to true. ($(gcc_objdir)/fp-bit.c): Remove. (DPBIT): Set to true only with -m64bit-doubles. ($(gcc_objdir)/dp-bit.c): Remove. * config/sparc/t-softfp: Remove. * config/spu/t-elf: New file. * config/t-fdpbit, config/t-fpbit: New files. * config.host (m32c*-*-*): Add t-fdpbit to tmake_file. (mips*-*-*): Likewise. (arm-wrs-vxworks): Likewise. (arm*-*-freebsd*): Likewise. (avr-*-rtems*): Add t-fpbit to tmake_file. (avr-*-*): Likewise. (bfin*-elf*): Add t-fdpbit to tmake_file. (bfin*-uclinux*): Likewise. (bfin*-linux-uclibc*): Likewise. (bfin*-rtems*): New case. Add t-fdpbit to tmake_file. (bfin*-*): Add t-fdpbit to tmake_file. (crisv32-*-elf): Likewise. (cris-*-linux*): Likewise. (fr30-*-elf): Likewise. (frv-*-elf, frv-*-*linux*): Likewise. (h8300-*-rtems*, h8300-*-elf*): Add t-fpbit to tmake_file. (iq2000*-*-elf*): Add t-fdpbit to tmake_file. (m32r-*-elf*): Likewise. (m32rle-*-elf*): Likewise. (m32r-*-linux*): Likewise. (m32rle-*-linux*): Likewise. (mcore-*-elf): Add t-fdpbit to tmake_file. (microblaze*-*-*): Likewise. (mips-sgi-irix6.5*): Add t-tpbit to tmake_file. (mips*-*-netbsd*): Add mips/t-mips to tmake_file. (mips64*-*-linux*): Also handle mipsisa64*-*-linux*. Fix typo. Add mips/t-tpbit to tmake-file. (mips*-*-linux*): Fix typo. (mips*-sde-elf*): New case Add mips/t-sdemtk unless using newlib. (mipsisa64sr71k-*-elf*): Add t-fdpbit to tmake_file. (mipsisa64sb1-*-elf*): Add mips/t-mips to tmake_file. (mn10300-*-*): Likewise. (pdp11-*-*): Likewise. (picochip-*-*): Add t-fpbit to tmake_file. (powerpc-*-eabisimaltivec*): Likewise. (powerpc-*-eabisim*): Likewise. (powerpc-*-elf*): Likewise. (powerpc-*-eabialtivec*): Likewise. (powerpc-xilinx-eabi*): New case. Add t-fdpbit to tmake_file. (powerpc-*-eabi*): Add t-fdpbit to tmake_file. (powerpc-*-rtems*): Likewise. (powerpc-*-linux*, powerpc64-*-linux*): Add rs6000/t-ppc64-fp to tmake_file. (powerpc-wrs-vxworks, powerpc-wrs-vxworksae): Add t-fdpbit to tmake_file. (powerpc-*-lynxos*): Likewise. (powerpcle-*-elf*): Likewise. (powerpcle-*-eabisim*): Likewise. (powerpcle-*-eabi*): Likewise. (rs6000-ibm-aix4.[3456789]*, powerpc-ibm-aix4.[3456789]*): Add t-fdpbit, rs6000/t-ppc64-fp to tmake_file. (rs6000-ibm-aix5.1.*, powerpc-ibm-aix5.1.*): Likewise. (rs6000-ibm-aix[56789].*, powerpc-ibm-aix[56789].*): Likewise. (rx-*-elf): Add t-fdpbit to tmake_file. (sh-*-elf*, sh[12346l]*-*-elf*, sh-*-linux*) (sh[2346lbe]*-*-linux*, sh-*-netbsdelf*, shl*-*-netbsdelf*) (sh5-*-netbsd*, sh5l*-*-netbsd*, sh64-*-netbsd*) (sh64l*-*-netbsd*): Add t-fdpbit to tmake_file except on sh*-*-netbsd*. (sh-*-rtems*): Add t-fdpbit to tmake_file. (sh-wrs-vxworks): Likewise. (sparc-*-elf*): Replace sparc/t-softfp by t-fdpbit in tmake_file. (sparc-*-linux*): Add t-fdpbit to tmake_file for *-leon*. (sparc-*-rtems*, sparc64-*-rtems*): Split off ... (sparc64-*-rtems*): ... new case. (sparc-*-rtems*): Add t-fdpbit to tmake_file. (spu-*-elf*): Likewise. Add spu/t-elf to tmake_file. (v850*-*-*): Add t-fdpbit to tmake_file. (xstormy16-*-elf): Likewise. (am33_2.0-*-linux*): Add t-fdpbit to tmake_file. (mep*-*-*): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177448 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog112
-rw-r--r--libgcc/Makefile.in54
-rw-r--r--libgcc/config.host111
-rw-r--r--libgcc/config/avr/avr-lib.h6
-rw-r--r--libgcc/config/h8300/h8300-lib.h7
-rw-r--r--libgcc/config/mips/t-irix612
-rw-r--r--libgcc/config/mips/t-mips4
-rw-r--r--libgcc/config/mips/t-sdemtk3
-rw-r--r--libgcc/config/mips/t-tpbit4
-rw-r--r--libgcc/config/rs6000/ppc64-fp.c239
-rw-r--r--libgcc/config/rs6000/t-darwin2
-rw-r--r--libgcc/config/rs6000/t-ppc64-fp2
-rw-r--r--libgcc/config/rx/rx-lib.h6
-rw-r--r--libgcc/config/rx/t-rx20
-rw-r--r--libgcc/config/sparc/t-softfp29
-rw-r--r--libgcc/config/spu/t-elf3
-rw-r--r--libgcc/config/t-fdpbit2
-rw-r--r--libgcc/config/t-fpbit2
-rw-r--r--libgcc/configure626
-rw-r--r--libgcc/configure.ac7
-rw-r--r--libgcc/fp-bit.c1657
-rw-r--r--libgcc/fp-bit.h507
22 files changed, 3319 insertions, 96 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 65d47a80278..00c4fa63b7b 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,5 +1,117 @@
2011-08-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+ * Makefile.in (double_type_size, long_double_type_size): Set.
+ Remove $(fpbit-in-libgcc) support.
+ (FPBIT_FUNCS, DPBIT_FUNCS, TPBIT_FUNCS): New variables.
+ (fpbit-src): New variable.
+ ($(fpbit-o), $(fpbit-s-o)): Use $(fpbit-src) instead of $(FPBIT).
+ Compile with -DFLOAT $(FPBIT_CFLAGS).
+ Use $<.
+ ($(dpbit-o), $(dpbit-s-o)): Use $(fpbit-src) instead of $(DPBIT).
+ Compile with $(FPBIT_CFLAGS).
+ Use $<.
+ ($(tpbit-o), $(tpbit-s-o): Use $(fpbit-src) instead of $(TPBIT).
+ Compile with -DFLOAT $(TPBIT_CFLAGS).
+ Use $<.
+ * configure.ac (double_type_size, long_double_type_size):
+ Determine and substitute.
+ * configure: Regenerate.
+ * fp-bit.c, fp-bit.h: New files.
+ * config/avr/avr-lib.h, config/h8300/h8300-lib.h: New files.
+ * config/mips/t-irix6 (TPBIT, $(gcc_objdir)/tp-bit.c): Remove.
+ * config/mips/t-mips: New file.
+ * config/mips/t-sdemtk: New file.
+ * config/rs6000/ppc64-fp.c: New file.
+ * config/rs6000/t-darwin (LIB2ADD): Add
+ $(srcdir)/config/rs6000/ppc64-fp.c.
+ * config/rs6000/t-ppc64-fp: New file.
+ * config/rx/rx-lib.h: New file.
+ * config/rx/t-rx (FPBIT): Set to true.
+ ($(gcc_objdir)/fp-bit.c): Remove.
+ (DPBIT): Set to true only with -m64bit-doubles.
+ ($(gcc_objdir)/dp-bit.c): Remove.
+ * config/sparc/t-softfp: Remove.
+ * config/spu/t-elf: New file.
+ * config/t-fdpbit, config/t-fpbit: New files.
+ * config.host (m32c*-*-*): Add t-fdpbit to tmake_file.
+ (mips*-*-*): Likewise.
+ (arm-wrs-vxworks): Likewise.
+ (arm*-*-freebsd*): Likewise.
+ (avr-*-rtems*): Add t-fpbit to tmake_file.
+ (avr-*-*): Likewise.
+ (bfin*-elf*): Add t-fdpbit to tmake_file.
+ (bfin*-uclinux*): Likewise.
+ (bfin*-linux-uclibc*): Likewise.
+ (bfin*-rtems*): New case.
+ Add t-fdpbit to tmake_file.
+ (bfin*-*): Add t-fdpbit to tmake_file.
+ (crisv32-*-elf): Likewise.
+ (cris-*-linux*): Likewise.
+ (fr30-*-elf): Likewise.
+ (frv-*-elf, frv-*-*linux*): Likewise.
+ (h8300-*-rtems*, h8300-*-elf*): Add t-fpbit to tmake_file.
+ (iq2000*-*-elf*): Add t-fdpbit to tmake_file.
+ (m32r-*-elf*): Likewise.
+ (m32rle-*-elf*): Likewise.
+ (m32r-*-linux*): Likewise.
+ (m32rle-*-linux*): Likewise.
+ (mcore-*-elf): Add t-fdpbit to tmake_file.
+ (microblaze*-*-*): Likewise.
+ (mips-sgi-irix6.5*): Add t-tpbit to tmake_file.
+ (mips*-*-netbsd*): Add mips/t-mips to tmake_file.
+ (mips64*-*-linux*): Also handle mipsisa64*-*-linux*.
+ Fix typo.
+ Add mips/t-tpbit to tmake-file.
+ (mips*-*-linux*): Fix typo.
+ (mips*-sde-elf*): New case
+ Add mips/t-sdemtk unless using newlib.
+ (mipsisa64sr71k-*-elf*): Add t-fdpbit to tmake_file.
+ (mipsisa64sb1-*-elf*): Add mips/t-mips to tmake_file.
+ (mn10300-*-*): Likewise.
+ (pdp11-*-*): Likewise.
+ (picochip-*-*): Add t-fpbit to tmake_file.
+ (powerpc-*-eabisimaltivec*): Likewise.
+ (powerpc-*-eabisim*): Likewise.
+ (powerpc-*-elf*): Likewise.
+ (powerpc-*-eabialtivec*): Likewise.
+ (powerpc-xilinx-eabi*): New case.
+ Add t-fdpbit to tmake_file.
+ (powerpc-*-eabi*): Add t-fdpbit to tmake_file.
+ (powerpc-*-rtems*): Likewise.
+ (powerpc-*-linux*, powerpc64-*-linux*): Add rs6000/t-ppc64-fp to
+ tmake_file.
+ (powerpc-wrs-vxworks, powerpc-wrs-vxworksae): Add t-fdpbit to
+ tmake_file.
+ (powerpc-*-lynxos*): Likewise.
+ (powerpcle-*-elf*): Likewise.
+ (powerpcle-*-eabisim*): Likewise.
+ (powerpcle-*-eabi*): Likewise.
+ (rs6000-ibm-aix4.[3456789]*, powerpc-ibm-aix4.[3456789]*): Add
+ t-fdpbit, rs6000/t-ppc64-fp to tmake_file.
+ (rs6000-ibm-aix5.1.*, powerpc-ibm-aix5.1.*): Likewise.
+ (rs6000-ibm-aix[56789].*, powerpc-ibm-aix[56789].*): Likewise.
+ (rx-*-elf): Add t-fdpbit to tmake_file.
+ (sh-*-elf*, sh[12346l]*-*-elf*, sh-*-linux*)
+ (sh[2346lbe]*-*-linux*, sh-*-netbsdelf*, shl*-*-netbsdelf*)
+ (sh5-*-netbsd*, sh5l*-*-netbsd*, sh64-*-netbsd*)
+ (sh64l*-*-netbsd*): Add t-fdpbit to tmake_file except on
+ sh*-*-netbsd*.
+ (sh-*-rtems*): Add t-fdpbit to tmake_file.
+ (sh-wrs-vxworks): Likewise.
+ (sparc-*-elf*): Replace sparc/t-softfp by t-fdpbit in tmake_file.
+ (sparc-*-linux*): Add t-fdpbit to tmake_file for *-leon*.
+ (sparc-*-rtems*, sparc64-*-rtems*): Split off ...
+ (sparc64-*-rtems*): ... new case.
+ (sparc-*-rtems*): Add t-fdpbit to tmake_file.
+ (spu-*-elf*): Likewise.
+ Add spu/t-elf to tmake_file.
+ (v850*-*-*): Add t-fdpbit to tmake_file.
+ (xstormy16-*-elf): Likewise.
+ (am33_2.0-*-linux*): Add t-fdpbit to tmake_file.
+ (mep*-*-*): Likewise.
+
+2011-08-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
* Makefile.in (LIB2ADDEH, LIB2ADDEHSTATIC, LIB2ADDEHSHARED): New
variables.
(LIBUNWIND, SHLIBUNWIND_LINK, SHLIBUNWIND_INSTALL): New variables.
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index c252d9a2217..4a75a37048e 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -37,6 +37,8 @@ SHELL = @SHELL@
cpu_type = @cpu_type@
enable_shared = @enable_shared@
+double_type_size = @double_type_size@
+long_double_type_size = @long_double_type_size@
decimal_float = @decimal_float@
enable_decimal_float = @enable_decimal_float@
fixed_point = @fixed_point@
@@ -256,6 +258,21 @@ LIBGCC_VER_GNU_PREFIX = __
LIBGCC_VER_FIXEDPOINT_GNU_PREFIX = __
LIBGCC_VER_SYMBOLS_PREFIX =
+FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
+ _fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
+ _lt_sf _le_sf _unord_sf _si_to_sf _sf_to_si _negate_sf _make_sf \
+ _sf_to_df _sf_to_tf _thenan_sf _sf_to_usi _usi_to_sf
+
+DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
+ _fpcmp_parts_df _compare_df _eq_df _ne_df _gt_df _ge_df \
+ _lt_df _le_df _unord_df _si_to_df _df_to_si _negate_df _make_df \
+ _df_to_sf _df_to_tf _thenan_df _df_to_usi _usi_to_df
+
+TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \
+ _fpcmp_parts_tf _compare_tf _eq_tf _ne_tf _gt_tf _ge_tf \
+ _lt_tf _le_tf _unord_tf _si_to_tf _tf_to_si _negate_tf _make_tf \
+ _tf_to_df _tf_to_sf _thenan_tf _tf_to_usi _usi_to_tf
+
# Additional sources to handle exceptions; overridden by targets as needed.
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
@@ -445,34 +462,25 @@ $(lib2-divmod-s-o): %_s$(objext): $(gcc_srcdir)/libgcc2.c
libgcc-s-objects += $(lib2-divmod-s-o)
endif
-# $(FPBIT) et al. are pathnames relative to the GCC build
-# directory; the supporting files are made by the GCC
-# Makefile.
-# FIXME: Soon we will be able to move this logic into this directory.
-
-ifneq ($(fpbit-in-libgcc),yes)
-FPBIT:=$(if $(FPBIT),$(gcc_objdir)/$(FPBIT),)
-DPBIT:=$(if $(DPBIT),$(gcc_objdir)/$(DPBIT),)
-TPBIT:=$(if $(TPBIT),$(gcc_objdir)/$(TPBIT),)
-endif
-
ifeq ($(TPBIT),)
# _sf_to_tf and _df_to_tf require tp-bit.c being compiled in.
FPBIT_FUNCS := $(filter-out _sf_to_tf,$(FPBIT_FUNCS))
DPBIT_FUNCS := $(filter-out _df_to_tf,$(DPBIT_FUNCS))
endif
+fpbit-src := $(srcdir)/fp-bit.c
+
# Build FPBIT.
ifneq ($(FPBIT),)
fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
-$(fpbit-o): %$(objext): $(FPBIT)
- $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
+$(fpbit-o): %$(objext): $(fpbit-src)
+ $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -DFLOAT $(FPBIT_CFLAGS) -c $< $(vis_hide)
libgcc-objects += $(fpbit-o)
ifeq ($(enable_shared),yes)
fpbit-s-o = $(patsubst %,%_s$(objext),$(FPBIT_FUNCS))
-$(fpbit-s-o): %_s$(objext): $(FPBIT)
- $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT)
+$(fpbit-s-o): %_s$(objext): $(fpbit-src)
+ $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* -DFLOAT $(FPBIT_CFLAGS) -c $<
libgcc-s-objects += $(fpbit-s-o)
endif
endif
@@ -480,14 +488,14 @@ endif
# Build DPBIT.
ifneq ($(DPBIT),)
dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
-$(dpbit-o): %$(objext): $(DPBIT)
- $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
+$(dpbit-o): %$(objext): $(fpbit-src)
+ $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* $(DPBIT_CFLAGS) -c $< $(vis_hide)
libgcc-objects += $(dpbit-o)
ifeq ($(enable_shared),yes)
dpbit-s-o = $(patsubst %,%_s$(objext),$(DPBIT_FUNCS))
-$(dpbit-s-o): %_s$(objext): $(DPBIT)
- $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT)
+$(dpbit-s-o): %_s$(objext): $(fpbit-src)
+ $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* $(DPBIT_CFLAGS) -c $<
libgcc-s-objects += $(dpbit-s-o)
endif
endif
@@ -495,14 +503,14 @@ endif
# Build TPBIT.
ifneq ($(TPBIT),)
tpbit-o = $(patsubst %,%$(objext),$(TPBIT_FUNCS))
-$(tpbit-o): %$(objext): $(TPBIT)
- $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(TPBIT) $(vis_hide)
+$(tpbit-o): %$(objext): $(fpbit-src)
+ $(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -DTFLOAT $(TPBIT_CFLAGS) -c $< $(vis_hide)
libgcc-objects += $(tpbit-o)
ifeq ($(enable_shared),yes)
tpbit-s-o = $(patsubst %,%_s$(objext),$(TPBIT_FUNCS))
-$(tpbit-s-o): %_s$(objext): $(TPBIT)
- $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(TPBIT)
+$(tpbit-s-o): %_s$(objext): $(fpbit-src)
+ $(gcc_s_compile) -DFINE_GRAINED_LIBRARIES -DL$* -DTFLOAT $(TPBIT_CFLAGS) -c $<
libgcc-s-objects += $(tpbit-s-o)
endif
endif
diff --git a/libgcc/config.host b/libgcc/config.host
index db00c4c2d8c..cd4f054336b 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -72,6 +72,7 @@ cpu_type=`echo ${host} | sed 's/-.*$//'`
case ${host} in
m32c*-*-*)
cpu_type=m32c
+ tmake_file=t-fdpbit
;;
alpha*-*-*)
cpu_type=alpha
@@ -121,6 +122,7 @@ microblaze*-*-*)
;;
mips*-*-*)
cpu_type=mips
+ tmake_file=mips/t-mips
;;
powerpc*-*-*)
cpu_type=rs6000
@@ -265,8 +267,10 @@ alpha*-dec-*vms*)
md_unwind_header=alpha/vms-unwind.h
;;
arm-wrs-vxworks)
+ tmake_file=t-fdpbit
;;
arm*-*-freebsd*)
+ tmake_file=t-fdpbit
;;
arm*-*-netbsdelf*)
;;
@@ -309,40 +313,56 @@ arm*-*-elf)
arm*-wince-pe*)
;;
avr-*-rtems*)
+ tmake_file=t-fpbit
;;
avr-*-*)
- # Make HImode functions for AVR
- tmake_file=${cpu_type}/t-avr
+ # Make HImode functions for AVR
+ tmake_file="${cpu_type}/t-avr t-fpbit"
+
;;
bfin*-elf*)
+ tmke_file=t-fdpbit
;;
bfin*-uclinux*)
+ tmake_file=t-fdpbit
md_unwind_header=bfin/linux-unwind.h
;;
bfin*-linux-uclibc*)
+ tmake_file=t-fdpbit
# No need to build crtbeginT.o on uClibc systems. Should probably
# be moved to the OS specific section above.
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
md_unwind_header=bfin/linux-unwind.h
;;
+bfin*-rtems*)
+ tmake_file=t-fdpbit
+ ;;
bfin*-*)
+ tmake_file=t-fdpbit
;;
crisv32-*-elf | crisv32-*-none | cris-*-elf | cris-*-none)
+ tmake_file=t-fdpbit
extra_parts="crtbegin.o crtend.o"
;;
cris-*-linux* | crisv32-*-linux*)
+ tmake_file=t-fdpbit
;;
fido-*-elf)
;;
fr30-*-elf)
+ tmake_file=t-fdpbit
;;
frv-*-elf)
+ tmake_file=t-fdpbit
;;
frv-*-*linux*)
+ tmake_file=t-fdpbit
;;
h8300-*-rtems*)
+ tmake_file=t-fpbit
;;
h8300-*-elf*)
+ tmake_file=t-fpbit
;;
hppa*64*-*-linux*)
;;
@@ -458,6 +478,7 @@ ia64-hp-*vms*)
md_unwind_header=ia64/vms-unwind.h
;;
iq2000*-*-elf*)
+ tmake_file=t-fdpbit
;;
lm32-*-elf*|lm32-*-rtems*)
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
@@ -468,12 +489,16 @@ lm32-*-uclinux*)
tmake_file="lm32/t-lm32 lm32/t-uclinux t-softfp"
;;
m32r-*-elf*|m32r-*-rtems*)
+ tmake_file=t-fdpbit
;;
m32rle-*-elf*)
+ tmake_file=t-fdpbit
;;
m32r-*-linux*)
+ tmake_file=t-fdpbit
;;
m32rle-*-linux*)
+ tmake_file=t-fdpbit
;;
m68k-*-elf*)
;;
@@ -492,29 +517,41 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
m68k-*-rtems*)
;;
mcore-*-elf)
+ tmake_file=t-fdpbit
;;
microblaze*-*-*)
- tmake_file="microblaze/t-microblaze"
+ tmake_file="microblaze/t-microblaze t-fdpbit"
;;
mips-sgi-irix6.5*)
- tmake_file="mips/t-irix6 t-crtfm t-slibgcc mips/t-slibgcc-irix"
+ tmake_file="$tmake_file mips/t-irix6 t-crtfm mips/t-tpbit t-slibgcc mips/t-slibgcc-irix"
extra_parts="crtbegin.o crtend.o crtfastmath.o irix-crti.o irix-crtn.o"
md_unwind_header=mips/irix6-unwind.h
;;
mips*-*-netbsd*) # NetBSD/mips, either endian.
;;
-mips64*-*-linux*)
+mips64*-*-linux* | mipsisa64*-*-linux*)
extra_parts="$extra_parts crtfastmath.o"
- tmake_file="{$tmake_file} t-crtfm"
+ tmake_file="${tmake_file} t-crtfm mips/t-tpbit"
md_unwind_header=mips/linux-unwind.h
;;
mips*-*-linux*) # Linux MIPS, either endian.
extra_parts="$extra_parts crtfastmath.o"
- tmake_file="{$tmake_file} t-crtfm"
+ tmake_file="${tmake_file} t-crtfm"
md_unwind_header=mips/linux-unwind.h
;;
mips*-*-openbsd*)
;;
+mips*-sde-elf*)
+ case "${with_newlib}" in
+ yes)
+ # newlib / libgloss.
+ ;;
+ *)
+ # MIPS toolkit libraries.
+ tmake_file=mips/t-sdemtk
+ ;;
+ esac
+ ;;
mipsisa32-*-elf* | mipsisa32el-*-elf*)
;;
mipsisa32r2-*-elf* | mipsisa32r2el-*-elf*)
@@ -524,6 +561,7 @@ mipsisa64-*-elf* | mipsisa64el-*-elf*)
mipsisa64r2-*-elf* | mipsisa64r2el-*-elf*)
;;
mipsisa64sr71k-*-elf*)
+ tmake_file=t-fdpbit
;;
mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
;;
@@ -546,15 +584,17 @@ mmix-knuth-mmixware)
tmake_file="${tmake_file} ${cpu_type}/t-${cpu_type}"
;;
mn10300-*-*)
+ tmake_file=t-fdpbit
;;
moxie-*-*)
tmake_file="moxie/t-moxie moxie/t-moxie-softfp"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
;;
pdp11-*-*)
+ tmake_file=t-fdpbit
;;
picochip-*-*)
- tmake_file=picochip/t-picochip
+ tmake_file="picochip/t-picochip t-fpbit"
;;
powerpc-*-darwin*)
case ${host} in
@@ -580,44 +620,60 @@ powerpc-*-eabispe*)
tmake_file="${tmake_file} rs6000/t-ppccomm"
;;
powerpc-*-eabisimaltivec*)
+ tmake_file=t-fdpbit
;;
powerpc-*-eabisim*)
+ tmake_file=t-fdpbit
;;
powerpc-*-elf*)
+ tmake_file=t-fdpbit
;;
powerpc-*-eabialtivec*)
+ tmake_file=t-fdpbit
+ ;;
+powerpc-xilinx-eabi*)
+ tmake_file=t-fdpbit
;;
powerpc-*-eabi*)
- tmake_file="${tmake_file} rs6000/t-ppccomm"
+ tmake_file="${tmake_file} rs6000/t-ppccomm t-fdpbit"
;;
powerpc-*-rtems*)
+ tmake_file=t-fdpbit
;;
powerpc-*-linux* | powerpc64-*-linux*)
- tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ldbl128 t-softfp t-dfprules"
+ tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-ldbl128 t-softfp t-dfprules rs6000/t-ppc64-fp"
md_unwind_header=rs6000/linux-unwind.h
;;
powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
+ tmake_file=t-fdpbit
;;
powerpc-*-lynxos*)
+ tmake_file=t-fdpbit
;;
powerpcle-*-elf*)
+ tmake_file=t-fdpbit
;;
powerpcle-*-eabisim*)
+ tmake_file=t-fdpbit
;;
powerpcle-*-eabi*)
+ tmake_file=t-fdpbit
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
md_unwind_header=rs6000/aix-unwind.h
+ tmake_file="t-fdpbit rs6000/t-ppc64-fp"
;;
rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
md_unwind_header=rs6000/aix-unwind.h
+ tmake_file="t-fdpbit rs6000/t-ppc64-fp"
;;
rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
md_unwind_header=rs6000/aix-unwind.h
+ tmake_file="t-fdpbit rs6000/t-ppc64-fp"
;;
rx-*-elf)
extra_parts="crtbegin.o crtend.o"
- tmake_file="rx/t-rx"
+ tmake_file="rx/t-rx t-fdpbit"
;;
s390-*-linux*)
tmake_file="${tmake_file} s390/t-crtstuff s390/t-linux s390/32/t-floattodi"
@@ -639,14 +695,25 @@ sh-*-elf* | sh[12346l]*-*-elf* | \
sh64-*-netbsd* | sh64l*-*-netbsd*)
case ${host} in
sh*-*-linux*)
- tmake_file="${tmake_file} sh/t-linux"
+ tmake_file="${tmake_file} sh/t-linux t-fdpbit"
md_unwind_header=sh/linux-unwind.h
;;
+ sh*-*-netbsd*)
+ # NetBSD's C library includes a fast software FP library that
+ # has support for setting/setting the rounding mode, exception
+ # mask, etc. Therefore, we don't want to include software FP
+ # in libgcc.
+ ;;
+ sh*-*-*)
+ tmake_file=t-fdpbit
+ ;;
esac
;;
sh-*-rtems*)
+ tmake_file=t-fdpbit
;;
sh-wrs-vxworks)
+ tmake_file=t-fdpbit
;;
sparc-*-netbsdelf*)
;;
@@ -660,16 +727,21 @@ sparc-*-elf*)
tmake_file="sparc/t-softmul"
;;
esac
- tmake_file="${tmake_file} sparc/t-softfp t-crtin t-crtfm"
+ tmake_file="${tmake_file} t-fdpbit t-crtin t-crtfm"
extra_parts="crtbegin.o crtend.o crti.o crtn.o crtfastmath.o"
;;
sparc-*-linux*) # SPARC's running GNU/Linux, libc6
+ case ${host} in
+ *-leon*)
+ tmake_file=t-fdpbit
+ ;;
+ esac
extra_parts="$extra_parts crtfastmath.o"
tmake_file="${tmake_file} t-crtfm"
md_unwind_header=sparc/linux-unwind.h
;;
-sparc-*-rtems* | sparc64-*-rtems* )
- tmake_file="sparc/t-elf t-crtin t-crtfm t-rtems"
+sparc-*-rtems*)
+ tmake_file="sparc/t-elf t-crtin t-crtfm t-rtems t-fdpbit"
extra_parts="crtbegin.o crtend.o crti.o crtn.o crtfastmath.o"
;;
sparc*-*-solaris2*)
@@ -681,6 +753,10 @@ sparc64-*-elf*)
tmake_file="${tmake_file} t-crtin t-crtfm"
extra_parts="crtbegin.o crtend.o crti.o crtn.o crtfastmath.o"
;;
+sparc64-*-rtems*)
+ tmake_file="sparc/t-elf t-crtin t-crtfm t-rtems"
+ extra_parts="crtbegin.o crtend.o crti.o crtn.o crtfastmath.o"
+ ;;
sparc-wrs-vxworks)
;;
sparc64-*-freebsd*|ultrasparc-*-freebsd*)
@@ -695,11 +771,13 @@ sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux
sparc64-*-netbsd*)
;;
spu-*-elf*)
+ tmake_file="t-fdpbit spu/t-elf"
;;
tic6x-*-*)
tmake_file="${tmake_file} t-gnu-prefix"
;;
v850*-*-*)
+ tmake_file=t-fdpbit
;;
vax-*-linux*)
;;
@@ -708,6 +786,7 @@ vax-*-netbsdelf*)
vax-*-openbsd*)
;;
xstormy16-*-elf)
+ tmake_file=t-fdpbit
;;
xtensa*-*-elf*)
tmake_file=xtensa/t-xtensa
@@ -718,10 +797,12 @@ xtensa*-*-linux*)
;;
am33_2.0-*-linux*)
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ tmake_file=t-fdpbit
;;
m32c-*-elf*|m32c-*-rtems*)
;;
mep*-*-*)
+ tmake_file=t-fdpbit
;;
*)
echo "*** Configuration ${host} not supported" 1>&2
diff --git a/libgcc/config/avr/avr-lib.h b/libgcc/config/avr/avr-lib.h
new file mode 100644
index 00000000000..daca4d81f9a
--- /dev/null
+++ b/libgcc/config/avr/avr-lib.h
@@ -0,0 +1,6 @@
+#ifdef FLOAT
+#define CMPtype QItype
+#define DF SF
+#define DI SI
+typedef int QItype __attribute__ ((mode (QI)));
+#endif
diff --git a/libgcc/config/h8300/h8300-lib.h b/libgcc/config/h8300/h8300-lib.h
new file mode 100644
index 00000000000..cff664a54ce
--- /dev/null
+++ b/libgcc/config/h8300/h8300-lib.h
@@ -0,0 +1,7 @@
+#ifdef FLOAT
+#ifdef __H8300__
+#define CMPtype HItype
+#else
+#define CMPtype SItype
+#endif
+#endif
diff --git a/libgcc/config/mips/t-irix6 b/libgcc/config/mips/t-irix6
index 77dd41da276..c9bd3cdcb0a 100644
--- a/libgcc/config/mips/t-irix6
+++ b/libgcc/config/mips/t-irix6
@@ -22,15 +22,3 @@ irix-crti.o: $(srcdir)/config/mips/irix-crti.S
irix-crtn.o: $(srcdir)/config/mips/irix-crtn.S
$(crt_compile) -c $<
-
-TPBIT = tp-bit.c
-
-$(gcc_objdir)/tp-bit.c: $(gcc_srcdir)/config/fp-bit.c
- echo '#ifdef __MIPSEL__' > $@
- echo '# define FLOAT_BIT_ORDER_MISMATCH' >> $@
- echo '#endif' >> $@
- echo '#define QUIET_NAN_NEGATED' >> $@
- echo '#if __LDBL_MANT_DIG__ == 106' >> $@
- echo '# define TFLOAT' >> $@
- cat $< >> $@
- echo '#endif' >> $@
diff --git a/libgcc/config/mips/t-mips b/libgcc/config/mips/t-mips
new file mode 100644
index 00000000000..b7d13b3ddb3
--- /dev/null
+++ b/libgcc/config/mips/t-mips
@@ -0,0 +1,4 @@
+FPBIT = true
+FPBIT_CFLAGS = -DQUIET_NAN_NEGATED
+DPBIT = true
+DPBIT_CFLAGS = -DQUIET_NAN_NEGATED
diff --git a/libgcc/config/mips/t-sdemtk b/libgcc/config/mips/t-sdemtk
new file mode 100644
index 00000000000..a06e828b545
--- /dev/null
+++ b/libgcc/config/mips/t-sdemtk
@@ -0,0 +1,3 @@
+# Don't build FPBIT and DPBIT; we'll be using the SDE soft-float library.
+FPBIT =
+DPBIT =
diff --git a/libgcc/config/mips/t-tpbit b/libgcc/config/mips/t-tpbit
new file mode 100644
index 00000000000..1670ef3ffd6
--- /dev/null
+++ b/libgcc/config/mips/t-tpbit
@@ -0,0 +1,4 @@
+ifeq ($(long_double_type_size),128)
+TPBIT = true
+TPBIT_CFLAGS = -DQUIET_NAN_NEGATED
+endif
diff --git a/libgcc/config/rs6000/ppc64-fp.c b/libgcc/config/rs6000/ppc64-fp.c
new file mode 100644
index 00000000000..ab18d2d94b5
--- /dev/null
+++ b/libgcc/config/rs6000/ppc64-fp.c
@@ -0,0 +1,239 @@
+/* Functions needed for soft-float on powerpc64-linux, copied from
+ libgcc2.c with macros expanded to force the use of specific types.
+
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004, 2006, 2009, 2011
+ 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 3, or (at your option) any later
+version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#if defined(__powerpc64__) || defined (__64BIT__) || defined(__ppc64__)
+#define TMODES
+#include "fp-bit.h"
+
+extern DItype __fixtfdi (TFtype);
+extern DItype __fixdfdi (DFtype);
+extern DItype __fixsfdi (SFtype);
+extern USItype __fixunsdfsi (DFtype);
+extern USItype __fixunssfsi (SFtype);
+extern TFtype __floatditf (DItype);
+extern TFtype __floatunditf (UDItype);
+extern DFtype __floatdidf (DItype);
+extern DFtype __floatundidf (UDItype);
+extern SFtype __floatdisf (DItype);
+extern SFtype __floatundisf (UDItype);
+extern DItype __fixunstfdi (TFtype);
+
+static DItype local_fixunssfdi (SFtype);
+static DItype local_fixunsdfdi (DFtype);
+
+DItype
+__fixtfdi (TFtype a)
+{
+ if (a < 0)
+ return - __fixunstfdi (-a);
+ return __fixunstfdi (a);
+}
+
+DItype
+__fixdfdi (DFtype a)
+{
+ if (a < 0)
+ return - local_fixunsdfdi (-a);
+ return local_fixunsdfdi (a);
+}
+
+DItype
+__fixsfdi (SFtype a)
+{
+ if (a < 0)
+ return - local_fixunssfdi (-a);
+ return local_fixunssfdi (a);
+}
+
+USItype
+__fixunsdfsi (DFtype a)
+{
+ if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
+ return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
+ - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
+ return (SItype) a;
+}
+
+USItype
+__fixunssfsi (SFtype a)
+{
+ if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
+ return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
+ - (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
+ return (SItype) a;
+}
+
+TFtype
+__floatditf (DItype u)
+{
+ DFtype dh, dl;
+
+ dh = (SItype) (u >> (sizeof (SItype) * 8));
+ dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (TFtype) dh + (TFtype) dl;
+}
+
+TFtype
+__floatunditf (UDItype u)
+{
+ DFtype dh, dl;
+
+ dh = (USItype) (u >> (sizeof (SItype) * 8));
+ dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (TFtype) dh + (TFtype) dl;
+}
+
+DFtype
+__floatdidf (DItype u)
+{
+ DFtype d;
+
+ d = (SItype) (u >> (sizeof (SItype) * 8));
+ d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return d;
+}
+
+DFtype
+__floatundidf (UDItype u)
+{
+ DFtype d;
+
+ d = (USItype) (u >> (sizeof (SItype) * 8));
+ d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return d;
+}
+
+SFtype
+__floatdisf (DItype u)
+{
+ DFtype f;
+
+ if (53 < (sizeof (DItype) * 8)
+ && 53 > ((sizeof (DItype) * 8) - 53 + 24))
+ {
+ if (! (- ((DItype) 1 << 53) < u
+ && u < ((DItype) 1 << 53)))
+ {
+ if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
+ {
+ u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
+ u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
+ }
+ }
+ }
+ f = (SItype) (u >> (sizeof (SItype) * 8));
+ f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (SFtype) f;
+}
+
+SFtype
+__floatundisf (UDItype u)
+{
+ DFtype f;
+
+ if (53 < (sizeof (DItype) * 8)
+ && 53 > ((sizeof (DItype) * 8) - 53 + 24))
+ {
+ if (u >= ((UDItype) 1 << 53))
+ {
+ if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
+ {
+ u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
+ u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
+ }
+ }
+ }
+ f = (USItype) (u >> (sizeof (SItype) * 8));
+ f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (SFtype) f;
+}
+
+DItype
+__fixunstfdi (TFtype a)
+{
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ UDItype v = (USItype) b;
+ v <<= (sizeof (SItype) * 8);
+ /* Remove high part from the TFtype, leaving the low part as flonum. */
+ a -= (TFtype) v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (-a);
+ else
+ v += (USItype) a;
+ return v;
+}
+
+/* This version is needed to prevent recursion; fixunsdfdi in libgcc
+ calls fixdfdi, which in turn calls calls fixunsdfdi. */
+
+static DItype
+local_fixunsdfdi (DFtype a)
+{
+ USItype hi, lo;
+
+ hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
+ lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
+ return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
+}
+
+/* This version is needed to prevent recursion; fixunssfdi in libgcc
+ calls fixsfdi, which in turn calls calls fixunssfdi. */
+
+static DItype
+local_fixunssfdi (SFtype original_a)
+{
+ DFtype a = original_a;
+ USItype hi, lo;
+
+ hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
+ lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
+ return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
+}
+
+#endif /* __powerpc64__ */
diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin
index 404df85870f..4464fd7d6e6 100644
--- a/libgcc/config/rs6000/t-darwin
+++ b/libgcc/config/rs6000/t-darwin
@@ -3,6 +3,8 @@ DARWIN_EXTRA_CRT_BUILD_CFLAGS = -mlongcall -mmacosx-version-min=10.4
crt2.o: $(srcdir)/config/rs6000/darwin-crt2.c
$(crt_compile) $(DARWIN_EXTRA_CRT_BUILD_CFLAGS) -c $<
+LIB2ADD += $(srcdir)/config/rs6000/ppc64-fp.c
+
LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c
SHLIB_VERPFX = $(gcc_srcdir)/config/rs6000/darwin-libgcc
diff --git a/libgcc/config/rs6000/t-ppc64-fp b/libgcc/config/rs6000/t-ppc64-fp
new file mode 100644
index 00000000000..26d1730bcdb
--- /dev/null
+++ b/libgcc/config/rs6000/t-ppc64-fp
@@ -0,0 +1,2 @@
+# Can be used unconditionally, wrapped in __powerpc64__ || __64BIT__ __ppc64__.
+LIB2ADD += $(srcdir)/config/rs6000/ppc64-fp.c
diff --git a/libgcc/config/rx/rx-lib.h b/libgcc/config/rx/rx-lib.h
new file mode 100644
index 00000000000..fb1d14632a6
--- /dev/null
+++ b/libgcc/config/rx/rx-lib.h
@@ -0,0 +1,6 @@
+#ifdef FLOAT
+#ifndef __RX_64BIT_DOUBLES__
+#define DF SF
+#define FLOAT_ONLY
+#endif
+#endif
diff --git a/libgcc/config/rx/t-rx b/libgcc/config/rx/t-rx
index 1e66af0c8d3..3ca7dc069fa 100644
--- a/libgcc/config/rx/t-rx
+++ b/libgcc/config/rx/t-rx
@@ -1,5 +1,5 @@
# Makefile fragment for building LIBGCC for the Renesas RX target.
-# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
# Contributed by Red Hat.
#
# This file is part of GCC.
@@ -28,17 +28,7 @@ LIB2ADD = $(srcdir)/config/rx/rx-abi-functions.c
# We need special handling of the floating point conversion
# routines, to allow for the varying size of a double:
-FPBIT = fp-bit.c
-$(gcc_objdir)/fp-bit.c: $(gcc_srcdir)/config/fp-bit.c
- echo '#define FLOAT' > $@
- echo '#ifndef __RX_64BIT_DOUBLES__' >> $@
- echo '#define DF SF' >> $@
- echo '#define FLOAT_ONLY' >> $@
- echo '#endif' >> $@
- cat $(gcc_srcdir)/config/fp-bit.c >> $@
-
-DPBIT = dp-bit.c
-$(gcc_objdir)/dp-bit.c: $(gcc_srcdir)/config/fp-bit.c
- echo '#ifdef __RX_64BIT_DOUBLES__' > $@
- cat $(gcc_srcdir)/config/fp-bit.c >> $@
- echo '#endif' >> $@
+FPBIT = true
+ifeq ($(double_type_size),64)
+DPBIT = true
+endif
diff --git a/libgcc/config/sparc/t-softfp b/libgcc/config/sparc/t-softfp
deleted file mode 100644
index 94dfcfae0a1..00000000000
--- a/libgcc/config/sparc/t-softfp
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2010, 2011 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 3, or (at your option)
-# any later version.
-#
-# 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 COPYING3. If not see
-# <http://www.gnu.org/licenses/>.
-
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-$(gcc_objdir)/dp-bit.c: $(gcc_srcdir)/config/fp-bit.c
- cat $< > $@
-
-$(gcc_objdir)/fp-bit.c: $(gcc_srcdir)/config/fp-bit.c
- echo '#define FLOAT' > $@
- cat $< >> $@
diff --git a/libgcc/config/spu/t-elf b/libgcc/config/spu/t-elf
new file mode 100644
index 00000000000..7094da526bb
--- /dev/null
+++ b/libgcc/config/spu/t-elf
@@ -0,0 +1,3 @@
+# We provide our own version of __divdf3 that performs better and has
+# better support for non-default rounding modes.
+DPBIT_FUNCS := $(filter-out _div_df, $(DPBIT_FUNCS))
diff --git a/libgcc/config/t-fdpbit b/libgcc/config/t-fdpbit
new file mode 100644
index 00000000000..0e7119adeaf
--- /dev/null
+++ b/libgcc/config/t-fdpbit
@@ -0,0 +1,2 @@
+FPBIT = true
+DPBIT = true
diff --git a/libgcc/config/t-fpbit b/libgcc/config/t-fpbit
new file mode 100644
index 00000000000..e56e34d91c8
--- /dev/null
+++ b/libgcc/config/t-fpbit
@@ -0,0 +1,2 @@
+FPBIT = true
+FPBIT_CFLAGS = -DFLOAT_ONLY -DSMALL_MACHINE
diff --git a/libgcc/configure b/libgcc/configure
index 60363387312..0ead080691d 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -168,7 +168,8 @@ test x\$exitcode = x0 || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
if (eval "$as_required") 2>/dev/null; then :
as_have_required=yes
else
@@ -551,6 +552,42 @@ PACKAGE_BUGREPORT=''
PACKAGE_URL='http://www.gnu.org/software/libgcc/'
ac_unique_file="static-object.mk"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
ac_subst_vars='LTLIBOBJS
LIBOBJS
asm_hidden_op
@@ -563,6 +600,10 @@ vis_hide
fixed_point
enable_decimal_float
decimal_float
+long_double_type_size
+double_type_size
+EGREP
+GREP
CPP
OBJEXT
EXEEXT
@@ -1464,6 +1505,255 @@ fi
return $ac_retval
} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_header_preproc LINENO HEADER VAR
+# ----------------------------------------------
+# Tests whether HEADER is present, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_preproc ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_preproc
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
@@ -3649,8 +3939,340 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_c_preproc_warn_flag=yes
-# Check for decimal float support.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if test "${ac_cv_sizeof_double+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (double)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5
+$as_echo_n "checking size of long double... " >&6; }
+if test "${ac_cv_sizeof_long_double+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long double)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_long_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5
+$as_echo "$ac_cv_sizeof_long_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+_ACEOF
+
+
+as_fn_arith $ac_cv_sizeof_double \* 8 && double_type_size=$as_val
+as_fn_arith $ac_cv_sizeof_long_double \* 8 && long_double_type_size=$as_val
+
+
+
+# Check for decimal float support.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether decimal floating point is supported" >&5
$as_echo_n "checking whether decimal floating point is supported... " >&6; }
if test "${libgcc_cv_dfp+set}" = set; then :
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index d96bcb4224a..8e2d1accd9d 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -152,6 +152,13 @@ GCC_NO_EXECUTABLES
AC_PROG_CC
AC_PROG_CPP_WERROR
+AC_CHECK_SIZEOF([double])
+AC_CHECK_SIZEOF([long double])
+AS_VAR_ARITH([double_type_size], [$ac_cv_sizeof_double \* 8])
+AS_VAR_ARITH([long_double_type_size], [$ac_cv_sizeof_long_double \* 8])
+AC_SUBST(double_type_size)
+AC_SUBST(long_double_type_size)
+
# Check for decimal float support.
AC_CACHE_CHECK([whether decimal floating point is supported], [libgcc_cv_dfp],
[AC_COMPILE_IFELSE([_Decimal32 x;], [libgcc_cv_dfp=yes],
diff --git a/libgcc/fp-bit.c b/libgcc/fp-bit.c
new file mode 100644
index 00000000000..de9b3ada5ec
--- /dev/null
+++ b/libgcc/fp-bit.c
@@ -0,0 +1,1657 @@
+/* This is a software floating point library which can be used
+ for targets without hardware floating point.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
+ 2004, 2005, 2008, 2009, 2010, 2011 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 3, or (at your option) any later
+version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* This implements IEEE 754 format arithmetic, but does not provide a
+ mechanism for setting the rounding mode, or for generating or handling
+ exceptions.
+
+ The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
+ Wilson, all of Cygnus Support. */
+
+/* The intended way to use this file is to make two copies, add `#define FLOAT'
+ to one copy, then compile both copies and add them to libgcc.a. */
+
+#include "tconfig.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "fp-bit.h"
+
+/* The following macros can be defined to change the behavior of this file:
+ FLOAT: Implement a `float', aka SFmode, fp library. If this is not
+ defined, then this file implements a `double', aka DFmode, fp library.
+ FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
+ don't include float->double conversion which requires the double library.
+ This is useful only for machines which can't support doubles, e.g. some
+ 8-bit processors.
+ CMPtype: Specify the type that floating point compares should return.
+ This defaults to SItype, aka int.
+ _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
+ two integers to the FLO_union_type.
+ NO_DENORMALS: Disable handling of denormals.
+ NO_NANS: Disable nan and infinity handling
+ SMALL_MACHINE: Useful when operations on QIs and HIs are faster
+ than on an SI */
+
+/* We don't currently support extended floats (long doubles) on machines
+ without hardware to deal with them.
+
+ These stubs are just to keep the linker from complaining about unresolved
+ references which can be pulled in from libio & libstdc++, even if the
+ user isn't using long doubles. However, they may generate an unresolved
+ external to abort if abort is not used by the function, and the stubs
+ are referenced from within libc, since libgcc goes before and after the
+ system library. */
+
+#ifdef DECLARE_LIBRARY_RENAMES
+ DECLARE_LIBRARY_RENAMES
+#endif
+
+#ifdef EXTENDED_FLOAT_STUBS
+extern void abort (void);
+void __extendsfxf2 (void) { abort(); }
+void __extenddfxf2 (void) { abort(); }
+void __truncxfdf2 (void) { abort(); }
+void __truncxfsf2 (void) { abort(); }
+void __fixxfsi (void) { abort(); }
+void __floatsixf (void) { abort(); }
+void __addxf3 (void) { abort(); }
+void __subxf3 (void) { abort(); }
+void __mulxf3 (void) { abort(); }
+void __divxf3 (void) { abort(); }
+void __negxf2 (void) { abort(); }
+void __eqxf2 (void) { abort(); }
+void __nexf2 (void) { abort(); }
+void __gtxf2 (void) { abort(); }
+void __gexf2 (void) { abort(); }
+void __lexf2 (void) { abort(); }
+void __ltxf2 (void) { abort(); }
+
+void __extendsftf2 (void) { abort(); }
+void __extenddftf2 (void) { abort(); }
+void __trunctfdf2 (void) { abort(); }
+void __trunctfsf2 (void) { abort(); }
+void __fixtfsi (void) { abort(); }
+void __floatsitf (void) { abort(); }
+void __addtf3 (void) { abort(); }
+void __subtf3 (void) { abort(); }
+void __multf3 (void) { abort(); }
+void __divtf3 (void) { abort(); }
+void __negtf2 (void) { abort(); }
+void __eqtf2 (void) { abort(); }
+void __netf2 (void) { abort(); }
+void __gttf2 (void) { abort(); }
+void __getf2 (void) { abort(); }
+void __letf2 (void) { abort(); }
+void __lttf2 (void) { abort(); }
+#else /* !EXTENDED_FLOAT_STUBS, rest of file */
+
+/* IEEE "special" number predicates */
+
+#ifdef NO_NANS
+
+#define nan() 0
+#define isnan(x) 0
+#define isinf(x) 0
+#else
+
+#if defined L_thenan_sf
+const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
+#elif defined L_thenan_df
+const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
+#elif defined L_thenan_tf
+const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
+#elif defined TFLOAT
+extern const fp_number_type __thenan_tf;
+#elif defined FLOAT
+extern const fp_number_type __thenan_sf;
+#else
+extern const fp_number_type __thenan_df;
+#endif
+
+INLINE
+static const fp_number_type *
+makenan (void)
+{
+#ifdef TFLOAT
+ return & __thenan_tf;
+#elif defined FLOAT
+ return & __thenan_sf;
+#else
+ return & __thenan_df;
+#endif
+}
+
+INLINE
+static int
+isnan (const fp_number_type *x)
+{
+ return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
+ 0);
+}
+
+INLINE
+static int
+isinf (const fp_number_type * x)
+{
+ return __builtin_expect (x->class == CLASS_INFINITY, 0);
+}
+
+#endif /* NO_NANS */
+
+INLINE
+static int
+iszero (const fp_number_type * x)
+{
+ return x->class == CLASS_ZERO;
+}
+
+INLINE
+static void
+flip_sign ( fp_number_type * x)
+{
+ x->sign = !x->sign;
+}
+
+/* Count leading zeroes in N. */
+INLINE
+static int
+clzusi (USItype n)
+{
+ extern int __clzsi2 (USItype);
+ if (sizeof (USItype) == sizeof (unsigned int))
+ return __builtin_clz (n);
+ else if (sizeof (USItype) == sizeof (unsigned long))
+ return __builtin_clzl (n);
+ else if (sizeof (USItype) == sizeof (unsigned long long))
+ return __builtin_clzll (n);
+ else
+ return __clzsi2 (n);
+}
+
+extern FLO_type pack_d (const fp_number_type * );
+
+#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
+FLO_type
+pack_d (const fp_number_type *src)
+{
+ FLO_union_type dst;
+ fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
+ int sign = src->sign;
+ int exp = 0;
+
+ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
+ {
+ /* We can't represent these values accurately. By using the
+ largest possible magnitude, we guarantee that the conversion
+ of infinity is at least as big as any finite number. */
+ exp = EXPMAX;
+ fraction = ((fractype) 1 << FRACBITS) - 1;
+ }
+ else if (isnan (src))
+ {
+ exp = EXPMAX;
+ if (src->class == CLASS_QNAN || 1)
+ {
+#ifdef QUIET_NAN_NEGATED
+ fraction |= QUIET_NAN - 1;
+#else
+ fraction |= QUIET_NAN;
+#endif
+ }
+ }
+ else if (isinf (src))
+ {
+ exp = EXPMAX;
+ fraction = 0;
+ }
+ else if (iszero (src))
+ {
+ exp = 0;
+ fraction = 0;
+ }
+ else if (fraction == 0)
+ {
+ exp = 0;
+ }
+ else
+ {
+ if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
+ {
+#ifdef NO_DENORMALS
+ /* Go straight to a zero representation if denormals are not
+ supported. The denormal handling would be harmless but
+ isn't unnecessary. */
+ exp = 0;
+ fraction = 0;
+#else /* NO_DENORMALS */
+ /* This number's exponent is too low to fit into the bits
+ available in the number, so we'll store 0 in the exponent and
+ shift the fraction to the right to make up for it. */
+
+ int shift = NORMAL_EXPMIN - src->normal_exp;
+
+ exp = 0;
+
+ if (shift > FRAC_NBITS - NGARDS)
+ {
+ /* No point shifting, since it's more that 64 out. */
+ fraction = 0;
+ }
+ else
+ {
+ int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
+ fraction = (fraction >> shift) | lowbit;
+ }
+ if ((fraction & GARDMASK) == GARDMSB)
+ {
+ if ((fraction & (1 << NGARDS)))
+ fraction += GARDROUND + 1;
+ }
+ else
+ {
+ /* Add to the guards to round up. */
+ fraction += GARDROUND;
+ }
+ /* Perhaps the rounding means we now need to change the
+ exponent, because the fraction is no longer denormal. */
+ if (fraction >= IMPLICIT_1)
+ {
+ exp += 1;
+ }
+ fraction >>= NGARDS;
+#endif /* NO_DENORMALS */
+ }
+ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
+ && __builtin_expect (src->normal_exp > EXPBIAS, 0))
+ {
+ exp = EXPMAX;
+ fraction = 0;
+ }
+ else
+ {
+ exp = src->normal_exp + EXPBIAS;
+ if (!ROUND_TOWARDS_ZERO)
+ {
+ /* IF the gard bits are the all zero, but the first, then we're
+ half way between two numbers, choose the one which makes the
+ lsb of the answer 0. */
+ if ((fraction & GARDMASK) == GARDMSB)
+ {
+ if (fraction & (1 << NGARDS))
+ fraction += GARDROUND + 1;
+ }
+ else
+ {
+ /* Add a one to the guards to round up */
+ fraction += GARDROUND;
+ }
+ if (fraction >= IMPLICIT_2)
+ {
+ fraction >>= 1;
+ exp += 1;
+ }
+ }
+ fraction >>= NGARDS;
+
+ if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
+ {
+ /* Saturate on overflow. */
+ exp = EXPMAX;
+ fraction = ((fractype) 1 << FRACBITS) - 1;
+ }
+ }
+ }
+
+ /* We previously used bitfields to store the number, but this doesn't
+ handle little/big endian systems conveniently, so use shifts and
+ masks */
+#ifdef FLOAT_BIT_ORDER_MISMATCH
+ dst.bits.fraction = fraction;
+ dst.bits.exp = exp;
+ dst.bits.sign = sign;
+#else
+# if defined TFLOAT && defined HALFFRACBITS
+ {
+ halffractype high, low, unity;
+ int lowsign, lowexp;
+
+ unity = (halffractype) 1 << HALFFRACBITS;
+
+ /* Set HIGH to the high double's significand, masking out the implicit 1.
+ Set LOW to the low double's full significand. */
+ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
+ low = fraction & (unity * 2 - 1);
+
+ /* Get the initial sign and exponent of the low double. */
+ lowexp = exp - HALFFRACBITS - 1;
+ lowsign = sign;
+
+ /* HIGH should be rounded like a normal double, making |LOW| <=
+ 0.5 ULP of HIGH. Assume round-to-nearest. */
+ if (exp < EXPMAX)
+ if (low > unity || (low == unity && (high & 1) == 1))
+ {
+ /* Round HIGH up and adjust LOW to match. */
+ high++;
+ if (high == unity)
+ {
+ /* May make it infinite, but that's OK. */
+ high = 0;
+ exp++;
+ }
+ low = unity * 2 - low;
+ lowsign ^= 1;
+ }
+
+ high |= (halffractype) exp << HALFFRACBITS;
+ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
+
+ if (exp == EXPMAX || exp == 0 || low == 0)
+ low = 0;
+ else
+ {
+ while (lowexp > 0 && low < unity)
+ {
+ low <<= 1;
+ lowexp--;
+ }
+
+ if (lowexp <= 0)
+ {
+ halffractype roundmsb, round;
+ int shift;
+
+ shift = 1 - lowexp;
+ roundmsb = (1 << (shift - 1));
+ round = low & ((roundmsb << 1) - 1);
+
+ low >>= shift;
+ lowexp = 0;
+
+ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
+ {
+ low++;
+ if (low == unity)
+ /* LOW rounds up to the smallest normal number. */
+ lowexp++;
+ }
+ }
+
+ low &= unity - 1;
+ low |= (halffractype) lowexp << HALFFRACBITS;
+ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
+ }
+ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
+ }
+# else
+ dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
+ dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
+ dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
+# endif
+#endif
+
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
+#ifdef TFLOAT
+ {
+ qrtrfractype tmp1 = dst.words[0];
+ qrtrfractype tmp2 = dst.words[1];
+ dst.words[0] = dst.words[3];
+ dst.words[1] = dst.words[2];
+ dst.words[2] = tmp2;
+ dst.words[3] = tmp1;
+ }
+#else
+ {
+ halffractype tmp = dst.words[0];
+ dst.words[0] = dst.words[1];
+ dst.words[1] = tmp;
+ }
+#endif
+#endif
+
+ return dst.value;
+}
+#endif
+
+#if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
+void
+unpack_d (FLO_union_type * src, fp_number_type * dst)
+{
+ /* We previously used bitfields to store the number, but this doesn't
+ handle little/big endian systems conveniently, so use shifts and
+ masks */
+ fractype fraction;
+ int exp;
+ int sign;
+
+#if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
+ FLO_union_type swapped;
+
+#ifdef TFLOAT
+ swapped.words[0] = src->words[3];
+ swapped.words[1] = src->words[2];
+ swapped.words[2] = src->words[1];
+ swapped.words[3] = src->words[0];
+#else
+ swapped.words[0] = src->words[1];
+ swapped.words[1] = src->words[0];
+#endif
+ src = &swapped;
+#endif
+
+#ifdef FLOAT_BIT_ORDER_MISMATCH
+ fraction = src->bits.fraction;
+ exp = src->bits.exp;
+ sign = src->bits.sign;
+#else
+# if defined TFLOAT && defined HALFFRACBITS
+ {
+ halffractype high, low;
+
+ high = src->value_raw >> HALFSHIFT;
+ low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
+
+ fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
+ fraction <<= FRACBITS - HALFFRACBITS;
+ exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
+ sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
+
+ if (exp != EXPMAX && exp != 0 && low != 0)
+ {
+ int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
+ int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
+ int shift;
+ fractype xlow;
+
+ xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
+ if (lowexp)
+ xlow |= (((halffractype)1) << HALFFRACBITS);
+ else
+ lowexp = 1;
+ shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
+ if (shift > 0)
+ xlow <<= shift;
+ else if (shift < 0)
+ xlow >>= -shift;
+ if (sign == lowsign)
+ fraction += xlow;
+ else if (fraction >= xlow)
+ fraction -= xlow;
+ else
+ {
+ /* The high part is a power of two but the full number is lower.
+ This code will leave the implicit 1 in FRACTION, but we'd
+ have added that below anyway. */
+ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
+ exp--;
+ }
+ }
+ }
+# else
+ fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
+ exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
+ sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
+# endif
+#endif
+
+ dst->sign = sign;
+ if (exp == 0)
+ {
+ /* Hmm. Looks like 0 */
+ if (fraction == 0
+#ifdef NO_DENORMALS
+ || 1
+#endif
+ )
+ {
+ /* tastes like zero */
+ dst->class = CLASS_ZERO;
+ }
+ else
+ {
+ /* Zero exponent with nonzero fraction - it's denormalized,
+ so there isn't a leading implicit one - we'll shift it so
+ it gets one. */
+ dst->normal_exp = exp - EXPBIAS + 1;
+ fraction <<= NGARDS;
+
+ dst->class = CLASS_NUMBER;
+#if 1
+ while (fraction < IMPLICIT_1)
+ {
+ fraction <<= 1;
+ dst->normal_exp--;
+ }
+#endif
+ dst->fraction.ll = fraction;
+ }
+ }
+ else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
+ && __builtin_expect (exp == EXPMAX, 0))
+ {
+ /* Huge exponent*/
+ if (fraction == 0)
+ {
+ /* Attached to a zero fraction - means infinity */
+ dst->class = CLASS_INFINITY;
+ }
+ else
+ {
+ /* Nonzero fraction, means nan */
+#ifdef QUIET_NAN_NEGATED
+ if ((fraction & QUIET_NAN) == 0)
+#else
+ if (fraction & QUIET_NAN)
+#endif
+ {
+ dst->class = CLASS_QNAN;
+ }
+ else
+ {
+ dst->class = CLASS_SNAN;
+ }
+ /* Keep the fraction part as the nan number */
+ dst->fraction.ll = fraction;
+ }
+ }
+ else
+ {
+ /* Nothing strange about this number */
+ dst->normal_exp = exp - EXPBIAS;
+ dst->class = CLASS_NUMBER;
+ dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
+ }
+}
+#endif /* L_unpack_df || L_unpack_sf */
+
+#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
+static const fp_number_type *
+_fpadd_parts (fp_number_type * a,
+ fp_number_type * b,
+ fp_number_type * tmp)
+{
+ intfrac tfraction;
+
+ /* Put commonly used fields in local variables. */
+ int a_normal_exp;
+ int b_normal_exp;
+ fractype a_fraction;
+ fractype b_fraction;
+
+ if (isnan (a))
+ {
+ return a;
+ }
+ if (isnan (b))
+ {
+ return b;
+ }
+ if (isinf (a))
+ {
+ /* Adding infinities with opposite signs yields a NaN. */
+ if (isinf (b) && a->sign != b->sign)
+ return makenan ();
+ return a;
+ }
+ if (isinf (b))
+ {
+ return b;
+ }
+ if (iszero (b))
+ {
+ if (iszero (a))
+ {
+ *tmp = *a;
+ tmp->sign = a->sign & b->sign;
+ return tmp;
+ }
+ return a;
+ }
+ if (iszero (a))
+ {
+ return b;
+ }
+
+ /* Got two numbers. shift the smaller and increment the exponent till
+ they're the same */
+ {
+ int diff;
+ int sdiff;
+
+ a_normal_exp = a->normal_exp;
+ b_normal_exp = b->normal_exp;
+ a_fraction = a->fraction.ll;
+ b_fraction = b->fraction.ll;
+
+ diff = a_normal_exp - b_normal_exp;
+ sdiff = diff;
+
+ if (diff < 0)
+ diff = -diff;
+ if (diff < FRAC_NBITS)
+ {
+ if (sdiff > 0)
+ {
+ b_normal_exp += diff;
+ LSHIFT (b_fraction, diff);
+ }
+ else if (sdiff < 0)
+ {
+ a_normal_exp += diff;
+ LSHIFT (a_fraction, diff);
+ }
+ }
+ else
+ {
+ /* Somethings's up.. choose the biggest */
+ if (a_normal_exp > b_normal_exp)
+ {
+ b_normal_exp = a_normal_exp;
+ b_fraction = 0;
+ }
+ else
+ {
+ a_normal_exp = b_normal_exp;
+ a_fraction = 0;
+ }
+ }
+ }
+
+ if (a->sign != b->sign)
+ {
+ if (a->sign)
+ {
+ tfraction = -a_fraction + b_fraction;
+ }
+ else
+ {
+ tfraction = a_fraction - b_fraction;
+ }
+ if (tfraction >= 0)
+ {
+ tmp->sign = 0;
+ tmp->normal_exp = a_normal_exp;
+ tmp->fraction.ll = tfraction;
+ }
+ else
+ {
+ tmp->sign = 1;
+ tmp->normal_exp = a_normal_exp;
+ tmp->fraction.ll = -tfraction;
+ }
+ /* and renormalize it */
+
+ while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
+ {
+ tmp->fraction.ll <<= 1;
+ tmp->normal_exp--;
+ }
+ }
+ else
+ {
+ tmp->sign = a->sign;
+ tmp->normal_exp = a_normal_exp;
+ tmp->fraction.ll = a_fraction + b_fraction;
+ }
+ tmp->class = CLASS_NUMBER;
+ /* Now the fraction is added, we have to shift down to renormalize the
+ number */
+
+ if (tmp->fraction.ll >= IMPLICIT_2)
+ {
+ LSHIFT (tmp->fraction.ll, 1);
+ tmp->normal_exp++;
+ }
+ return tmp;
+}
+
+FLO_type
+add (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ fp_number_type tmp;
+ const fp_number_type *res;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ res = _fpadd_parts (&a, &b, &tmp);
+
+ return pack_d (res);
+}
+
+FLO_type
+sub (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ fp_number_type tmp;
+ const fp_number_type *res;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ b.sign ^= 1;
+
+ res = _fpadd_parts (&a, &b, &tmp);
+
+ return pack_d (res);
+}
+#endif /* L_addsub_sf || L_addsub_df */
+
+#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
+static inline __attribute__ ((__always_inline__)) const fp_number_type *
+_fpmul_parts ( fp_number_type * a,
+ fp_number_type * b,
+ fp_number_type * tmp)
+{
+ fractype low = 0;
+ fractype high = 0;
+
+ if (isnan (a))
+ {
+ a->sign = a->sign != b->sign;
+ return a;
+ }
+ if (isnan (b))
+ {
+ b->sign = a->sign != b->sign;
+ return b;
+ }
+ if (isinf (a))
+ {
+ if (iszero (b))
+ return makenan ();
+ a->sign = a->sign != b->sign;
+ return a;
+ }
+ if (isinf (b))
+ {
+ if (iszero (a))
+ {
+ return makenan ();
+ }
+ b->sign = a->sign != b->sign;
+ return b;
+ }
+ if (iszero (a))
+ {
+ a->sign = a->sign != b->sign;
+ return a;
+ }
+ if (iszero (b))
+ {
+ b->sign = a->sign != b->sign;
+ return b;
+ }
+
+ /* Calculate the mantissa by multiplying both numbers to get a
+ twice-as-wide number. */
+ {
+#if defined(NO_DI_MODE) || defined(TFLOAT)
+ {
+ fractype x = a->fraction.ll;
+ fractype ylow = b->fraction.ll;
+ fractype yhigh = 0;
+ int bit;
+
+ /* ??? This does multiplies one bit at a time. Optimize. */
+ for (bit = 0; bit < FRAC_NBITS; bit++)
+ {
+ int carry;
+
+ if (x & 1)
+ {
+ carry = (low += ylow) < ylow;
+ high += yhigh + carry;
+ }
+ yhigh <<= 1;
+ if (ylow & FRACHIGH)
+ {
+ yhigh |= 1;
+ }
+ ylow <<= 1;
+ x >>= 1;
+ }
+ }
+#elif defined(FLOAT)
+ /* Multiplying two USIs to get a UDI, we're safe. */
+ {
+ UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
+
+ high = answer >> BITS_PER_SI;
+ low = answer;
+ }
+#else
+ /* fractype is DImode, but we need the result to be twice as wide.
+ Assuming a widening multiply from DImode to TImode is not
+ available, build one by hand. */
+ {
+ USItype nl = a->fraction.ll;
+ USItype nh = a->fraction.ll >> BITS_PER_SI;
+ USItype ml = b->fraction.ll;
+ USItype mh = b->fraction.ll >> BITS_PER_SI;
+ UDItype pp_ll = (UDItype) ml * nl;
+ UDItype pp_hl = (UDItype) mh * nl;
+ UDItype pp_lh = (UDItype) ml * nh;
+ UDItype pp_hh = (UDItype) mh * nh;
+ UDItype res2 = 0;
+ UDItype res0 = 0;
+ UDItype ps_hh__ = pp_hl + pp_lh;
+ if (ps_hh__ < pp_hl)
+ res2 += (UDItype)1 << BITS_PER_SI;
+ pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
+ res0 = pp_ll + pp_hl;
+ if (res0 < pp_ll)
+ res2++;
+ res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
+ high = res2;
+ low = res0;
+ }
+#endif
+ }
+
+ tmp->normal_exp = a->normal_exp + b->normal_exp
+ + FRAC_NBITS - (FRACBITS + NGARDS);
+ tmp->sign = a->sign != b->sign;
+ while (high >= IMPLICIT_2)
+ {
+ tmp->normal_exp++;
+ if (high & 1)
+ {
+ low >>= 1;
+ low |= FRACHIGH;
+ }
+ high >>= 1;
+ }
+ while (high < IMPLICIT_1)
+ {
+ tmp->normal_exp--;
+
+ high <<= 1;
+ if (low & FRACHIGH)
+ high |= 1;
+ low <<= 1;
+ }
+
+ if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
+ {
+ if (high & (1 << NGARDS))
+ {
+ /* Because we're half way, we would round to even by adding
+ GARDROUND + 1, except that's also done in the packing
+ function, and rounding twice will lose precision and cause
+ the result to be too far off. Example: 32-bit floats with
+ bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
+ off), not 0x1000 (more than 0.5ulp off). */
+ }
+ else if (low)
+ {
+ /* We're a further than half way by a small amount corresponding
+ to the bits set in "low". Knowing that, we round here and
+ not in pack_d, because there we don't have "low" available
+ anymore. */
+ high += GARDROUND + 1;
+
+ /* Avoid further rounding in pack_d. */
+ high &= ~(fractype) GARDMASK;
+ }
+ }
+ tmp->fraction.ll = high;
+ tmp->class = CLASS_NUMBER;
+ return tmp;
+}
+
+FLO_type
+multiply (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ fp_number_type tmp;
+ const fp_number_type *res;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ res = _fpmul_parts (&a, &b, &tmp);
+
+ return pack_d (res);
+}
+#endif /* L_mul_sf || L_mul_df || L_mul_tf */
+
+#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
+static inline __attribute__ ((__always_inline__)) const fp_number_type *
+_fpdiv_parts (fp_number_type * a,
+ fp_number_type * b)
+{
+ fractype bit;
+ fractype numerator;
+ fractype denominator;
+ fractype quotient;
+
+ if (isnan (a))
+ {
+ return a;
+ }
+ if (isnan (b))
+ {
+ return b;
+ }
+
+ a->sign = a->sign ^ b->sign;
+
+ if (isinf (a) || iszero (a))
+ {
+ if (a->class == b->class)
+ return makenan ();
+ return a;
+ }
+
+ if (isinf (b))
+ {
+ a->fraction.ll = 0;
+ a->normal_exp = 0;
+ return a;
+ }
+ if (iszero (b))
+ {
+ a->class = CLASS_INFINITY;
+ return a;
+ }
+
+ /* Calculate the mantissa by multiplying both 64bit numbers to get a
+ 128 bit number */
+ {
+ /* quotient =
+ ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
+ */
+
+ a->normal_exp = a->normal_exp - b->normal_exp;
+ numerator = a->fraction.ll;
+ denominator = b->fraction.ll;
+
+ if (numerator < denominator)
+ {
+ /* Fraction will be less than 1.0 */
+ numerator *= 2;
+ a->normal_exp--;
+ }
+ bit = IMPLICIT_1;
+ quotient = 0;
+ /* ??? Does divide one bit at a time. Optimize. */
+ while (bit)
+ {
+ if (numerator >= denominator)
+ {
+ quotient |= bit;
+ numerator -= denominator;
+ }
+ bit >>= 1;
+ numerator *= 2;
+ }
+
+ if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
+ {
+ if (quotient & (1 << NGARDS))
+ {
+ /* Because we're half way, we would round to even by adding
+ GARDROUND + 1, except that's also done in the packing
+ function, and rounding twice will lose precision and cause
+ the result to be too far off. */
+ }
+ else if (numerator)
+ {
+ /* We're a further than half way by the small amount
+ corresponding to the bits set in "numerator". Knowing
+ that, we round here and not in pack_d, because there we
+ don't have "numerator" available anymore. */
+ quotient += GARDROUND + 1;
+
+ /* Avoid further rounding in pack_d. */
+ quotient &= ~(fractype) GARDMASK;
+ }
+ }
+
+ a->fraction.ll = quotient;
+ return (a);
+ }
+}
+
+FLO_type
+divide (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ const fp_number_type *res;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ res = _fpdiv_parts (&a, &b);
+
+ return pack_d (res);
+}
+#endif /* L_div_sf || L_div_df */
+
+#if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
+ || defined(L_fpcmp_parts_tf)
+/* according to the demo, fpcmp returns a comparison with 0... thus
+ a<b -> -1
+ a==b -> 0
+ a>b -> +1
+ */
+
+int
+__fpcmp_parts (fp_number_type * a, fp_number_type * b)
+{
+#if 0
+ /* either nan -> unordered. Must be checked outside of this routine. */
+ if (isnan (a) && isnan (b))
+ {
+ return 1; /* still unordered! */
+ }
+#endif
+
+ if (isnan (a) || isnan (b))
+ {
+ return 1; /* how to indicate unordered compare? */
+ }
+ if (isinf (a) && isinf (b))
+ {
+ /* +inf > -inf, but +inf != +inf */
+ /* b \a| +inf(0)| -inf(1)
+ ______\+--------+--------
+ +inf(0)| a==b(0)| a<b(-1)
+ -------+--------+--------
+ -inf(1)| a>b(1) | a==b(0)
+ -------+--------+--------
+ So since unordered must be nonzero, just line up the columns...
+ */
+ return b->sign - a->sign;
+ }
+ /* but not both... */
+ if (isinf (a))
+ {
+ return a->sign ? -1 : 1;
+ }
+ if (isinf (b))
+ {
+ return b->sign ? 1 : -1;
+ }
+ if (iszero (a) && iszero (b))
+ {
+ return 0;
+ }
+ if (iszero (a))
+ {
+ return b->sign ? 1 : -1;
+ }
+ if (iszero (b))
+ {
+ return a->sign ? -1 : 1;
+ }
+ /* now both are "normal". */
+ if (a->sign != b->sign)
+ {
+ /* opposite signs */
+ return a->sign ? -1 : 1;
+ }
+ /* same sign; exponents? */
+ if (a->normal_exp > b->normal_exp)
+ {
+ return a->sign ? -1 : 1;
+ }
+ if (a->normal_exp < b->normal_exp)
+ {
+ return a->sign ? 1 : -1;
+ }
+ /* same exponents; check size. */
+ if (a->fraction.ll > b->fraction.ll)
+ {
+ return a->sign ? -1 : 1;
+ }
+ if (a->fraction.ll < b->fraction.ll)
+ {
+ return a->sign ? 1 : -1;
+ }
+ /* after all that, they're equal. */
+ return 0;
+}
+#endif
+
+#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
+CMPtype
+compare (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ return __fpcmp_parts (&a, &b);
+}
+#endif /* L_compare_sf || L_compare_df */
+
+/* These should be optimized for their specific tasks someday. */
+
+#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
+CMPtype
+_eq_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return 1; /* false, truth == 0 */
+
+ return __fpcmp_parts (&a, &b) ;
+}
+#endif /* L_eq_sf || L_eq_df */
+
+#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
+CMPtype
+_ne_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return 1; /* true, truth != 0 */
+
+ return __fpcmp_parts (&a, &b) ;
+}
+#endif /* L_ne_sf || L_ne_df */
+
+#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
+CMPtype
+_gt_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return -1; /* false, truth > 0 */
+
+ return __fpcmp_parts (&a, &b);
+}
+#endif /* L_gt_sf || L_gt_df */
+
+#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
+CMPtype
+_ge_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return -1; /* false, truth >= 0 */
+ return __fpcmp_parts (&a, &b) ;
+}
+#endif /* L_ge_sf || L_ge_df */
+
+#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
+CMPtype
+_lt_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return 1; /* false, truth < 0 */
+
+ return __fpcmp_parts (&a, &b);
+}
+#endif /* L_lt_sf || L_lt_df */
+
+#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
+CMPtype
+_le_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ if (isnan (&a) || isnan (&b))
+ return 1; /* false, truth <= 0 */
+
+ return __fpcmp_parts (&a, &b) ;
+}
+#endif /* L_le_sf || L_le_df */
+
+#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
+CMPtype
+_unord_f2 (FLO_type arg_a, FLO_type arg_b)
+{
+ fp_number_type a;
+ fp_number_type b;
+ FLO_union_type au, bu;
+
+ au.value = arg_a;
+ bu.value = arg_b;
+
+ unpack_d (&au, &a);
+ unpack_d (&bu, &b);
+
+ return (isnan (&a) || isnan (&b));
+}
+#endif /* L_unord_sf || L_unord_df */
+
+#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
+FLO_type
+si_to_float (SItype arg_a)
+{
+ fp_number_type in;
+
+ in.class = CLASS_NUMBER;
+ in.sign = arg_a < 0;
+ if (!arg_a)
+ {
+ in.class = CLASS_ZERO;
+ }
+ else
+ {
+ USItype uarg;
+ int shift;
+ in.normal_exp = FRACBITS + NGARDS;
+ if (in.sign)
+ {
+ /* Special case for minint, since there is no +ve integer
+ representation for it */
+ if (arg_a == (- MAX_SI_INT - 1))
+ {
+ return (FLO_type)(- MAX_SI_INT - 1);
+ }
+ uarg = (-arg_a);
+ }
+ else
+ uarg = arg_a;
+
+ in.fraction.ll = uarg;
+ shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
+ if (shift > 0)
+ {
+ in.fraction.ll <<= shift;
+ in.normal_exp -= shift;
+ }
+ }
+ return pack_d (&in);
+}
+#endif /* L_si_to_sf || L_si_to_df */
+
+#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
+FLO_type
+usi_to_float (USItype arg_a)
+{
+ fp_number_type in;
+
+ in.sign = 0;
+ if (!arg_a)
+ {
+ in.class = CLASS_ZERO;
+ }
+ else
+ {
+ int shift;
+ in.class = CLASS_NUMBER;
+ in.normal_exp = FRACBITS + NGARDS;
+ in.fraction.ll = arg_a;
+
+ shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
+ if (shift < 0)
+ {
+ fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
+ in.fraction.ll >>= -shift;
+ in.fraction.ll |= (guard != 0);
+ in.normal_exp -= shift;
+ }
+ else if (shift > 0)
+ {
+ in.fraction.ll <<= shift;
+ in.normal_exp -= shift;
+ }
+ }
+ return pack_d (&in);
+}
+#endif
+
+#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
+SItype
+float_to_si (FLO_type arg_a)
+{
+ fp_number_type a;
+ SItype tmp;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &a);
+
+ if (iszero (&a))
+ return 0;
+ if (isnan (&a))
+ return 0;
+ /* get reasonable MAX_SI_INT... */
+ if (isinf (&a))
+ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
+ /* it is a number, but a small one */
+ if (a.normal_exp < 0)
+ return 0;
+ if (a.normal_exp > BITS_PER_SI - 2)
+ return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
+ tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
+ return a.sign ? (-tmp) : (tmp);
+}
+#endif /* L_sf_to_si || L_df_to_si */
+
+#if defined(L_tf_to_usi)
+USItype
+float_to_usi (FLO_type arg_a)
+{
+ fp_number_type a;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &a);
+
+ if (iszero (&a))
+ return 0;
+ if (isnan (&a))
+ return 0;
+ /* it is a negative number */
+ if (a.sign)
+ return 0;
+ /* get reasonable MAX_USI_INT... */
+ if (isinf (&a))
+ return MAX_USI_INT;
+ /* it is a number, but a small one */
+ if (a.normal_exp < 0)
+ return 0;
+ if (a.normal_exp > BITS_PER_SI - 1)
+ return MAX_USI_INT;
+ else if (a.normal_exp > (FRACBITS + NGARDS))
+ return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
+ else
+ return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
+}
+#endif /* L_tf_to_usi */
+
+#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
+FLO_type
+negate (FLO_type arg_a)
+{
+ fp_number_type a;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &a);
+
+ flip_sign (&a);
+ return pack_d (&a);
+}
+#endif /* L_negate_sf || L_negate_df */
+
+#ifdef FLOAT
+
+#if defined(L_make_sf)
+SFtype
+__make_fp(fp_class_type class,
+ unsigned int sign,
+ int exp,
+ USItype frac)
+{
+ fp_number_type in;
+
+ in.class = class;
+ in.sign = sign;
+ in.normal_exp = exp;
+ in.fraction.ll = frac;
+ return pack_d (&in);
+}
+#endif /* L_make_sf */
+
+#ifndef FLOAT_ONLY
+
+/* This enables one to build an fp library that supports float but not double.
+ Otherwise, we would get an undefined reference to __make_dp.
+ This is needed for some 8-bit ports that can't handle well values that
+ are 8-bytes in size, so we just don't support double for them at all. */
+
+#if defined(L_sf_to_df)
+DFtype
+sf_to_df (SFtype arg_a)
+{
+ fp_number_type in;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ return __make_dp (in.class, in.sign, in.normal_exp,
+ ((UDItype) in.fraction.ll) << F_D_BITOFF);
+}
+#endif /* L_sf_to_df */
+
+#if defined(L_sf_to_tf) && defined(TMODES)
+TFtype
+sf_to_tf (SFtype arg_a)
+{
+ fp_number_type in;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ return __make_tp (in.class, in.sign, in.normal_exp,
+ ((UTItype) in.fraction.ll) << F_T_BITOFF);
+}
+#endif /* L_sf_to_df */
+
+#endif /* ! FLOAT_ONLY */
+#endif /* FLOAT */
+
+#ifndef FLOAT
+
+extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
+
+#if defined(L_make_df)
+DFtype
+__make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
+{
+ fp_number_type in;
+
+ in.class = class;
+ in.sign = sign;
+ in.normal_exp = exp;
+ in.fraction.ll = frac;
+ return pack_d (&in);
+}
+#endif /* L_make_df */
+
+#if defined(L_df_to_sf)
+SFtype
+df_to_sf (DFtype arg_a)
+{
+ fp_number_type in;
+ USItype sffrac;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ sffrac = in.fraction.ll >> F_D_BITOFF;
+
+ /* We set the lowest guard bit in SFFRAC if we discarded any non
+ zero bits. */
+ if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
+ sffrac |= 1;
+
+ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
+}
+#endif /* L_df_to_sf */
+
+#if defined(L_df_to_tf) && defined(TMODES) \
+ && !defined(FLOAT) && !defined(TFLOAT)
+TFtype
+df_to_tf (DFtype arg_a)
+{
+ fp_number_type in;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ return __make_tp (in.class, in.sign, in.normal_exp,
+ ((UTItype) in.fraction.ll) << D_T_BITOFF);
+}
+#endif /* L_sf_to_df */
+
+#ifdef TFLOAT
+#if defined(L_make_tf)
+TFtype
+__make_tp(fp_class_type class,
+ unsigned int sign,
+ int exp,
+ UTItype frac)
+{
+ fp_number_type in;
+
+ in.class = class;
+ in.sign = sign;
+ in.normal_exp = exp;
+ in.fraction.ll = frac;
+ return pack_d (&in);
+}
+#endif /* L_make_tf */
+
+#if defined(L_tf_to_df)
+DFtype
+tf_to_df (TFtype arg_a)
+{
+ fp_number_type in;
+ UDItype sffrac;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ sffrac = in.fraction.ll >> D_T_BITOFF;
+
+ /* We set the lowest guard bit in SFFRAC if we discarded any non
+ zero bits. */
+ if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
+ sffrac |= 1;
+
+ return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
+}
+#endif /* L_tf_to_df */
+
+#if defined(L_tf_to_sf)
+SFtype
+tf_to_sf (TFtype arg_a)
+{
+ fp_number_type in;
+ USItype sffrac;
+ FLO_union_type au;
+
+ au.value = arg_a;
+ unpack_d (&au, &in);
+
+ sffrac = in.fraction.ll >> F_T_BITOFF;
+
+ /* We set the lowest guard bit in SFFRAC if we discarded any non
+ zero bits. */
+ if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
+ sffrac |= 1;
+
+ return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
+}
+#endif /* L_tf_to_sf */
+#endif /* TFLOAT */
+
+#endif /* ! FLOAT */
+#endif /* !EXTENDED_FLOAT_STUBS */
diff --git a/libgcc/fp-bit.h b/libgcc/fp-bit.h
new file mode 100644
index 00000000000..1ae0741d6af
--- /dev/null
+++ b/libgcc/fp-bit.h
@@ -0,0 +1,507 @@
+/* Header file for fp-bit.c. */
+/* Copyright (C) 2000, 2002, 2003, 2006, 2009, 2010, 2011
+ 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 3, or (at your option) any later
+version.
+
+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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_FP_BIT_H
+#define GCC_FP_BIT_H
+
+/* Defining FINE_GRAINED_LIBRARIES allows one to select which routines
+ from this file are compiled via additional -D options.
+
+ This avoids the need to pull in the entire fp emulation library
+ when only a small number of functions are needed.
+
+ If FINE_GRAINED_LIBRARIES is not defined, then compile every
+ suitable routine. */
+#ifndef FINE_GRAINED_LIBRARIES
+#define L_pack_df
+#define L_unpack_df
+#define L_pack_sf
+#define L_unpack_sf
+#define L_addsub_sf
+#define L_addsub_df
+#define L_mul_sf
+#define L_mul_df
+#define L_div_sf
+#define L_div_df
+#define L_fpcmp_parts_sf
+#define L_fpcmp_parts_df
+#define L_compare_sf
+#define L_compare_df
+#define L_eq_sf
+#define L_eq_df
+#define L_ne_sf
+#define L_ne_df
+#define L_gt_sf
+#define L_gt_df
+#define L_ge_sf
+#define L_ge_df
+#define L_lt_sf
+#define L_lt_df
+#define L_le_sf
+#define L_le_df
+#define L_unord_sf
+#define L_unord_df
+#define L_usi_to_sf
+#define L_usi_to_df
+#define L_si_to_sf
+#define L_si_to_df
+#define L_sf_to_si
+#define L_df_to_si
+#define L_f_to_usi
+#define L_df_to_usi
+#define L_negate_sf
+#define L_negate_df
+#define L_make_sf
+#define L_make_df
+#define L_sf_to_df
+#define L_df_to_sf
+#ifdef FLOAT
+#define L_thenan_sf
+#else
+#define L_thenan_df
+#endif
+#endif /* ! FINE_GRAINED_LIBRARIES */
+
+#if __LDBL_MANT_DIG__ == 113 || __LDBL_MANT_DIG__ == 106
+# if defined(TFLOAT) || defined(L_sf_to_tf) || defined(L_df_to_tf)
+# define TMODES
+# endif
+#endif
+
+typedef float SFtype __attribute__ ((mode (SF)));
+typedef float DFtype __attribute__ ((mode (DF)));
+#ifdef TMODES
+typedef float TFtype __attribute__ ((mode (TF)));
+#endif
+
+typedef int HItype __attribute__ ((mode (HI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+#ifdef TMODES
+typedef int TItype __attribute__ ((mode (TI)));
+#endif
+
+/* The type of the result of a floating point comparison. This must
+ match `__libgcc_cmp_return__' in GCC for the target. */
+#ifndef CMPtype
+typedef int CMPtype __attribute__ ((mode (__libgcc_cmp_return__)));
+#endif
+
+typedef unsigned int UHItype __attribute__ ((mode (HI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#ifdef TMODES
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+#endif
+
+#define MAX_USI_INT (~(USItype)0)
+#define MAX_SI_INT ((SItype) (MAX_USI_INT >> 1))
+#define BITS_PER_SI (4 * BITS_PER_UNIT)
+#ifdef TMODES
+#define MAX_UDI_INT (~(UDItype)0)
+#define MAX_DI_INT ((DItype) (MAX_UDI_INT >> 1))
+#define BITS_PER_DI (8 * BITS_PER_UNIT)
+#endif
+
+#ifdef FLOAT_ONLY
+#define NO_DI_MODE
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define FLOAT_BIT_ORDER_MISMATCH
+#endif
+
+#if __BYTE_ORDER__ != __FLOAT_WORD_ORDER__
+#define FLOAT_WORD_ORDER_MISMATCH
+#endif
+
+#ifdef TFLOAT
+# ifndef TMODES
+# error "TFLOAT requires long double to have 113 bits of mantissa"
+# endif
+
+# define PREFIXFPDP tp
+# define PREFIXSFDF tf
+# define NGARDS 10L /* Is this right? */
+# define GARDROUND 0x1ff
+# define GARDMASK 0x3ff
+# define GARDMSB 0x200
+# define FRAC_NBITS 128
+
+# if __LDBL_MANT_DIG__ == 113 /* IEEE quad */
+# define EXPBITS 15
+# define EXPBIAS 16383
+# define EXPMAX (0x7fff)
+# define QUIET_NAN ((TItype)0x8 << 108)
+# define FRACHIGH ((TItype)0x8 << 124)
+# define FRACHIGH2 ((TItype)0xc << 124)
+# define FRACBITS 112
+# endif
+
+# if __LDBL_MANT_DIG__ == 106 /* IBM extended (double+double) */
+# define EXPBITS 11
+# define EXPBIAS 1023
+# define EXPMAX (0x7ff)
+# define QUIET_NAN ((TItype)0x8 << (48 + 64))
+# define FRACHIGH ((TItype)0x8 << 124)
+# define FRACHIGH2 ((TItype)0xc << 124)
+# define FRACBITS 105
+# define HALFFRACBITS 52
+# define HALFSHIFT 64
+# endif
+
+# define pack_d __pack_t
+# define unpack_d __unpack_t
+# define __fpcmp_parts __fpcmp_parts_t
+ typedef UTItype fractype;
+ typedef UDItype halffractype;
+ typedef USItype qrtrfractype;
+#define qrtrfractype qrtrfractype
+ typedef TFtype FLO_type;
+ typedef TItype intfrac;
+#elif defined FLOAT
+# define NGARDS 7L
+# define GARDROUND 0x3f
+# define GARDMASK 0x7f
+# define GARDMSB 0x40
+# define EXPBITS 8
+# define EXPBIAS 127
+# define FRACBITS 23
+# define EXPMAX (0xff)
+# define QUIET_NAN 0x100000L
+# define FRAC_NBITS 32
+# define FRACHIGH 0x80000000L
+# define FRACHIGH2 0xc0000000L
+# define pack_d __pack_f
+# define unpack_d __unpack_f
+# define __fpcmp_parts __fpcmp_parts_f
+ typedef USItype fractype;
+ typedef UHItype halffractype;
+ typedef SFtype FLO_type;
+ typedef SItype intfrac;
+
+#else
+# define PREFIXFPDP dp
+# define PREFIXSFDF df
+# define NGARDS 8L
+# define GARDROUND 0x7f
+# define GARDMASK 0xff
+# define GARDMSB 0x80
+# define EXPBITS 11
+# define EXPBIAS 1023
+# define FRACBITS 52
+# define EXPMAX (0x7ff)
+# define QUIET_NAN 0x8000000000000LL
+# define FRAC_NBITS 64
+# define FRACHIGH 0x8000000000000000LL
+# define FRACHIGH2 0xc000000000000000LL
+# define pack_d __pack_d
+# define unpack_d __unpack_d
+# define __fpcmp_parts __fpcmp_parts_d
+ typedef UDItype fractype;
+ typedef USItype halffractype;
+ typedef DFtype FLO_type;
+ typedef DItype intfrac;
+#endif /* FLOAT */
+
+#ifdef TFLOAT
+# define add __addtf3
+# define sub __subtf3
+# define multiply __multf3
+# define divide __divtf3
+# define compare __cmptf2
+# define _eq_f2 __eqtf2
+# define _ne_f2 __netf2
+# define _gt_f2 __gttf2
+# define _ge_f2 __getf2
+# define _lt_f2 __lttf2
+# define _le_f2 __letf2
+# define _unord_f2 __unordtf2
+# define usi_to_float __floatunsitf
+# define si_to_float __floatsitf
+# define float_to_si __fixtfsi
+# define float_to_usi __fixunstfsi
+# define negate __negtf2
+# define tf_to_sf __trunctfsf2
+# define tf_to_df __trunctfdf2
+#elif defined FLOAT
+# define add __addsf3
+# define sub __subsf3
+# define multiply __mulsf3
+# define divide __divsf3
+# define compare __cmpsf2
+# define _eq_f2 __eqsf2
+# define _ne_f2 __nesf2
+# define _gt_f2 __gtsf2
+# define _ge_f2 __gesf2
+# define _lt_f2 __ltsf2
+# define _le_f2 __lesf2
+# define _unord_f2 __unordsf2
+# define usi_to_float __floatunsisf
+# define si_to_float __floatsisf
+# define float_to_si __fixsfsi
+# define float_to_usi __fixunssfsi
+# define negate __negsf2
+# define sf_to_df __extendsfdf2
+# define sf_to_tf __extendsftf2
+#else
+# define add __adddf3
+# define sub __subdf3
+# define multiply __muldf3
+# define divide __divdf3
+# define compare __cmpdf2
+# define _eq_f2 __eqdf2
+# define _ne_f2 __nedf2
+# define _gt_f2 __gtdf2
+# define _ge_f2 __gedf2
+# define _lt_f2 __ltdf2
+# define _le_f2 __ledf2
+# define _unord_f2 __unorddf2
+# define usi_to_float __floatunsidf
+# define si_to_float __floatsidf
+# define float_to_si __fixdfsi
+# define float_to_usi __fixunsdfsi
+# define negate __negdf2
+# define df_to_sf __truncdfsf2
+# define df_to_tf __extenddftf2
+#endif /* FLOAT */
+
+#ifndef INLINE
+#define INLINE __inline__
+#endif
+
+/* Preserve the sticky-bit when shifting fractions to the right. */
+#define LSHIFT(a, s) { a = (a >> s) | !!(a & (((fractype) 1 << s) - 1)); }
+
+/* numeric parameters */
+/* F_D_BITOFF is the number of bits offset between the MSB of the mantissa
+ of a float and of a double. Assumes there are only two float types.
+ (double::FRAC_BITS+double::NGARDS-(float::FRAC_BITS-float::NGARDS))
+ */
+#define F_D_BITOFF (52+8-(23+7))
+
+#ifdef TMODES
+# define F_T_BITOFF (__LDBL_MANT_DIG__-1+10-(23+7))
+# define D_T_BITOFF (__LDBL_MANT_DIG__-1+10-(52+8))
+#endif
+
+
+#define NORMAL_EXPMIN (-(EXPBIAS)+1)
+#define IMPLICIT_1 ((fractype)1<<(FRACBITS+NGARDS))
+#define IMPLICIT_2 ((fractype)1<<(FRACBITS+1+NGARDS))
+
+/* common types */
+
+typedef enum
+{
+ CLASS_SNAN,
+ CLASS_QNAN,
+ CLASS_ZERO,
+ CLASS_NUMBER,
+ CLASS_INFINITY
+} fp_class_type;
+
+typedef struct
+{
+#ifdef SMALL_MACHINE
+ char class;
+ unsigned char sign;
+ short normal_exp;
+#else
+ fp_class_type class;
+ unsigned int sign;
+ int normal_exp;
+#endif
+
+ union
+ {
+ fractype ll;
+ halffractype l[2];
+ } fraction;
+} fp_number_type;
+
+typedef union
+{
+ FLO_type value;
+ fractype value_raw;
+
+#ifndef FLOAT
+# ifdef qrtrfractype
+ qrtrfractype qwords[4];
+# else
+ halffractype words[2];
+# endif
+#endif
+
+#ifdef FLOAT_BIT_ORDER_MISMATCH
+ struct
+ {
+ fractype fraction:FRACBITS __attribute__ ((packed));
+ unsigned int exp:EXPBITS __attribute__ ((packed));
+ unsigned int sign:1 __attribute__ ((packed));
+ }
+ bits;
+#endif
+
+#ifdef _DEBUG_BITFLOAT
+ struct
+ {
+ unsigned int sign:1 __attribute__ ((packed));
+ unsigned int exp:EXPBITS __attribute__ ((packed));
+ fractype fraction:FRACBITS __attribute__ ((packed));
+ }
+ bits_big_endian;
+
+ struct
+ {
+ fractype fraction:FRACBITS __attribute__ ((packed));
+ unsigned int exp:EXPBITS __attribute__ ((packed));
+ unsigned int sign:1 __attribute__ ((packed));
+ }
+ bits_little_endian;
+#endif
+}
+FLO_union_type;
+
+/* Prototypes. */
+
+#if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
+extern FLO_type pack_d (const fp_number_type *);
+#endif
+
+extern void unpack_d (FLO_union_type *, fp_number_type *);
+
+#if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
+extern FLO_type add (FLO_type, FLO_type);
+extern FLO_type sub (FLO_type, FLO_type);
+#endif
+
+#if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
+extern FLO_type multiply (FLO_type, FLO_type);
+#endif
+
+#if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
+extern FLO_type divide (FLO_type, FLO_type);
+#endif
+
+extern int __fpcmp_parts (fp_number_type *, fp_number_type *);
+
+#if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compare_tf)
+extern CMPtype compare (FLO_type, FLO_type);
+#endif
+
+#if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
+extern CMPtype _eq_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
+extern CMPtype _ne_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
+extern CMPtype _gt_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
+extern CMPtype _ge_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
+extern CMPtype _lt_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
+extern CMPtype _le_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
+extern CMPtype _unord_f2 (FLO_type, FLO_type);
+#endif
+
+#if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
+extern FLO_type si_to_float (SItype);
+#endif
+
+#if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
+extern SItype float_to_si (FLO_type);
+#endif
+
+#if defined(L_tf_to_usi)
+extern USItype float_to_usi (FLO_type);
+#endif
+
+#if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
+extern FLO_type usi_to_float (USItype);
+#endif
+
+#if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
+extern FLO_type negate (FLO_type);
+#endif
+
+#ifdef FLOAT
+#if defined(L_make_sf)
+extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
+#endif
+#ifndef FLOAT_ONLY
+extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype);
+#if defined(L_sf_to_df)
+extern DFtype sf_to_df (SFtype);
+#endif
+#if defined(L_sf_to_tf) && defined(TMODES)
+extern TFtype sf_to_tf (SFtype);
+#endif
+#endif /* ! FLOAT_ONLY */
+#endif /* FLOAT */
+
+#ifndef FLOAT
+extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
+#if defined(L_make_df)
+extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype);
+#endif
+#if defined(L_df_to_sf)
+extern SFtype df_to_sf (DFtype);
+#endif
+#if defined(L_df_to_tf) && defined(TMODES)
+extern TFtype df_to_tf (DFtype);
+#endif
+#endif /* ! FLOAT */
+
+#ifdef TMODES
+extern DFtype __make_dp (fp_class_type, unsigned int, int, UDItype);
+extern TFtype __make_tp (fp_class_type, unsigned int, int, UTItype);
+#ifdef TFLOAT
+#if defined(L_tf_to_sf)
+extern SFtype tf_to_sf (TFtype);
+#endif
+#if defined(L_tf_to_df)
+extern DFtype tf_to_df (TFtype);
+#endif
+#if defined(L_di_to_tf)
+extern TFtype di_to_df (DItype);
+#endif
+#endif /* TFLOAT */
+#endif /* TMODES */
+
+#endif /* ! GCC_FP_BIT_H */