]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
soft-fp: New directory.
authorJoseph Myers <joseph@codesourcery.com>
Tue, 18 Apr 2006 20:50:45 +0000 (21:50 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Tue, 18 Apr 2006 20:50:45 +0000 (21:50 +0100)
* config/soft-fp: New directory.  From glibc.
* config/soft-fp/t-softfp: New.
* config/soft-fp/README: New.
* mklibgcc.in: Handle LIB2FUNCS_EXCLUDE.
* Makefile.in (LIB2FUNCS_EXCLUDE, SFP_MACHINE): New.
(libgcc.mk): Pass LIB2FUNCS_EXCLUDE.
(LIBGCC_DEPS): Add $(SFP_MACHINE).
* config.gcc: Use rs6000/t-fprules-fpbit or
rs6000/t-fprules-softfp and soft-fp/t-softfp together with
rs6000/t-fprules.
* config/rs6000/sfp-machine.h: New.  Based on glibc.
* config/rs6000/t-fprules-fpbit, config/rs6000/t-fprules-softfp:
New.
* config/rs6000/t-fprules: Remove fp-bit rules.
* config/rs6000/t-ppccomm (LIB2FUNCS_EXTRA): Use +=.
* config/rs6000/t-linux64: Likewise.  Remove duplicates from
LIB2FUNCS_EXTRA.  Remove fp-bit rules.
(softfp_wrap_start, softfp_wrap_end): New.

From-SVN: r113056

79 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/config.gcc
gcc/config/rs6000/sfp-machine.h [new file with mode: 0644]
gcc/config/rs6000/t-fprules
gcc/config/rs6000/t-fprules-fpbit [new file with mode: 0644]
gcc/config/rs6000/t-fprules-softfp [new file with mode: 0644]
gcc/config/rs6000/t-linux64
gcc/config/rs6000/t-ppccomm
gcc/config/soft-fp/README [new file with mode: 0644]
gcc/config/soft-fp/adddf3.c [new file with mode: 0644]
gcc/config/soft-fp/addsf3.c [new file with mode: 0644]
gcc/config/soft-fp/addtf3.c [new file with mode: 0644]
gcc/config/soft-fp/divdf3.c [new file with mode: 0644]
gcc/config/soft-fp/divsf3.c [new file with mode: 0644]
gcc/config/soft-fp/divtf3.c [new file with mode: 0644]
gcc/config/soft-fp/double.h [new file with mode: 0644]
gcc/config/soft-fp/eqdf2.c [new file with mode: 0644]
gcc/config/soft-fp/eqsf2.c [new file with mode: 0644]
gcc/config/soft-fp/eqtf2.c [new file with mode: 0644]
gcc/config/soft-fp/extenddftf2.c [new file with mode: 0644]
gcc/config/soft-fp/extended.h [new file with mode: 0644]
gcc/config/soft-fp/extendsfdf2.c [new file with mode: 0644]
gcc/config/soft-fp/extendsftf2.c [new file with mode: 0644]
gcc/config/soft-fp/fixdfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixdfsi.c [new file with mode: 0644]
gcc/config/soft-fp/fixsfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixsfsi.c [new file with mode: 0644]
gcc/config/soft-fp/fixtfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixtfsi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunsdfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunsdfsi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunssfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunssfsi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunstfdi.c [new file with mode: 0644]
gcc/config/soft-fp/fixunstfsi.c [new file with mode: 0644]
gcc/config/soft-fp/floatdidf.c [new file with mode: 0644]
gcc/config/soft-fp/floatdisf.c [new file with mode: 0644]
gcc/config/soft-fp/floatditf.c [new file with mode: 0644]
gcc/config/soft-fp/floatsidf.c [new file with mode: 0644]
gcc/config/soft-fp/floatsisf.c [new file with mode: 0644]
gcc/config/soft-fp/floatsitf.c [new file with mode: 0644]
gcc/config/soft-fp/floatundidf.c [new file with mode: 0644]
gcc/config/soft-fp/floatundisf.c [new file with mode: 0644]
gcc/config/soft-fp/floatunditf.c [new file with mode: 0644]
gcc/config/soft-fp/floatunsidf.c [new file with mode: 0644]
gcc/config/soft-fp/floatunsisf.c [new file with mode: 0644]
gcc/config/soft-fp/floatunsitf.c [new file with mode: 0644]
gcc/config/soft-fp/gedf2.c [new file with mode: 0644]
gcc/config/soft-fp/gesf2.c [new file with mode: 0644]
gcc/config/soft-fp/getf2.c [new file with mode: 0644]
gcc/config/soft-fp/ledf2.c [new file with mode: 0644]
gcc/config/soft-fp/lesf2.c [new file with mode: 0644]
gcc/config/soft-fp/letf2.c [new file with mode: 0644]
gcc/config/soft-fp/muldf3.c [new file with mode: 0644]
gcc/config/soft-fp/mulsf3.c [new file with mode: 0644]
gcc/config/soft-fp/multf3.c [new file with mode: 0644]
gcc/config/soft-fp/negdf2.c [new file with mode: 0644]
gcc/config/soft-fp/negsf2.c [new file with mode: 0644]
gcc/config/soft-fp/negtf2.c [new file with mode: 0644]
gcc/config/soft-fp/op-1.h [new file with mode: 0644]
gcc/config/soft-fp/op-2.h [new file with mode: 0644]
gcc/config/soft-fp/op-4.h [new file with mode: 0644]
gcc/config/soft-fp/op-8.h [new file with mode: 0644]
gcc/config/soft-fp/op-common.h [new file with mode: 0644]
gcc/config/soft-fp/quad.h [new file with mode: 0644]
gcc/config/soft-fp/single.h [new file with mode: 0644]
gcc/config/soft-fp/soft-fp.h [new file with mode: 0644]
gcc/config/soft-fp/subdf3.c [new file with mode: 0644]
gcc/config/soft-fp/subsf3.c [new file with mode: 0644]
gcc/config/soft-fp/subtf3.c [new file with mode: 0644]
gcc/config/soft-fp/t-softfp [new file with mode: 0644]
gcc/config/soft-fp/truncdfsf2.c [new file with mode: 0644]
gcc/config/soft-fp/trunctfdf2.c [new file with mode: 0644]
gcc/config/soft-fp/trunctfsf2.c [new file with mode: 0644]
gcc/config/soft-fp/unorddf2.c [new file with mode: 0644]
gcc/config/soft-fp/unordsf2.c [new file with mode: 0644]
gcc/config/soft-fp/unordtf2.c [new file with mode: 0644]
gcc/mklibgcc.in

index da75e25185930b4437509586e99ff0ec5b5450f5..e6efdcd8939137b7ff6c72b42107fa84fd146a4c 100644 (file)
@@ -1,3 +1,24 @@
+2006-04-18  Joseph S. Myers  <joseph@codesourcery.com>
+
+       * config/soft-fp: New directory.  From glibc.
+       * config/soft-fp/t-softfp: New.
+       * config/soft-fp/README: New.
+       * mklibgcc.in: Handle LIB2FUNCS_EXCLUDE.
+       * Makefile.in (LIB2FUNCS_EXCLUDE, SFP_MACHINE): New.
+       (libgcc.mk): Pass LIB2FUNCS_EXCLUDE.
+       (LIBGCC_DEPS): Add $(SFP_MACHINE).
+       * config.gcc: Use rs6000/t-fprules-fpbit or
+       rs6000/t-fprules-softfp and soft-fp/t-softfp together with
+       rs6000/t-fprules.
+       * config/rs6000/sfp-machine.h: New.  Based on glibc.
+       * config/rs6000/t-fprules-fpbit, config/rs6000/t-fprules-softfp:
+       New.
+       * config/rs6000/t-fprules: Remove fp-bit rules.
+       * config/rs6000/t-ppccomm (LIB2FUNCS_EXTRA): Use +=.
+       * config/rs6000/t-linux64: Likewise.  Remove duplicates from
+       LIB2FUNCS_EXTRA.  Remove fp-bit rules.
+       (softfp_wrap_start, softfp_wrap_end): New.
+
 2006-04-18  DJ Delorie  <dj@redhat.com>
 
        * config/m32c/m32c.h (PTRDIFF_TYPE): Define.
index 68db99cf3ee944f72bbcbf169e404bfe5d73fca8..925ee6c1ddfd25913f98bbd902a3bbedf86141f6 100644 (file)
@@ -611,6 +611,12 @@ LIB2FUNCS_EXTRA =
 # Assembler files should have names ending in `.asm'.
 LIB2FUNCS_STATIC_EXTRA =
 
+# List of functions not to build from libgcc2.c.
+LIB2FUNCS_EXCLUDE =
+
+# Target sfp-machine.h file.
+SFP_MACHINE =
+
 # Program to convert libraries.
 LIBCONVERT =
 
@@ -1398,6 +1404,7 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) specs \
        objext='$(objext)' \
        LIB1ASMFUNCS='$(LIB1ASMFUNCS)' \
        LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
+       LIB2FUNCS_EXCLUDE='$(LIB2FUNCS_EXCLUDE)' \
        LIBGCOV='$(LIBGCOV)' \
        LIB2ADD='$(LIB2ADD)' \
        LIB2ADD_ST='$(LIB2ADD_ST)' \
@@ -1449,7 +1456,7 @@ LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \
        config/dfp-bit.h config/dfp-bit.c \
        $(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \
        $(srcdir)/config/$(LIB1ASMSRC) \
-       $(srcdir)/gcov-io.h $(srcdir)/gcov-io.c gcov-iov.h
+       $(srcdir)/gcov-io.h $(srcdir)/gcov-io.c gcov-iov.h $(SFP_MACHINE)
 
 libgcov.a: libgcc.a; @true
 
index 67a0625b1ddb82523f812e087051f2eca6fe2eac..dbc6debdd9f87c6aa441d21cba03c515f2aedd29 100644 (file)
@@ -1642,7 +1642,7 @@ pdp11-*-*)
        ;;
 # port not yet contributed
 #powerpc-*-openbsd*)
-#      tmake_file="${tmake_file} rs6000/t-fprules "
+#      tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-fprules-fpbit "
 #      extra_headers=
 #      ;;
 powerpc64-*-linux*)
@@ -1654,16 +1654,16 @@ powerpc64-*-linux*)
                tm_file="rs6000/secureplt.h ${tm_file}"
        fi
        extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt"
-       tmake_file="t-dfprules rs6000/t-fprules ${tmake_file} rs6000/t-ppccomm rs6000/t-linux64"
+       tmake_file="t-dfprules rs6000/t-fprules ${tmake_file} rs6000/t-ppccomm rs6000/t-linux64 rs6000/t-fprules-softfp soft-fp/t-softfp"
        ;;
 powerpc64-*-gnu*)
        tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux64.h rs6000/gnu.h"
        extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt"
-       tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-gnu rs6000/t-linux64"
+       tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-gnu rs6000/t-linux64 rs6000/t-fprules-softfp soft-fp/t-softfp"
        ;;
 powerpc-*-beos*)
        tm_file="${tm_file} rs6000/aix.h rs6000/beos.h rs6000/xcoff.h"
-       tmake_file="rs6000/t-fprules rs6000/t-beos"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-beos"
        extra_headers=
        use_fixproto=yes
        ;;
@@ -1685,7 +1685,7 @@ powerpc-*-darwin*)
        ;;
 powerpc*-*-freebsd*)
        tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} rs6000/sysv4.h rs6000/freebsd.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        ;;
 powerpc-*-netbsd*)
@@ -1695,7 +1695,7 @@ powerpc-*-netbsd*)
        ;;
 powerpc-*-chorusos*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h chorus.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        case ${enable_threads} in
          yes | posix)
@@ -1712,48 +1712,48 @@ powerpc-*-eabispe*)
 powerpc-*-eabisimaltivec*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h rs6000/eabialtivec.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
        ;;
 powerpc-*-eabisim*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        ;;
 powerpc-*-elf*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        use_fixproto=yes
        ;;
 powerpc-*-eabialtivec*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabialtivec.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcendian rs6000/t-ppccomm"
        ;;
 powerpc-*-eabi*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        ;;
 powerpc-*-rtems*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h rtems.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-rtems t-rtems rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-rtems t-rtems rs6000/t-ppccomm"
        ;;
 powerpc-*-linux*altivec*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
        ;;
 powerpc-*-linux*spe*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxspe.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
        ;;
 powerpc-*-linux*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="t-dfprules rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
+       tmake_file="t-dfprules rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
        case ${enable_targets}:${cpu_is_64bit} in
            *powerpc64* | all:* | *:yes)
                if test x$cpu_is_64bit = xyes; then
@@ -1774,14 +1774,14 @@ powerpc-*-linux*)
 powerpc-*-gnu-gnualtivec*)
        tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
        extra_options="${extra_options} rs6000/sysv4.opt"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
        if test x$enable_threads = xyes; then
                thread_file='posix'
        fi
        ;;
 powerpc-*-gnu*)
        tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/gnu.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        if test x$enable_threads = xyes; then
                thread_file='posix'
@@ -1791,7 +1791,7 @@ powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
        # We want vxworks.h after rs6000/sysv4.h, which unfortunately
        # means we have to redo the tm_file list from scratch.
        tm_file="rs6000/rs6000.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
-       tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm rs6000/t-vxworks"
+       tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppccomm rs6000/t-vxworks"
        extra_options="${extra_options} rs6000/sysv4.opt"
        extra_headers=ppc-asm.h
        case ${target} in
@@ -1806,7 +1806,7 @@ powerpc-wrs-vxworks|powerpc-wrs-vxworksae)
        ;;
 powerpc-wrs-windiss*)  # Instruction-level simulator for VxWorks.
        tm_file="${tm_file} elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        thread_file=""
        use_fixproto=yes
@@ -1824,39 +1824,39 @@ powerpc-*-lynxos*)
        ;;
 powerpcle-*-sysv*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcos rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcos rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        use_fixproto=yes
        ;;
 powerpcle-*-elf*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        use_fixproto=yes
        ;;
 powerpcle-*-eabisim*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/eabisim.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        ;;
 powerpcle-*-eabi*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        ;;
 powerpc-*-kaos*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        ;;
 powerpcle-*-kaos*)
        tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h"
-       tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-ppcgas rs6000/t-ppccomm"
        extra_options="${extra_options} rs6000/sysv4.opt"
        ;;
 rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
        tm_file="${tm_file} rs6000/aix.h rs6000/aix41.h rs6000/xcoff.h"
-       tmake_file="rs6000/t-fprules rs6000/t-newas"
+       tmake_file="rs6000/t-fprules rs6000/t-fprules-fpbit rs6000/t-newas"
        extra_options="${extra_options} rs6000/aix41.opt"
        use_collect2=yes
        extra_headers=
diff --git a/gcc/config/rs6000/sfp-machine.h b/gcc/config/rs6000/sfp-machine.h
new file mode 100644 (file)
index 0000000..29173e2
--- /dev/null
@@ -0,0 +1,63 @@
+#define _FP_W_TYPE_SIZE                32
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _FP_MUL_MEAT_S(R,X,Y)                          \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)                          \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                          \
+  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* Someone please check this.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+#define        __LITTLE_ENDIAN 1234
+#define        __BIG_ENDIAN    4321
+
+#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+#  error "Both BIG_ENDIAN and LITTLE_ENDIAN defined!"
+# endif
+# define __BYTE_ORDER __BIG_ENDIAN
+#else
+# if defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
+#  define __BYTE_ORDER __LITTLE_ENDIAN
+# else
+#  error "Cannot determine current byte order"
+# endif
+#endif
+
+
+/* Define ALIASNAME as a strong alias for NAME.  */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
index d311d8c31873027d347e527e6d128fad20d558ca..aa686c15b00d154ec4fac85d825717d53b556b0b 100644 (file)
@@ -1,15 +1,3 @@
-# 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
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
-       cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
-       echo '#define FLOAT' > fp-bit.c
-       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
 MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
                          msoft-float=mcpu?403 \
                          msoft-float=mcpu?405 \
diff --git a/gcc/config/rs6000/t-fprules-fpbit b/gcc/config/rs6000/t-fprules-fpbit
new file mode 100644 (file)
index 0000000..a80c1cf
--- /dev/null
@@ -0,0 +1,11 @@
+# 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
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+       cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+       echo '#define FLOAT' > fp-bit.c
+       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
diff --git a/gcc/config/rs6000/t-fprules-softfp b/gcc/config/rs6000/t-fprules-softfp
new file mode 100644 (file)
index 0000000..10b271f
--- /dev/null
@@ -0,0 +1,6 @@
+softfp_float_modes := sf df
+softfp_int_modes := si di
+softfp_extensions := sfdf
+softfp_truncations := dfsf
+softfp_machine_header := rs6000/sfp-machine.h
+softfp_exclude_libgcc2 := y
index 2c30a89892fb45d5672ab1f53b4817cc419ed27f..a2c04f928e6c8de8e3918cba7e1f751e96a4529c 100644 (file)
@@ -1,8 +1,9 @@
 
 #rs6000/t-linux64
 
-LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
+LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
        $(srcdir)/config/rs6000/darwin-ldouble.c
+LIB2FUNCS_EXTRA := $(sort $(LIB2FUNCS_EXTRA))
 
 TARGET_LIBGCC2_CFLAGS += -mno-minimal-toc
 
@@ -14,19 +15,5 @@ MULTILIB_EXCLUSIONS     = m64/!m32/msoft-float
 MULTILIB_OSDIRNAMES    = ../lib64 ../lib nof
 MULTILIB_MATCHES        = $(MULTILIB_MATCHES_FLOAT)
 
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-# fp-bit is only to be used by 32-bit multilibs
-FPBIT = fp-bit32.c
-DPBIT = dp-bit32.c
-
-dp-bit32.c: $(srcdir)/config/fp-bit.c
-       ( echo '#ifndef __powerpc64__'; \
-         cat $(srcdir)/config/fp-bit.c; \
-         echo '#endif' ) > dp-bit32.c
-
-fp-bit32.c: $(srcdir)/config/fp-bit.c
-       ( echo '#ifndef __powerpc64__'; \
-         echo '#define FLOAT'; \
-         cat $(srcdir)/config/fp-bit.c; \
-         echo '#endif' ) > fp-bit32.c
+softfp_wrap_start := '\#ifndef __powerpc64__'
+softfp_wrap_end := '\#endif'
index e58dfe5f68738ab30d04ab282145dc3a8c0650ca..1ca509cd59a2b0c4d823aa1fb5f8d4ec4776480b 100644 (file)
@@ -1,6 +1,6 @@
 # Common support for PowerPC ELF targets (both EABI and SVR4).
 
-LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
+LIB2FUNCS_EXTRA += tramp.S $(srcdir)/config/rs6000/darwin-ldouble.c
 
 # This one can't end up in shared libgcc
 LIB2FUNCS_STATIC_EXTRA = eabi.S
diff --git a/gcc/config/soft-fp/README b/gcc/config/soft-fp/README
new file mode 100644 (file)
index 0000000..870025c
--- /dev/null
@@ -0,0 +1,4 @@
+Except for t-softfp, the files in this directory are part of the GNU C
+Library, not part of GCC.  As described at
+<http://gcc.gnu.org/codingconventions.html>, changes should be made to
+the GNU C Library and the changed files then imported into GCC.
diff --git a/gcc/config/soft-fp/adddf3.c b/gcc/config/soft-fp/adddf3.c
new file mode 100644 (file)
index 0000000..24c03db
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __adddf3(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_D(A, a);
+  FP_UNPACK_SEMIRAW_D(B, b);
+  FP_ADD_D(R, A, B);
+  FP_PACK_SEMIRAW_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/addsf3.c b/gcc/config/soft-fp/addsf3.c
new file mode 100644 (file)
index 0000000..b86991e
--- /dev/null
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __addsf3(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_S(A, a);
+  FP_UNPACK_SEMIRAW_S(B, b);
+  FP_ADD_S(R, A, B);
+  FP_PACK_SEMIRAW_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
diff --git a/gcc/config/soft-fp/addtf3.c b/gcc/config/soft-fp/addtf3.c
new file mode 100644 (file)
index 0000000..49b67f0
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __addtf3(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_Q(A, a);
+  FP_UNPACK_SEMIRAW_Q(B, b);
+  FP_ADD_Q(R, A, B);
+  FP_PACK_SEMIRAW_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/divdf3.c b/gcc/config/soft-fp/divdf3.c
new file mode 100644 (file)
index 0000000..c3bb0d2
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __divdf3(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+  FP_UNPACK_D(B, b);
+  FP_DIV_D(R, A, B);
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/divsf3.c b/gcc/config/soft-fp/divsf3.c
new file mode 100644 (file)
index 0000000..176bb3c
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __divsf3(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+  FP_UNPACK_S(B, b);
+  FP_DIV_S(R, A, B);
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/divtf3.c b/gcc/config/soft-fp/divtf3.c
new file mode 100644 (file)
index 0000000..916fbfe
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __divtf3(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_DIV_Q(R, A, B);
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/double.h b/gcc/config/soft-fp/double.h
new file mode 100644 (file)
index 0000000..c8f4420
--- /dev/null
@@ -0,0 +1,264 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Double Precision
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_D                (2 * _FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_D                _FP_W_TYPE_SIZE
+#endif
+
+#define _FP_FRACBITS_D         53
+#define _FP_FRACXBITS_D                (_FP_FRACTBITS_D - _FP_FRACBITS_D)
+#define _FP_WFRACBITS_D                (_FP_WORKBITS + _FP_FRACBITS_D)
+#define _FP_WFRACXBITS_D       (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
+#define _FP_EXPBITS_D          11
+#define _FP_EXPBIAS_D          1023
+#define _FP_EXPMAX_D           2047
+
+#define _FP_QNANBIT_D          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_D               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_D          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_D               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_D         \
+       ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
+
+typedef float DFtype __attribute__((mode(DF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_D
+{
+  DFtype flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+#else
+    unsigned frac0 : _FP_W_TYPE_SIZE;
+    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_D;
+    unsigned sign  : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)           _FP_DECL(2,X)
+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val)        _FP_UNPACK_RAW_2_P(D,X,val)
+#define FP_PACK_RAW_D(val,X)   _FP_PACK_RAW_2(D,val,X)
+#define FP_PACK_RAW_DP(val,X)          \
+  do {                                 \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(D,val,X);       \
+  } while (0)
+
+#define FP_UNPACK_D(X,val)             \
+  do {                                 \
+    _FP_UNPACK_RAW_2(D,X,val);         \
+    _FP_UNPACK_CANONICAL(D,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_DP(X,val)            \
+  do {                                 \
+    _FP_UNPACK_RAW_2_P(D,X,val);       \
+    _FP_UNPACK_CANONICAL(D,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_D(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_2(D,X,val);         \
+    _FP_UNPACK_SEMIRAW(D,2,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_DP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_2_P(D,X,val);       \
+    _FP_UNPACK_SEMIRAW(D,2,X);         \
+  } while (0)
+
+#define FP_PACK_D(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(D,2,X);         \
+    _FP_PACK_RAW_2(D,val,X);           \
+  } while (0)
+
+#define FP_PACK_DP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(D,2,X);         \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(D,val,X);       \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_D(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(D,2,X);           \
+    _FP_PACK_RAW_2(D,val,X);           \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_DP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(D,2,X);           \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(D,val,X);       \
+  } while (0)
+
+#define FP_ISSIGNAN_D(X)               _FP_ISSIGNAN(D,2,X)
+#define FP_NEG_D(R,X)                  _FP_NEG(D,2,R,X)
+#define FP_ADD_D(R,X,Y)                        _FP_ADD(D,2,R,X,Y)
+#define FP_SUB_D(R,X,Y)                        _FP_SUB(D,2,R,X,Y)
+#define FP_MUL_D(R,X,Y)                        _FP_MUL(D,2,R,X,Y)
+#define FP_DIV_D(R,X,Y)                        _FP_DIV(D,2,R,X,Y)
+#define FP_SQRT_D(R,X)                 _FP_SQRT(D,2,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q)     _FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_D(r,X,Y,un)     _FP_CMP(D,2,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,2,r,X,Y)
+#define FP_CMP_UNORD_D(r,X,Y)  _FP_CMP_UNORD(D,2,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)       _FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)       _FP_FROM_INT(D,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X)     _FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_2(X)
+
+#else
+
+union _FP_UNION_D
+{
+  DFtype flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+#else
+    unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
+    unsigned exp  : _FP_EXPBITS_D;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_D(X)           _FP_DECL(1,X)
+#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
+#define FP_UNPACK_RAW_DP(X,val)        _FP_UNPACK_RAW_1_P(D,X,val)
+#define FP_PACK_RAW_D(val,X)   _FP_PACK_RAW_1(D,val,X)
+#define FP_PACK_RAW_DP(val,X)          \
+  do {                                 \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(D,val,X);       \
+  } while (0)
+
+#define FP_UNPACK_D(X,val)             \
+  do {                                 \
+    _FP_UNPACK_RAW_1(D,X,val);         \
+    _FP_UNPACK_CANONICAL(D,1,X);       \
+  } while (0)
+
+#define FP_UNPACK_DP(X,val)            \
+  do {                                 \
+    _FP_UNPACK_RAW_1_P(D,X,val);       \
+    _FP_UNPACK_CANONICAL(D,1,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_D(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_2(1,X,val);         \
+    _FP_UNPACK_SEMIRAW(D,1,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_DP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_2_P(1,X,val);       \
+    _FP_UNPACK_SEMIRAW(D,1,X);         \
+  } while (0)
+
+#define FP_PACK_D(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(D,1,X);         \
+    _FP_PACK_RAW_1(D,val,X);           \
+  } while (0)
+
+#define FP_PACK_DP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(D,1,X);         \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(D,val,X);       \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_D(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(D,1,X);           \
+    _FP_PACK_RAW_1(D,val,X);           \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_DP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(D,1,X);           \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(D,val,X);       \
+  } while (0)
+
+#define FP_ISSIGNAN_D(X)               _FP_ISSIGNAN(D,1,X)
+#define FP_NEG_D(R,X)                  _FP_NEG(D,1,R,X)
+#define FP_ADD_D(R,X,Y)                        _FP_ADD(D,1,R,X,Y)
+#define FP_SUB_D(R,X,Y)                        _FP_SUB(D,1,R,X,Y)
+#define FP_MUL_D(R,X,Y)                        _FP_MUL(D,1,R,X,Y)
+#define FP_DIV_D(R,X,Y)                        _FP_DIV(D,1,R,X,Y)
+#define FP_SQRT_D(R,X)                 _FP_SQRT(D,1,R,X)
+#define _FP_SQRT_MEAT_D(R,S,T,X,Q)     _FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
+   the target machine.  */
+
+#define FP_CMP_D(r,X,Y,un)     _FP_CMP(D,1,r,X,Y,un)
+#define FP_CMP_EQ_D(r,X,Y)     _FP_CMP_EQ(D,1,r,X,Y)
+#define FP_CMP_UNORD_D(r,X,Y)  _FP_CMP_UNORD(D,1,r,X,Y)
+
+#define FP_TO_INT_D(r,X,rsz,rsg)       _FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_FROM_INT_D(X,r,rs,rt)       _FP_FROM_INT(D,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_D(X)     _FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_D(X) _FP_FRAC_HIGH_1(X)
+
+#endif /* W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/eqdf2.c b/gcc/config/soft-fp/eqdf2.c
new file mode 100644 (file)
index 0000000..efa769e
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __eqdf2(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B);
+  int r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_UNPACK_RAW_D(B, b);
+  FP_CMP_EQ_D(r, A, B);
+  if (r && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__eqdf2, __nedf2);
diff --git a/gcc/config/soft-fp/eqsf2.c b/gcc/config/soft-fp/eqsf2.c
new file mode 100644 (file)
index 0000000..7e01c01
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __eqsf2(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B);
+  int r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_UNPACK_RAW_S(B, b);
+  FP_CMP_EQ_S(r, A, B);
+  if (r && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__eqsf2, __nesf2);
diff --git a/gcc/config/soft-fp/eqtf2.c b/gcc/config/soft-fp/eqtf2.c
new file mode 100644 (file)
index 0000000..fd6ffd1
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __eqtf2(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+  FP_CMP_EQ_Q(r, A, B);
+  if (r && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__eqtf2, __netf2);
diff --git a/gcc/config/soft-fp/extenddftf2.c b/gcc/config/soft-fp/extenddftf2.c
new file mode 100644 (file)
index 0000000..4101639
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE quad
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+TFtype __extenddftf2(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_EXTEND(Q,D,4,2,R,A);
+#else
+  FP_EXTEND(Q,D,2,1,R,A);
+#endif
+  FP_PACK_RAW_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/extended.h b/gcc/config/soft-fp/extended.h
new file mode 100644 (file)
index 0000000..bbf3942
--- /dev/null
@@ -0,0 +1,453 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Extended Precision.
+   Copyright (C) 1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_E         (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_E                (2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_E         64
+#define _FP_FRACXBITS_E                (_FP_FRACTBITS_E - _FP_FRACBITS_E)
+#define _FP_WFRACBITS_E                (_FP_WORKBITS + _FP_FRACBITS_E)
+#define _FP_WFRACXBITS_E       (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
+#define _FP_EXPBITS_E          15
+#define _FP_EXPBIAS_E          16383
+#define _FP_EXPMAX_E           32767
+
+#define _FP_QNANBIT_E          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_E               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_E          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_E               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_E         \
+       ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
+
+typedef float XFtype __attribute__((mode(XF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_E
+{
+   XFtype flt;
+   struct 
+   {
+#if __BYTE_ORDER == __BIG_ENDIAN
+      unsigned long pad1 : _FP_W_TYPE_SIZE;
+      unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+      unsigned long sign : 1;
+      unsigned long exp : _FP_EXPBITS_E;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned exp : _FP_EXPBITS_E;
+      unsigned sign : 1;
+#endif /* not bigendian */
+   } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_E(X)           _FP_DECL(4,X)
+
+#define FP_UNPACK_RAW_E(X, val)                                \
+  do {                                                 \
+    union _FP_UNION_E _flo; _flo.flt = (val);          \
+                                                       \
+    X##_f[2] = 0; X##_f[3] = 0;                                \
+    X##_f[0] = _flo.bits.frac0;                                \
+    X##_f[1] = _flo.bits.frac1;                                \
+    X##_e  = _flo.bits.exp;                            \
+    X##_s  = _flo.bits.sign;                           \
+    if (!X##_e && (X##_f[1] || X##_f[0])               \
+        && !(X##_f[1] & _FP_IMPLBIT_E))                        \
+      {                                                        \
+        X##_e++;                                       \
+        FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+      }                                                        \
+  } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val)                       \
+  do {                                                 \
+    union _FP_UNION_E *_flo =                          \
+    (union _FP_UNION_E *)(val);                                \
+                                                       \
+    X##_f[2] = 0; X##_f[3] = 0;                                \
+    X##_f[0] = _flo->bits.frac0;                       \
+    X##_f[1] = _flo->bits.frac1;                       \
+    X##_e  = _flo->bits.exp;                           \
+    X##_s  = _flo->bits.sign;                          \
+    if (!X##_e && (X##_f[1] || X##_f[0])               \
+        && !(X##_f[1] & _FP_IMPLBIT_E))                        \
+      {                                                        \
+        X##_e++;                                       \
+        FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+      }                                                        \
+  } while (0)
+
+#define FP_PACK_RAW_E(val, X)                          \
+  do {                                                 \
+    union _FP_UNION_E _flo;                            \
+                                                       \
+    if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;              \
+    else X##_f[1] &= ~(_FP_IMPLBIT_E);                 \
+    _flo.bits.frac0 = X##_f[0];                                \
+    _flo.bits.frac1 = X##_f[1];                                \
+    _flo.bits.exp   = X##_e;                           \
+    _flo.bits.sign  = X##_s;                           \
+                                                       \
+    (val) = _flo.flt;                                  \
+  } while (0)
+
+#define FP_PACK_RAW_EP(val, X)                         \
+  do {                                                 \
+    if (!FP_INHIBIT_RESULTS)                           \
+      {                                                        \
+       union _FP_UNION_E *_flo =                       \
+         (union _FP_UNION_E *)(val);                   \
+                                                       \
+       if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;           \
+       else X##_f[1] &= ~(_FP_IMPLBIT_E);              \
+       _flo->bits.frac0 = X##_f[0];                    \
+       _flo->bits.frac1 = X##_f[1];                    \
+       _flo->bits.exp   = X##_e;                       \
+       _flo->bits.sign  = X##_s;                       \
+      }                                                        \
+  } while (0)
+
+#define FP_UNPACK_E(X,val)             \
+  do {                                 \
+    FP_UNPACK_RAW_E(X,val);            \
+    _FP_UNPACK_CANONICAL(E,4,X);       \
+  } while (0)
+
+#define FP_UNPACK_EP(X,val)            \
+  do {                                 \
+    FP_UNPACK_RAW_EP(X,val);           \
+    _FP_UNPACK_CANONICAL(E,4,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_E(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_E(X,val);           \
+    _FP_UNPACK_SEMIRAW(E,4,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_EP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_EP(X,val);          \
+    _FP_UNPACK_SEMIRAW(E,4,X);         \
+  } while (0)
+
+#define FP_PACK_E(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(E,4,X);         \
+    FP_PACK_RAW_E(val,X);              \
+  } while (0)
+
+#define FP_PACK_EP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(E,4,X);         \
+    FP_PACK_RAW_EP(val,X);             \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_E(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(E,4,X);           \
+    _FP_PACK_RAW_E(val,X);             \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_EP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(E,4,X);           \
+    _FP_PACK_RAW_EP(val,X);            \
+  } while (0)
+
+#define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN(E,4,X)
+#define FP_NEG_E(R,X)          _FP_NEG(E,4,R,X)
+#define FP_ADD_E(R,X,Y)                _FP_ADD(E,4,R,X,Y)
+#define FP_SUB_E(R,X,Y)                _FP_SUB(E,4,R,X,Y)
+#define FP_MUL_E(R,X,Y)                _FP_MUL(E,4,R,X,Y)
+#define FP_DIV_E(R,X,Y)                _FP_DIV(E,4,R,X,Y)
+#define FP_SQRT_E(R,X)         _FP_SQRT(E,4,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * This has special _E version because standard _4 square
+ * root would not work (it has to start normally with the
+ * second word and not the first), but as we have to do it
+ * anyway, we optimize it by doing most of the calculations
+ * in two UWtype registers instead of four.
+ */
+#define _FP_SQRT_MEAT_E(R, S, T, X, q)                 \
+  do {                                                 \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                \
+    _FP_FRAC_SRL_4(X, (_FP_WORKBITS));                 \
+    while (q)                                          \
+      {                                                        \
+       T##_f[1] = S##_f[1] + q;                        \
+       if (T##_f[1] <= X##_f[1])                       \
+         {                                             \
+           S##_f[1] = T##_f[1] + q;                    \
+           X##_f[1] -= T##_f[1];                       \
+           R##_f[1] += q;                              \
+         }                                             \
+       _FP_FRAC_SLL_2(X, 1);                           \
+       q >>= 1;                                        \
+      }                                                        \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                \
+    while (q)                                          \
+      {                                                        \
+       T##_f[0] = S##_f[0] + q;                        \
+       T##_f[1] = S##_f[1];                            \
+       if (T##_f[1] < X##_f[1] ||                      \
+           (T##_f[1] == X##_f[1] &&                    \
+            T##_f[0] <= X##_f[0]))                     \
+         {                                             \
+           S##_f[0] = T##_f[0] + q;                    \
+           S##_f[1] += (T##_f[0] > S##_f[0]);          \
+           _FP_FRAC_DEC_2(X, T);                       \
+           R##_f[0] += q;                              \
+         }                                             \
+       _FP_FRAC_SLL_2(X, 1);                           \
+       q >>= 1;                                        \
+      }                                                        \
+    _FP_FRAC_SLL_4(R, (_FP_WORKBITS));                 \
+    if (X##_f[0] | X##_f[1])                           \
+      {                                                        \
+       if (S##_f[1] < X##_f[1] ||                      \
+           (S##_f[1] == X##_f[1] &&                    \
+            S##_f[0] < X##_f[0]))                      \
+         R##_f[0] |= _FP_WORK_ROUND;                   \
+       R##_f[0] |= _FP_WORK_STICKY;                    \
+      }                                                        \
+  } while (0)
+
+#define FP_CMP_E(r,X,Y,un)     _FP_CMP(E,4,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y)     _FP_CMP_EQ(E,4,r,X,Y)
+#define FP_CMP_UNORD_E(r,X,Y)  _FP_CMP_UNORD(E,4,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg)       _FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt)       _FP_FROM_INT(E,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X)     (X##_f[2])
+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
+
+#else   /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_E
+{
+  XFtype flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned long pad : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_E;
+    unsigned long frac : _FP_W_TYPE_SIZE;
+#else
+    unsigned long frac : _FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_E;
+    unsigned sign  : 1;
+#endif
+  } bits;
+};
+
+#define FP_DECL_E(X)           _FP_DECL(2,X)
+
+#define FP_UNPACK_RAW_E(X, val)                                        \
+  do {                                                         \
+    union _FP_UNION_E _flo; _flo.flt = (val);                  \
+                                                               \
+    X##_f0 = _flo.bits.frac;                                   \
+    X##_f1 = 0;                                                        \
+    X##_e = _flo.bits.exp;                                     \
+    X##_s = _flo.bits.sign;                                    \
+    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))         \
+      {                                                                \
+        X##_e++;                                               \
+        FP_SET_EXCEPTION(FP_EX_DENORM);                                \
+      }                                                                \
+  } while (0)
+
+#define FP_UNPACK_RAW_EP(X, val)                               \
+  do {                                                         \
+    union _FP_UNION_E *_flo =                                  \
+      (union _FP_UNION_E *)(val);                              \
+                                                               \
+    X##_f0 = _flo->bits.frac;                                  \
+    X##_f1 = 0;                                                        \
+    X##_e = _flo->bits.exp;                                    \
+    X##_s = _flo->bits.sign;                                   \
+    if (!X##_e && X##_f0 && !(X##_f0 & _FP_IMPLBIT_E))         \
+      {                                                                \
+        X##_e++;                                               \
+        FP_SET_EXCEPTION(FP_EX_DENORM);                                \
+      }                                                                \
+  } while (0)
+
+#define FP_PACK_RAW_E(val, X)                                  \
+  do {                                                         \
+    union _FP_UNION_E _flo;                                    \
+                                                               \
+    if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                                \
+    else X##_f0 &= ~(_FP_IMPLBIT_E);                           \
+    _flo.bits.frac = X##_f0;                                   \
+    _flo.bits.exp  = X##_e;                                    \
+    _flo.bits.sign = X##_s;                                    \
+                                                               \
+    (val) = _flo.flt;                                          \
+  } while (0)
+
+#define FP_PACK_RAW_EP(fs, val, X)                             \
+  do {                                                         \
+    if (!FP_INHIBIT_RESULTS)                                   \
+      {                                                                \
+       union _FP_UNION_E *_flo =                               \
+         (union _FP_UNION_E *)(val);                           \
+                                                               \
+       if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                     \
+       else X##_f0 &= ~(_FP_IMPLBIT_E);                        \
+       _flo->bits.frac = X##_f0;                               \
+       _flo->bits.exp  = X##_e;                                \
+       _flo->bits.sign = X##_s;                                \
+      }                                                                \
+  } while (0)
+
+
+#define FP_UNPACK_E(X,val)             \
+  do {                                 \
+    FP_UNPACK_RAW_E(X,val);            \
+    _FP_UNPACK_CANONICAL(E,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_EP(X,val)            \
+  do {                                 \
+    FP_UNPACK_RAW_EP(X,val);           \
+    _FP_UNPACK_CANONICAL(E,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_E(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_E(X,val);           \
+    _FP_UNPACK_SEMIRAW(E,2,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_EP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_EP(X,val);          \
+    _FP_UNPACK_SEMIRAW(E,2,X);         \
+  } while (0)
+
+#define FP_PACK_E(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(E,2,X);         \
+    FP_PACK_RAW_E(val,X);              \
+  } while (0)
+
+#define FP_PACK_EP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(E,2,X);         \
+    FP_PACK_RAW_EP(val,X);             \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_E(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(E,2,X);           \
+    _FP_PACK_RAW_E(val,X);             \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_EP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(E,2,X);           \
+    _FP_PACK_RAW_EP(val,X);            \
+  } while (0)
+
+#define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN(E,2,X)
+#define FP_NEG_E(R,X)          _FP_NEG(E,2,R,X)
+#define FP_ADD_E(R,X,Y)                _FP_ADD(E,2,R,X,Y)
+#define FP_SUB_E(R,X,Y)                _FP_SUB(E,2,R,X,Y)
+#define FP_MUL_E(R,X,Y)                _FP_MUL(E,2,R,X,Y)
+#define FP_DIV_E(R,X,Y)                _FP_DIV(E,2,R,X,Y)
+#define FP_SQRT_E(R,X)         _FP_SQRT(E,2,R,X)
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ * We optimize it by doing most of the calculations
+ * in one UWtype registers instead of two, although we don't
+ * have to.
+ */
+#define _FP_SQRT_MEAT_E(R, S, T, X, q)                 \
+  do {                                                 \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                \
+    _FP_FRAC_SRL_2(X, (_FP_WORKBITS));                 \
+    while (q)                                          \
+      {                                                        \
+        T##_f0 = S##_f0 + q;                           \
+        if (T##_f0 <= X##_f0)                          \
+          {                                            \
+            S##_f0 = T##_f0 + q;                       \
+            X##_f0 -= T##_f0;                          \
+            R##_f0 += q;                               \
+          }                                            \
+        _FP_FRAC_SLL_1(X, 1);                          \
+        q >>= 1;                                       \
+      }                                                        \
+    _FP_FRAC_SLL_2(R, (_FP_WORKBITS));                 \
+    if (X##_f0)                                                \
+      {                                                        \
+       if (S##_f0 < X##_f0)                            \
+         R##_f0 |= _FP_WORK_ROUND;                     \
+       R##_f0 |= _FP_WORK_STICKY;                      \
+      }                                                        \
+  } while (0)
+#define FP_CMP_E(r,X,Y,un)     _FP_CMP(E,2,r,X,Y,un)
+#define FP_CMP_EQ_E(r,X,Y)     _FP_CMP_EQ(E,2,r,X,Y)
+#define FP_CMP_UNORD_E(r,X,Y)  _FP_CMP_UNORD(E,2,r,X,Y)
+
+#define FP_TO_INT_E(r,X,rsz,rsg)       _FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_FROM_INT_E(X,r,rs,rt)       _FP_FROM_INT(E,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_E(X)     (X##_f1)
+#define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/extendsfdf2.c b/gcc/config/soft-fp/extendsfdf2.c
new file mode 100644 (file)
index 0000000..fba22d5
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE double
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+DFtype __extendsfdf2(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_S(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_EXTEND(D,S,2,1,R,A);
+#else
+  FP_EXTEND(D,S,1,1,R,A);
+#endif
+  FP_PACK_RAW_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/extendsftf2.c b/gcc/config/soft-fp/extendsftf2.c
new file mode 100644 (file)
index 0000000..c43cf1e
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE quad
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+TFtype __extendsftf2(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_EXTEND(Q,S,4,1,R,A);
+#else
+  FP_EXTEND(Q,S,2,1,R,A);
+#endif
+  FP_PACK_RAW_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixdfdi.c b/gcc/config/soft-fp/fixdfdi.c
new file mode 100644 (file)
index 0000000..fdfe35a
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DItype __fixdfdi(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_TO_INT_D(r, A, DI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixdfsi.c b/gcc/config/soft-fp/fixdfsi.c
new file mode 100644 (file)
index 0000000..a05f3e3
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+SItype __fixdfsi(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  USItype r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_TO_INT_D(r, A, SI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixsfdi.c b/gcc/config/soft-fp/fixsfdi.c
new file mode 100644 (file)
index 0000000..384d9bd
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+DItype __fixsfdi(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_TO_INT_S(r, A, DI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixsfsi.c b/gcc/config/soft-fp/fixsfsi.c
new file mode 100644 (file)
index 0000000..1d40ed0
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SItype __fixsfsi(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  USItype r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_TO_INT_S(r, A, SI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixtfdi.c b/gcc/config/soft-fp/fixtfdi.c
new file mode 100644 (file)
index 0000000..ea10ce2
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+DItype __fixtfdi(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_TO_INT_Q(r, A, DI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixtfsi.c b/gcc/config/soft-fp/fixtfsi.c
new file mode 100644 (file)
index 0000000..eb71038
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+SItype __fixtfsi(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  USItype r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_TO_INT_Q(r, A, SI_BITS, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunsdfdi.c b/gcc/config/soft-fp/fixunsdfdi.c
new file mode 100644 (file)
index 0000000..d85198f
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+UDItype __fixunsdfdi(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_TO_INT_D(r, A, DI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunsdfsi.c b/gcc/config/soft-fp/fixunsdfsi.c
new file mode 100644 (file)
index 0000000..492ffde
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+USItype __fixunsdfsi(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  USItype r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_TO_INT_D(r, A, SI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunssfdi.c b/gcc/config/soft-fp/fixunssfdi.c
new file mode 100644 (file)
index 0000000..5484153
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+UDItype __fixunssfdi(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_TO_INT_S(r, A, DI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunssfsi.c b/gcc/config/soft-fp/fixunssfsi.c
new file mode 100644 (file)
index 0000000..ac9d4b9
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+USItype __fixunssfsi(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  USItype r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_TO_INT_S(r, A, SI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunstfdi.c b/gcc/config/soft-fp/fixunstfdi.c
new file mode 100644 (file)
index 0000000..86f1fc8
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+UDItype __fixunstfdi(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  UDItype r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_TO_INT_Q(r, A, DI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/fixunstfsi.c b/gcc/config/soft-fp/fixunstfsi.c
new file mode 100644 (file)
index 0000000..e0335da
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+USItype __fixunstfsi(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  USItype r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_TO_INT_Q(r, A, SI_BITS, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/floatdidf.c b/gcc/config/soft-fp/floatdidf.c
new file mode 100644 (file)
index 0000000..21e9fb1
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE double
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __floatdidf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  DFtype a;
+
+  FP_FROM_INT_D(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatdisf.c b/gcc/config/soft-fp/floatdisf.c
new file mode 100644 (file)
index 0000000..ee57915
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE single
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __floatdisf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  SFtype a;
+
+  FP_FROM_INT_S(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatditf.c b/gcc/config/soft-fp/floatditf.c
new file mode 100644 (file)
index 0000000..564800b
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE quad
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __floatditf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  TFtype a;
+
+  FP_FROM_INT_Q(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatsidf.c b/gcc/config/soft-fp/floatsidf.c
new file mode 100644 (file)
index 0000000..b6d5f8d
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE double
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __floatsidf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  DFtype a;
+
+  FP_FROM_INT_D(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatsisf.c b/gcc/config/soft-fp/floatsisf.c
new file mode 100644 (file)
index 0000000..76217fe
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE single
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __floatsisf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  SFtype a;
+
+  FP_FROM_INT_S(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatsitf.c b/gcc/config/soft-fp/floatsitf.c
new file mode 100644 (file)
index 0000000..8c3d9cc
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE quad
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __floatsitf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  TFtype a;
+
+  FP_FROM_INT_Q(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatundidf.c b/gcc/config/soft-fp/floatundidf.c
new file mode 100644 (file)
index 0000000..2169a3f
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 64bit unsigned integer to IEEE double
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double
+__floatundidf(UDItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  DFtype a;
+
+  FP_FROM_INT_D(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatundisf.c b/gcc/config/soft-fp/floatundisf.c
new file mode 100644 (file)
index 0000000..5f08764
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 64bit unsigned integer to IEEE single
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float
+__floatundisf(UDItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  SFtype a;
+
+  FP_FROM_INT_S(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatunditf.c b/gcc/config/soft-fp/floatunditf.c
new file mode 100644 (file)
index 0000000..ab357f0
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 64bit unsigned integer to IEEE quad
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype
+__floatunditf(UDItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  TFtype a;
+
+  FP_FROM_INT_Q(A, i, DI_BITS, UDItype);
+  FP_PACK_RAW_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatunsidf.c b/gcc/config/soft-fp/floatunsidf.c
new file mode 100644 (file)
index 0000000..97b488a
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 32bit unsigned integer to IEEE double
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double
+__floatunsidf(USItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  DFtype a;
+
+  FP_FROM_INT_D(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatunsisf.c b/gcc/config/soft-fp/floatunsisf.c
new file mode 100644 (file)
index 0000000..2ec16ba
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 32bit unsigned integer to IEEE single
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float
+__floatunsisf(USItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  SFtype a;
+
+  FP_FROM_INT_S(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/floatunsitf.c b/gcc/config/soft-fp/floatunsitf.c
new file mode 100644 (file)
index 0000000..c993716
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Convert a 32bit unsigned integer to IEEE quad
+   Copyright (C) 1997,1999, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype
+__floatunsitf(USItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  TFtype a;
+
+  FP_FROM_INT_Q(A, i, SI_BITS, USItype);
+  FP_PACK_RAW_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/gcc/config/soft-fp/gedf2.c b/gcc/config/soft-fp/gedf2.c
new file mode 100644 (file)
index 0000000..e0dc862
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __gedf2(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B);
+  int r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_UNPACK_RAW_D(B, b);
+  FP_CMP_D(r, A, B, -2);
+  if (r == -2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__gedf2, __gtdf2);
diff --git a/gcc/config/soft-fp/gesf2.c b/gcc/config/soft-fp/gesf2.c
new file mode 100644 (file)
index 0000000..d1f3ba2
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __gesf2(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B);
+  int r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_UNPACK_RAW_S(B, b);
+  FP_CMP_S(r, A, B, -2);
+  if (r == -2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__gesf2, __gtsf2);
diff --git a/gcc/config/soft-fp/getf2.c b/gcc/config/soft-fp/getf2.c
new file mode 100644 (file)
index 0000000..82ff283
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, -2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __getf2(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+  FP_CMP_Q(r, A, B, -2);
+  if (r == -2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__getf2, __gttf2);
diff --git a/gcc/config/soft-fp/ledf2.c b/gcc/config/soft-fp/ledf2.c
new file mode 100644 (file)
index 0000000..528a981
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __ledf2(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B);
+  int r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_UNPACK_RAW_D(B, b);
+  FP_CMP_D(r, A, B, 2);
+  if (r == 2 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__ledf2, __ltdf2);
diff --git a/gcc/config/soft-fp/lesf2.c b/gcc/config/soft-fp/lesf2.c
new file mode 100644 (file)
index 0000000..c564bd9
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __lesf2(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B);
+  int r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_UNPACK_RAW_S(B, b);
+  FP_CMP_S(r, A, B, 2);
+  if (r == 2 && (FP_ISSIGNAN_S(A) || FP_ISSIGNAN_S(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__lesf2, __ltsf2);
diff --git a/gcc/config/soft-fp/letf2.c b/gcc/config/soft-fp/letf2.c
new file mode 100644 (file)
index 0000000..35e03aa
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 iff a > b, 2 iff a ? b, -1 iff a < b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __letf2(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+  FP_CMP_Q(r, A, B, 2);
+  if (r == 2 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+strong_alias(__letf2, __lttf2);
diff --git a/gcc/config/soft-fp/muldf3.c b/gcc/config/soft-fp/muldf3.c
new file mode 100644 (file)
index 0000000..7eb2015
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __muldf3(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+  FP_UNPACK_D(B, b);
+  FP_MUL_D(R, A, B);
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/mulsf3.c b/gcc/config/soft-fp/mulsf3.c
new file mode 100644 (file)
index 0000000..5df4406
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __mulsf3(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+  FP_UNPACK_S(B, b);
+  FP_MUL_S(R, A, B);
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/multf3.c b/gcc/config/soft-fp/multf3.c
new file mode 100644 (file)
index 0000000..0abab6d
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __multf3(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_MUL_Q(R, A, B);
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/negdf2.c b/gcc/config/soft-fp/negdf2.c
new file mode 100644 (file)
index 0000000..54869e9
--- /dev/null
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __negdf2(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(R);
+  DFtype r;
+
+  FP_UNPACK_D(A, a);
+  FP_NEG_D(R, A);
+  FP_PACK_D(r, R);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/negsf2.c b/gcc/config/soft-fp/negsf2.c
new file mode 100644 (file)
index 0000000..bf5db7a
--- /dev/null
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __negsf2(SFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(R);
+  SFtype r;
+
+  FP_UNPACK_S(A, a);
+  FP_NEG_S(R, A);
+  FP_PACK_S(r, R);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/negtf2.c b/gcc/config/soft-fp/negtf2.c
new file mode 100644 (file)
index 0000000..5524c82
--- /dev/null
@@ -0,0 +1,48 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __negtf2(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(R);
+  TFtype r;
+
+  FP_UNPACK_Q(A, a);
+  FP_NEG_Q(R, A);
+  FP_PACK_Q(r, R);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/op-1.h b/gcc/config/soft-fp/op-1.h
new file mode 100644 (file)
index 0000000..35cd0ba
--- /dev/null
@@ -0,0 +1,302 @@
+/* Software floating-point emulation.
+   Basic one-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define _FP_FRAC_DECL_1(X)     _FP_W_TYPE X##_f
+#define _FP_FRAC_COPY_1(D,S)   (D##_f = S##_f)
+#define _FP_FRAC_SET_1(X,I)    (X##_f = I)
+#define _FP_FRAC_HIGH_1(X)     (X##_f)
+#define _FP_FRAC_LOW_1(X)      (X##_f)
+#define _FP_FRAC_WORD_1(X,w)   (X##_f)
+
+#define _FP_FRAC_ADDI_1(X,I)   (X##_f += I)
+#define _FP_FRAC_SLL_1(X,N)                    \
+  do {                                         \
+    if (__builtin_constant_p(N) && (N) == 1)   \
+      X##_f += X##_f;                          \
+    else                                       \
+      X##_f <<= (N);                           \
+  } while (0)
+#define _FP_FRAC_SRL_1(X,N)    (X##_f >>= N)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRST_1(X,S,N,sz)      __FP_FRAC_SRST_1(X##_f, S, N, sz)
+#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
+
+#define __FP_FRAC_SRST_1(X,S,N,sz)                     \
+do {                                                   \
+  S = (__builtin_constant_p(N) && (N) == 1             \
+       ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \
+  X = X >> (N);                                                \
+} while (0)
+
+#define __FP_FRAC_SRS_1(X,N,sz)                                                \
+   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1               \
+                    ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
+
+#define _FP_FRAC_ADD_1(R,X,Y)  (R##_f = X##_f + Y##_f)
+#define _FP_FRAC_SUB_1(R,X,Y)  (R##_f = X##_f - Y##_f)
+#define _FP_FRAC_DEC_1(X,Y)    (X##_f -= Y##_f)
+#define _FP_FRAC_CLZ_1(z, X)   __FP_CLZ(z, X##_f)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_1(X)     ((_FP_WS_TYPE)X##_f < 0)
+#define _FP_FRAC_ZEROP_1(X)    (X##_f == 0)
+#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_1(fs,X)   (X##_f &= ~_FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_1(X, Y)    (X##_f == Y##_f)
+#define _FP_FRAC_GE_1(X, Y)    (X##_f >= Y##_f)
+#define _FP_FRAC_GT_1(X, Y)    (X##_f > Y##_f)
+
+#define _FP_ZEROFRAC_1         0
+#define _FP_MINFRAC_1          1
+#define _FP_MAXFRAC_1          (~(_FP_WS_TYPE)0)
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_1(fs, X, val)                           \
+  do {                                                         \
+    union _FP_UNION_##fs _flo; _flo.flt = (val);               \
+                                                               \
+    X##_f = _flo.bits.frac;                                    \
+    X##_e = _flo.bits.exp;                                     \
+    X##_s = _flo.bits.sign;                                    \
+  } while (0)
+
+#define _FP_UNPACK_RAW_1_P(fs, X, val)                         \
+  do {                                                         \
+    union _FP_UNION_##fs *_flo =                               \
+      (union _FP_UNION_##fs *)(val);                           \
+                                                               \
+    X##_f = _flo->bits.frac;                                   \
+    X##_e = _flo->bits.exp;                                    \
+    X##_s = _flo->bits.sign;                                   \
+  } while (0)
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_1(fs, val, X)                             \
+  do {                                                         \
+    union _FP_UNION_##fs _flo;                                 \
+                                                               \
+    _flo.bits.frac = X##_f;                                    \
+    _flo.bits.exp  = X##_e;                                    \
+    _flo.bits.sign = X##_s;                                    \
+                                                               \
+    (val) = _flo.flt;                                          \
+  } while (0)
+
+#define _FP_PACK_RAW_1_P(fs, val, X)                           \
+  do {                                                         \
+    union _FP_UNION_##fs *_flo =                               \
+      (union _FP_UNION_##fs *)(val);                           \
+                                                               \
+    _flo->bits.frac = X##_f;                                   \
+    _flo->bits.exp  = X##_e;                                   \
+    _flo->bits.sign = X##_s;                                   \
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   multiplication immediately.  */
+
+#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)                         \
+  do {                                                                 \
+    R##_f = X##_f * Y##_f;                                             \
+    /* Normalize since we know where the msb of the multiplicands      \
+       were (bit B), we know that the msb of the of the product is     \
+       at either 2B or 2B-1.  */                                       \
+    _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits);                       \
+  } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)                  \
+  do {                                                                 \
+    _FP_W_TYPE _Z_f0, _Z_f1;                                           \
+    doit(_Z_f1, _Z_f0, X##_f, Y##_f);                                  \
+    /* Normalize since we know where the msb of the multiplicands      \
+       were (bit B), we know that the msb of the of the product is     \
+       at either 2B or 2B-1.  */                                       \
+    _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits);                      \
+    R##_f = _Z_f0;                                                     \
+  } while (0)
+
+/* Finally, a simple widening multiply algorithm.  What fun!  */
+
+#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)                                \
+  do {                                                                 \
+    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;         \
+                                                                       \
+    /* split the words in half */                                      \
+    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);                                        \
+    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);                \
+    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);                                        \
+    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);                \
+                                                                       \
+    /* multiply the pieces */                                          \
+    _z_f0 = _xl * _yl;                                                 \
+    _a_f0 = _xh * _yl;                                                 \
+    _a_f1 = _xl * _yh;                                                 \
+    _z_f1 = _xh * _yh;                                                 \
+                                                                       \
+    /* reassemble into two full words */                               \
+    if ((_a_f0 += _a_f1) < _a_f1)                                      \
+      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);                   \
+    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);                              \
+    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);                              \
+    _FP_FRAC_ADD_2(_z, _z, _a);                                                \
+                                                                       \
+    /* normalize */                                                    \
+    _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits);                    \
+    R##_f = _z_f0;                                                     \
+  } while (0)
+
+
+/*
+ * Division algorithms:
+ */
+
+/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
+   division immediately.  Give this macro either _FP_DIV_HELP_imm for
+   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
+   choose will depend on what the compiler does with divrem4.  */
+
+#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)          \
+  do {                                                 \
+    _FP_W_TYPE _q, _r;                                 \
+    X##_f <<= (X##_f < Y##_f                           \
+              ? R##_e--, _FP_WFRACBITS_##fs            \
+              : _FP_WFRACBITS_##fs - 1);               \
+    doit(_q, _r, X##_f, Y##_f);                                \
+    R##_f = _q | (_r != 0);                            \
+  } while (0)
+
+/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
+   that may be useful in this situation.  This first is for a primitive
+   that requires normalization, the second for one that does not.  Look
+   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
+
+#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)                          \
+  do {                                                                 \
+    _FP_W_TYPE _nh, _nl, _q, _r, _y;                                   \
+                                                                       \
+    /* Normalize Y -- i.e. make the most significant bit set.  */      \
+    _y = Y##_f << _FP_WFRACXBITS_##fs;                                 \
+                                                                       \
+    /* Shift X op correspondingly high, that is, up one full word.  */ \
+    if (X##_f < Y##_f)                                                 \
+      {                                                                        \
+       R##_e--;                                                        \
+       _nl = 0;                                                        \
+       _nh = X##_f;                                                    \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       _nl = X##_f << (_FP_W_TYPE_SIZE - 1);                           \
+       _nh = X##_f >> 1;                                               \
+      }                                                                        \
+                                                                       \
+    udiv_qrnnd(_q, _r, _nh, _nl, _y);                                  \
+    R##_f = _q | (_r != 0);                                            \
+  } while (0)
+
+#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)               \
+  do {                                                 \
+    _FP_W_TYPE _nh, _nl, _q, _r;                       \
+    if (X##_f < Y##_f)                                 \
+      {                                                        \
+       R##_e--;                                        \
+       _nl = X##_f << _FP_WFRACBITS_##fs;              \
+       _nh = X##_f >> _FP_WFRACXBITS_##fs;             \
+      }                                                        \
+    else                                               \
+      {                                                        \
+       _nl = X##_f << (_FP_WFRACBITS_##fs - 1);        \
+       _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);       \
+      }                                                        \
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);               \
+    R##_f = _q | (_r != 0);                            \
+  } while (0)
+  
+  
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+#define _FP_SQRT_MEAT_1(R, S, T, X, q)                 \
+  do {                                                 \
+    while (q != _FP_WORK_ROUND)                                \
+      {                                                        \
+        T##_f = S##_f + q;                             \
+        if (T##_f <= X##_f)                            \
+          {                                            \
+            S##_f = T##_f + q;                         \
+            X##_f -= T##_f;                            \
+            R##_f += q;                                        \
+          }                                            \
+        _FP_FRAC_SLL_1(X, 1);                          \
+        q >>= 1;                                       \
+      }                                                        \
+    if (X##_f)                                         \
+      {                                                        \
+       if (S##_f < X##_f)                              \
+         R##_f |= _FP_WORK_ROUND;                      \
+       R##_f |= _FP_WORK_STICKY;                       \
+      }                                                        \
+  } while (0)
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)       (r = X##_f)
+#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)    (X##_f = r)
+
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_COPY_1_1(D, S)                (D##_f = S##_f)
diff --git a/gcc/config/soft-fp/op-2.h b/gcc/config/soft-fp/op-2.h
new file mode 100644 (file)
index 0000000..5c9bce4
--- /dev/null
@@ -0,0 +1,615 @@
+/* Software floating-point emulation.
+   Basic two-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define _FP_FRAC_DECL_2(X)     _FP_W_TYPE X##_f0, X##_f1
+#define _FP_FRAC_COPY_2(D,S)   (D##_f0 = S##_f0, D##_f1 = S##_f1)
+#define _FP_FRAC_SET_2(X,I)    __FP_FRAC_SET_2(X, I)
+#define _FP_FRAC_HIGH_2(X)     (X##_f1)
+#define _FP_FRAC_LOW_2(X)      (X##_f0)
+#define _FP_FRAC_WORD_2(X,w)   (X##_f##w)
+
+#define _FP_FRAC_SLL_2(X,N)                                                \
+(void)(((N) < _FP_W_TYPE_SIZE)                                             \
+       ? ({                                                                \
+           if (__builtin_constant_p(N) && (N) == 1)                        \
+             {                                                             \
+               X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0);   \
+               X##_f0 += X##_f0;                                           \
+             }                                                             \
+           else                                                            \
+             {                                                             \
+               X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
+               X##_f0 <<= (N);                                             \
+             }                                                             \
+           0;                                                              \
+         })                                                                \
+       : ({                                                                \
+           X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);                     \
+           X##_f0 = 0;                                                     \
+         }))
+
+
+#define _FP_FRAC_SRL_2(X,N)                                            \
+(void)(((N) < _FP_W_TYPE_SIZE)                                         \
+       ? ({                                                            \
+           X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
+           X##_f1 >>= (N);                                             \
+         })                                                            \
+       : ({                                                            \
+           X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);                 \
+           X##_f1 = 0;                                                 \
+         }))
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRST_2(X,S, N,sz)                                       \
+(void)(((N) < _FP_W_TYPE_SIZE)                                           \
+       ? ({                                                              \
+           S = (__builtin_constant_p(N) && (N) == 1                      \
+                ? X##_f0 & 1                                             \
+                : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0);             \
+           X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N)); \
+           X##_f1 >>= (N);                                               \
+         })                                                              \
+       : ({                                                              \
+           S = ((((N) == _FP_W_TYPE_SIZE                                 \
+                  ? 0                                                    \
+                  : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N))))               \
+                 | X##_f0) != 0);                                        \
+           X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE));                 \
+           X##_f1 = 0;                                                   \
+         }))
+
+#define _FP_FRAC_SRS_2(X,N,sz)                                           \
+(void)(((N) < _FP_W_TYPE_SIZE)                                           \
+       ? ({                                                              \
+           X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
+                     (__builtin_constant_p(N) && (N) == 1                \
+                      ? X##_f0 & 1                                       \
+                      : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0));      \
+           X##_f1 >>= (N);                                               \
+         })                                                              \
+       : ({                                                              \
+           X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |                 \
+                     ((((N) == _FP_W_TYPE_SIZE                           \
+                        ? 0                                              \
+                        : (X##_f1 << (2*_FP_W_TYPE_SIZE - (N))))         \
+                       | X##_f0) != 0));                                 \
+           X##_f1 = 0;                                                   \
+         }))
+
+#define _FP_FRAC_ADDI_2(X,I)   \
+  __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
+
+#define _FP_FRAC_ADD_2(R,X,Y)  \
+  __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_SUB_2(R,X,Y)  \
+  __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_DEC_2(X,Y)    \
+  __FP_FRAC_DEC_2(X##_f1, X##_f0, Y##_f1, Y##_f0)
+
+#define _FP_FRAC_CLZ_2(R,X)    \
+  do {                         \
+    if (X##_f1)                        \
+      __FP_CLZ(R,X##_f1);      \
+    else                       \
+    {                          \
+      __FP_CLZ(R,X##_f0);      \
+      R += _FP_W_TYPE_SIZE;    \
+    }                          \
+  } while(0)
+
+/* Predicates */
+#define _FP_FRAC_NEGP_2(X)     ((_FP_WS_TYPE)X##_f1 < 0)
+#define _FP_FRAC_ZEROP_2(X)    ((X##_f1 | X##_f0) == 0)
+#define _FP_FRAC_OVERP_2(fs,X) (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_2(fs,X)   (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
+#define _FP_FRAC_EQ_2(X, Y)    (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
+#define _FP_FRAC_GT_2(X, Y)    \
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
+#define _FP_FRAC_GE_2(X, Y)    \
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
+
+#define _FP_ZEROFRAC_2         0, 0
+#define _FP_MINFRAC_2          0, 1
+#define _FP_MAXFRAC_2          (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_2(X,I1,I0)       (X##_f0 = I0, X##_f1 = I1)
+
+#define __FP_CLZ_2(R, xh, xl)  \
+  do {                         \
+    if (xh)                    \
+      __FP_CLZ(R,xh);          \
+    else                       \
+    {                          \
+      __FP_CLZ(R,xl);          \
+      R += _FP_W_TYPE_SIZE;    \
+    }                          \
+  } while(0)
+
+#if 0
+
+#ifndef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i)    \
+  (xh += ((xl += i) < i))
+#endif
+#ifndef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)        \
+  (rh = xh + yh + ((rl = xl + yl) < xl))
+#endif
+#ifndef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)        \
+  (rh = xh - yh - ((rl = xl - yl) > xl))
+#endif
+#ifndef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl)        \
+  do {                                 \
+    UWtype _t = xl;                    \
+    xh -= yh + ((xl -= yl) > _t);      \
+  } while (0)
+#endif
+
+#else
+
+#undef __FP_FRAC_ADDI_2
+#define __FP_FRAC_ADDI_2(xh, xl, i)    add_ssaaaa(xh, xl, xh, xl, 0, i)
+#undef __FP_FRAC_ADD_2
+#define __FP_FRAC_ADD_2                        add_ssaaaa
+#undef __FP_FRAC_SUB_2
+#define __FP_FRAC_SUB_2                        sub_ddmmss
+#undef __FP_FRAC_DEC_2
+#define __FP_FRAC_DEC_2(xh, xl, yh, yl)        sub_ddmmss(xh, xl, xh, xl, yh, yl)
+
+#endif
+
+/*
+ * Unpack the raw bits of a native fp value.  Do not classify or
+ * normalize the data.
+ */
+
+#define _FP_UNPACK_RAW_2(fs, X, val)                   \
+  do {                                                 \
+    union _FP_UNION_##fs _flo; _flo.flt = (val);       \
+                                                       \
+    X##_f0 = _flo.bits.frac0;                          \
+    X##_f1 = _flo.bits.frac1;                          \
+    X##_e  = _flo.bits.exp;                            \
+    X##_s  = _flo.bits.sign;                           \
+  } while (0)
+
+#define _FP_UNPACK_RAW_2_P(fs, X, val)                 \
+  do {                                                 \
+    union _FP_UNION_##fs *_flo =                       \
+      (union _FP_UNION_##fs *)(val);                   \
+                                                       \
+    X##_f0 = _flo->bits.frac0;                         \
+    X##_f1 = _flo->bits.frac1;                         \
+    X##_e  = _flo->bits.exp;                           \
+    X##_s  = _flo->bits.sign;                          \
+  } while (0)
+
+
+/*
+ * Repack the raw bits of a native fp value.
+ */
+
+#define _FP_PACK_RAW_2(fs, val, X)                     \
+  do {                                                 \
+    union _FP_UNION_##fs _flo;                         \
+                                                       \
+    _flo.bits.frac0 = X##_f0;                          \
+    _flo.bits.frac1 = X##_f1;                          \
+    _flo.bits.exp   = X##_e;                           \
+    _flo.bits.sign  = X##_s;                           \
+                                                       \
+    (val) = _flo.flt;                                  \
+  } while (0)
+
+#define _FP_PACK_RAW_2_P(fs, val, X)                   \
+  do {                                                 \
+    union _FP_UNION_##fs *_flo =                       \
+      (union _FP_UNION_##fs *)(val);                   \
+                                                       \
+    _flo->bits.frac0 = X##_f0;                         \
+    _flo->bits.frac1 = X##_f1;                         \
+    _flo->bits.exp   = X##_e;                          \
+    _flo->bits.sign  = X##_s;                          \
+  } while (0)
+
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_2_wide(wfracbits, R, X, Y, doit)                  \
+  do {                                                                 \
+    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);     \
+                                                                       \
+    doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0);        \
+    doit(_b_f1, _b_f0, X##_f0, Y##_f1);                                        \
+    doit(_c_f1, _c_f0, X##_f1, Y##_f0);                                        \
+    doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1);        \
+                                                                       \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
+                   _FP_FRAC_WORD_4(_z,1), 0, _b_f1, _b_f0,             \
+                   _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),        \
+                   _FP_FRAC_WORD_4(_z,1));                             \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
+                   _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0,             \
+                   _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),        \
+                   _FP_FRAC_WORD_4(_z,1));                             \
+                                                                       \
+    /* Normalize since we know where the msb of the multiplicands      \
+       were (bit B), we know that the msb of the of the product is     \
+       at either 2B or 2B-1.  */                                       \
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);                      \
+    R##_f0 = _FP_FRAC_WORD_4(_z,0);                                    \
+    R##_f1 = _FP_FRAC_WORD_4(_z,1);                                    \
+  } while (0)
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.
+   Do only 3 multiplications instead of four. This one is for machines
+   where multiplication is much more expensive than subtraction.  */
+
+#define _FP_MUL_MEAT_2_wide_3mul(wfracbits, R, X, Y, doit)             \
+  do {                                                                 \
+    _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);     \
+    _FP_W_TYPE _d;                                                     \
+    int _c1, _c2;                                                      \
+                                                                       \
+    _b_f0 = X##_f0 + X##_f1;                                           \
+    _c1 = _b_f0 < X##_f0;                                              \
+    _b_f1 = Y##_f0 + Y##_f1;                                           \
+    _c2 = _b_f1 < Y##_f0;                                              \
+    doit(_d, _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0);                   \
+    doit(_FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1), _b_f0, _b_f1);  \
+    doit(_c_f1, _c_f0, X##_f1, Y##_f1);                                        \
+                                                                       \
+    _b_f0 &= -_c2;                                                     \
+    _b_f1 &= -_c1;                                                     \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
+                   _FP_FRAC_WORD_4(_z,1), (_c1 & _c2), 0, _d,          \
+                   0, _FP_FRAC_WORD_4(_z,2), _FP_FRAC_WORD_4(_z,1));   \
+    __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),      \
+                    _b_f0);                                            \
+    __FP_FRAC_ADDI_2(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),      \
+                    _b_f1);                                            \
+    __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
+                   _FP_FRAC_WORD_4(_z,1),                              \
+                   0, _d, _FP_FRAC_WORD_4(_z,0));                      \
+    __FP_FRAC_DEC_3(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2),       \
+                   _FP_FRAC_WORD_4(_z,1), 0, _c_f1, _c_f0);            \
+    __FP_FRAC_ADD_2(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2),      \
+                   _c_f1, _c_f0,                                       \
+                   _FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2));      \
+                                                                       \
+    /* Normalize since we know where the msb of the multiplicands      \
+       were (bit B), we know that the msb of the of the product is     \
+       at either 2B or 2B-1.  */                                       \
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);                      \
+    R##_f0 = _FP_FRAC_WORD_4(_z,0);                                    \
+    R##_f1 = _FP_FRAC_WORD_4(_z,1);                                    \
+  } while (0)
+
+#define _FP_MUL_MEAT_2_gmp(wfracbits, R, X, Y)                         \
+  do {                                                                 \
+    _FP_FRAC_DECL_4(_z);                                               \
+    _FP_W_TYPE _x[2], _y[2];                                           \
+    _x[0] = X##_f0; _x[1] = X##_f1;                                    \
+    _y[0] = Y##_f0; _y[1] = Y##_f1;                                    \
+                                                                       \
+    mpn_mul_n(_z_f, _x, _y, 2);                                                \
+                                                                       \
+    /* Normalize since we know where the msb of the multiplicands      \
+       were (bit B), we know that the msb of the of the product is     \
+       at either 2B or 2B-1.  */                                       \
+    _FP_FRAC_SRS_4(_z, wfracbits-1, 2*wfracbits);                      \
+    R##_f0 = _z_f[0];                                                  \
+    R##_f1 = _z_f[1];                                                  \
+  } while (0)
+
+/* Do at most 120x120=240 bits multiplication using double floating
+   point multiplication.  This is useful if floating point
+   multiplication has much bigger throughput than integer multiply.
+   It is supposed to work for _FP_W_TYPE_SIZE 64 and wfracbits
+   between 106 and 120 only.  
+   Caller guarantees that X and Y has (1LLL << (wfracbits - 1)) set.
+   SETFETZ is a macro which will disable all FPU exceptions and set rounding
+   towards zero,  RESETFE should optionally reset it back.  */
+
+#define _FP_MUL_MEAT_2_120_240_double(wfracbits, R, X, Y, setfetz, resetfe)    \
+  do {                                                                         \
+    static const double _const[] = {                                           \
+      /* 2^-24 */ 5.9604644775390625e-08,                                      \
+      /* 2^-48 */ 3.5527136788005009e-15,                                      \
+      /* 2^-72 */ 2.1175823681357508e-22,                                      \
+      /* 2^-96 */ 1.2621774483536189e-29,                                      \
+      /* 2^28 */ 2.68435456e+08,                                               \
+      /* 2^4 */ 1.600000e+01,                                                  \
+      /* 2^-20 */ 9.5367431640625e-07,                                         \
+      /* 2^-44 */ 5.6843418860808015e-14,                                      \
+      /* 2^-68 */ 3.3881317890172014e-21,                                      \
+      /* 2^-92 */ 2.0194839173657902e-28,                                      \
+      /* 2^-116 */ 1.2037062152420224e-35};                                    \
+    double _a240, _b240, _c240, _d240, _e240, _f240,                           \
+          _g240, _h240, _i240, _j240, _k240;                                   \
+    union { double d; UDItype i; } _l240, _m240, _n240, _o240,                 \
+                                  _p240, _q240, _r240, _s240;                  \
+    UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0;                      \
+                                                                               \
+    if (wfracbits < 106 || wfracbits > 120)                                    \
+      abort();                                                                 \
+                                                                               \
+    setfetz;                                                                   \
+                                                                               \
+    _e240 = (double)(long)(X##_f0 & 0xffffff);                                 \
+    _j240 = (double)(long)(Y##_f0 & 0xffffff);                                 \
+    _d240 = (double)(long)((X##_f0 >> 24) & 0xffffff);                         \
+    _i240 = (double)(long)((Y##_f0 >> 24) & 0xffffff);                         \
+    _c240 = (double)(long)(((X##_f1 << 16) & 0xffffff) | (X##_f0 >> 48));      \
+    _h240 = (double)(long)(((Y##_f1 << 16) & 0xffffff) | (Y##_f0 >> 48));      \
+    _b240 = (double)(long)((X##_f1 >> 8) & 0xffffff);                          \
+    _g240 = (double)(long)((Y##_f1 >> 8) & 0xffffff);                          \
+    _a240 = (double)(long)(X##_f1 >> 32);                                      \
+    _f240 = (double)(long)(Y##_f1 >> 32);                                      \
+    _e240 *= _const[3];                                                                \
+    _j240 *= _const[3];                                                                \
+    _d240 *= _const[2];                                                                \
+    _i240 *= _const[2];                                                                \
+    _c240 *= _const[1];                                                                \
+    _h240 *= _const[1];                                                                \
+    _b240 *= _const[0];                                                                \
+    _g240 *= _const[0];                                                                \
+    _s240.d =                                                        _e240*_j240;\
+    _r240.d =                                          _d240*_j240 + _e240*_i240;\
+    _q240.d =                            _c240*_j240 + _d240*_i240 + _e240*_h240;\
+    _p240.d =              _b240*_j240 + _c240*_i240 + _d240*_h240 + _e240*_g240;\
+    _o240.d = _a240*_j240 + _b240*_i240 + _c240*_h240 + _d240*_g240 + _e240*_f240;\
+    _n240.d = _a240*_i240 + _b240*_h240 + _c240*_g240 + _d240*_f240;           \
+    _m240.d = _a240*_h240 + _b240*_g240 + _c240*_f240;                         \
+    _l240.d = _a240*_g240 + _b240*_f240;                                       \
+    _k240 =   _a240*_f240;                                                     \
+    _r240.d += _s240.d;                                                                \
+    _q240.d += _r240.d;                                                                \
+    _p240.d += _q240.d;                                                                \
+    _o240.d += _p240.d;                                                                \
+    _n240.d += _o240.d;                                                                \
+    _m240.d += _n240.d;                                                                \
+    _l240.d += _m240.d;                                                                \
+    _k240 += _l240.d;                                                          \
+    _s240.d -= ((_const[10]+_s240.d)-_const[10]);                              \
+    _r240.d -= ((_const[9]+_r240.d)-_const[9]);                                        \
+    _q240.d -= ((_const[8]+_q240.d)-_const[8]);                                        \
+    _p240.d -= ((_const[7]+_p240.d)-_const[7]);                                        \
+    _o240.d += _const[7];                                                      \
+    _n240.d += _const[6];                                                      \
+    _m240.d += _const[5];                                                      \
+    _l240.d += _const[4];                                                      \
+    if (_s240.d != 0.0) _y240 = 1;                                             \
+    if (_r240.d != 0.0) _y240 = 1;                                             \
+    if (_q240.d != 0.0) _y240 = 1;                                             \
+    if (_p240.d != 0.0) _y240 = 1;                                             \
+    _t240 = (DItype)_k240;                                                     \
+    _u240 = _l240.i;                                                           \
+    _v240 = _m240.i;                                                           \
+    _w240 = _n240.i;                                                           \
+    _x240 = _o240.i;                                                           \
+    R##_f1 = (_t240 << (128 - (wfracbits - 1)))                                        \
+            | ((_u240 & 0xffffff) >> ((wfracbits - 1) - 104));                 \
+    R##_f0 = ((_u240 & 0xffffff) << (168 - (wfracbits - 1)))                   \
+            | ((_v240 & 0xffffff) << (144 - (wfracbits - 1)))                  \
+            | ((_w240 & 0xffffff) << (120 - (wfracbits - 1)))                  \
+            | ((_x240 & 0xffffff) >> ((wfracbits - 1) - 96))                   \
+            | _y240;                                                           \
+    resetfe;                                                                   \
+  } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_2_udiv(fs, R, X, Y)                               \
+  do {                                                                 \
+    _FP_W_TYPE _n_f2, _n_f1, _n_f0, _r_f1, _r_f0, _m_f1, _m_f0;                \
+    if (_FP_FRAC_GT_2(X, Y))                                           \
+      {                                                                        \
+       _n_f2 = X##_f1 >> 1;                                            \
+       _n_f1 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1;          \
+       _n_f0 = X##_f0 << (_FP_W_TYPE_SIZE - 1);                        \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       R##_e--;                                                        \
+       _n_f2 = X##_f1;                                                 \
+       _n_f1 = X##_f0;                                                 \
+       _n_f0 = 0;                                                      \
+      }                                                                        \
+                                                                       \
+    /* Normalize, i.e. make the most significant bit of the            \
+       denominator set. */                                             \
+    _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs);                            \
+                                                                       \
+    udiv_qrnnd(R##_f1, _r_f1, _n_f2, _n_f1, Y##_f1);                   \
+    umul_ppmm(_m_f1, _m_f0, R##_f1, Y##_f0);                           \
+    _r_f0 = _n_f0;                                                     \
+    if (_FP_FRAC_GT_2(_m, _r))                                         \
+      {                                                                        \
+       R##_f1--;                                                       \
+       _FP_FRAC_ADD_2(_r, Y, _r);                                      \
+       if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))              \
+         {                                                             \
+           R##_f1--;                                                   \
+           _FP_FRAC_ADD_2(_r, Y, _r);                                  \
+         }                                                             \
+      }                                                                        \
+    _FP_FRAC_DEC_2(_r, _m);                                            \
+                                                                       \
+    if (_r_f1 == Y##_f1)                                               \
+      {                                                                        \
+       /* This is a special case, not an optimization                  \
+          (_r/Y##_f1 would not fit into UWtype).                       \
+          As _r is guaranteed to be < Y,  R##_f0 can be either         \
+          (UWtype)-1 or (UWtype)-2.  But as we know what kind          \
+          of bits it is (sticky, guard, round),  we don't care.        \
+          We also don't care what the reminder is,  because the        \
+          guard bit will be set anyway.  -jj */                        \
+       R##_f0 = -1;                                                    \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       udiv_qrnnd(R##_f0, _r_f1, _r_f1, _r_f0, Y##_f1);                \
+       umul_ppmm(_m_f1, _m_f0, R##_f0, Y##_f0);                        \
+       _r_f0 = 0;                                                      \
+       if (_FP_FRAC_GT_2(_m, _r))                                      \
+         {                                                             \
+           R##_f0--;                                                   \
+           _FP_FRAC_ADD_2(_r, Y, _r);                                  \
+           if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r))          \
+             {                                                         \
+               R##_f0--;                                               \
+               _FP_FRAC_ADD_2(_r, Y, _r);                              \
+             }                                                         \
+         }                                                             \
+       if (!_FP_FRAC_EQ_2(_r, _m))                                     \
+         R##_f0 |= _FP_WORK_STICKY;                                    \
+      }                                                                        \
+  } while (0)
+
+
+#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y)                                        \
+  do {                                                                 \
+    _FP_W_TYPE _x[4], _y[2], _z[4];                                    \
+    _y[0] = Y##_f0; _y[1] = Y##_f1;                                    \
+    _x[0] = _x[3] = 0;                                                 \
+    if (_FP_FRAC_GT_2(X, Y))                                           \
+      {                                                                        \
+       R##_e++;                                                        \
+       _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE) |   \
+                X##_f1 >> (_FP_W_TYPE_SIZE -                           \
+                           (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE))); \
+       _x[2] = X##_f1 << (_FP_WFRACBITS_##fs-1 - _FP_W_TYPE_SIZE);     \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       _x[1] = (X##_f0 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE) |     \
+                X##_f1 >> (_FP_W_TYPE_SIZE -                           \
+                           (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE)));   \
+       _x[2] = X##_f1 << (_FP_WFRACBITS_##fs - _FP_W_TYPE_SIZE);       \
+      }                                                                        \
+                                                                       \
+    (void) mpn_divrem (_z, 0, _x, 4, _y, 2);                           \
+    R##_f1 = _z[1];                                                    \
+    R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0);                           \
+  } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+#define _FP_SQRT_MEAT_2(R, S, T, X, q)                 \
+  do {                                                 \
+    while (q)                                          \
+      {                                                        \
+       T##_f1 = S##_f1 + q;                            \
+       if (T##_f1 <= X##_f1)                           \
+         {                                             \
+           S##_f1 = T##_f1 + q;                        \
+           X##_f1 -= T##_f1;                           \
+           R##_f1 += q;                                \
+         }                                             \
+       _FP_FRAC_SLL_2(X, 1);                           \
+       q >>= 1;                                        \
+      }                                                        \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                \
+    while (q != _FP_WORK_ROUND)                                \
+      {                                                        \
+       T##_f0 = S##_f0 + q;                            \
+       T##_f1 = S##_f1;                                \
+       if (T##_f1 < X##_f1 ||                          \
+           (T##_f1 == X##_f1 && T##_f0 <= X##_f0))     \
+         {                                             \
+           S##_f0 = T##_f0 + q;                        \
+           S##_f1 += (T##_f0 > S##_f0);                \
+           _FP_FRAC_DEC_2(X, T);                       \
+           R##_f0 += q;                                \
+         }                                             \
+       _FP_FRAC_SLL_2(X, 1);                           \
+       q >>= 1;                                        \
+      }                                                        \
+    if (X##_f0 | X##_f1)                               \
+      {                                                        \
+       if (S##_f1 < X##_f1 ||                          \
+           (S##_f1 == X##_f1 && S##_f0 < X##_f0))      \
+         R##_f0 |= _FP_WORK_ROUND;                     \
+       R##_f0 |= _FP_WORK_STICKY;                      \
+      }                                                        \
+  } while (0)
+
+
+/*
+ * Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+
+#define _FP_FRAC_ASSEMBLE_2(r, X, rsize)       \
+(void)((rsize <= _FP_W_TYPE_SIZE)              \
+       ? ({ r = X##_f0; })                     \
+       : ({                                    \
+           r = X##_f1;                         \
+           r <<= _FP_W_TYPE_SIZE;              \
+           r += X##_f0;                        \
+         }))
+
+#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize)                            \
+  do {                                                                 \
+    X##_f0 = r;                                                                \
+    X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);    \
+  } while (0)
+
+/*
+ * Convert FP values between word sizes
+ */
+
+#define _FP_FRAC_COPY_1_2(D, S)                (D##_f = S##_f0)
+
+#define _FP_FRAC_COPY_2_1(D, S)                ((D##_f0 = S##_f), (D##_f1 = 0))
diff --git a/gcc/config/soft-fp/op-4.h b/gcc/config/soft-fp/op-4.h
new file mode 100644 (file)
index 0000000..34f5098
--- /dev/null
@@ -0,0 +1,686 @@
+/* Software floating-point emulation.
+   Basic four-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define _FP_FRAC_DECL_4(X)     _FP_W_TYPE X##_f[4]
+#define _FP_FRAC_COPY_4(D,S)                   \
+  (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1],   \
+   D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
+#define _FP_FRAC_SET_4(X,I)    __FP_FRAC_SET_4(X, I)
+#define _FP_FRAC_HIGH_4(X)     (X##_f[3])
+#define _FP_FRAC_LOW_4(X)      (X##_f[0])
+#define _FP_FRAC_WORD_4(X,w)   (X##_f[w])
+
+#define _FP_FRAC_SLL_4(X,N)                                            \
+  do {                                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                                  \
+    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
+    _up = (N) % _FP_W_TYPE_SIZE;                                       \
+    _down = _FP_W_TYPE_SIZE - _up;                                     \
+    if (!_up)                                                          \
+      for (_i = 3; _i >= _skip; --_i)                                  \
+       X##_f[_i] = X##_f[_i-_skip];                                    \
+    else                                                               \
+      {                                                                        \
+       for (_i = 3; _i > _skip; --_i)                                  \
+         X##_f[_i] = X##_f[_i-_skip] << _up                            \
+                     | X##_f[_i-_skip-1] >> _down;                     \
+       X##_f[_i--] = X##_f[0] << _up;                                  \
+      }                                                                        \
+    for (; _i >= 0; --_i)                                              \
+      X##_f[_i] = 0;                                                   \
+  } while (0)
+
+/* This one was broken too */
+#define _FP_FRAC_SRL_4(X,N)                                            \
+  do {                                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                                  \
+    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
+    _down = (N) % _FP_W_TYPE_SIZE;                                     \
+    _up = _FP_W_TYPE_SIZE - _down;                                     \
+    if (!_down)                                                                \
+      for (_i = 0; _i <= 3-_skip; ++_i)                                        \
+       X##_f[_i] = X##_f[_i+_skip];                                    \
+    else                                                               \
+      {                                                                        \
+       for (_i = 0; _i < 3-_skip; ++_i)                                \
+         X##_f[_i] = X##_f[_i+_skip] >> _down                          \
+                     | X##_f[_i+_skip+1] << _up;                       \
+       X##_f[_i++] = X##_f[3] >> _down;                                \
+      }                                                                        \
+    for (; _i < 4; ++_i)                                               \
+      X##_f[_i] = 0;                                                   \
+  } while (0)
+
+
+/* Right shift with sticky-lsb. 
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRST_4(X,S,N,size)                    \
+  do {                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                  \
+    _FP_W_TYPE _s;                                     \
+    _skip = (N) / _FP_W_TYPE_SIZE;                     \
+    _down = (N) % _FP_W_TYPE_SIZE;                     \
+    _up = _FP_W_TYPE_SIZE - _down;                     \
+    for (_s = _i = 0; _i < _skip; ++_i)                        \
+      _s |= X##_f[_i];                                 \
+    if (!_down)                                                \
+      for (_i = 0; _i <= 3-_skip; ++_i)                        \
+       X##_f[_i] = X##_f[_i+_skip];                    \
+    else                                               \
+      {                                                        \
+       _s |= X##_f[_i] << _up;                         \
+       for (_i = 0; _i < 3-_skip; ++_i)                \
+         X##_f[_i] = X##_f[_i+_skip] >> _down          \
+                     | X##_f[_i+_skip+1] << _up;       \
+       X##_f[_i++] = X##_f[3] >> _down;                \
+      }                                                        \
+    for (; _i < 4; ++_i)                               \
+      X##_f[_i] = 0;                                   \
+    S = (_s != 0);                                     \
+  } while (0)
+
+#define _FP_FRAC_SRS_4(X,N,size)               \
+  do {                                         \
+    int _sticky;                               \
+    _FP_FRAC_SRST_4(X, _sticky, N, size);      \
+    X##_f[0] |= _sticky;                       \
+  } while (0)
+
+#define _FP_FRAC_ADD_4(R,X,Y)                                          \
+  __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],              \
+                 X##_f[3], X##_f[2], X##_f[1], X##_f[0],               \
+                 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_SUB_4(R,X,Y)                                          \
+  __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0],              \
+                 X##_f[3], X##_f[2], X##_f[1], X##_f[0],               \
+                 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_DEC_4(X,Y)                                            \
+  __FP_FRAC_DEC_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0],              \
+                 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
+
+#define _FP_FRAC_ADDI_4(X,I)                                           \
+  __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
+
+#define _FP_ZEROFRAC_4  0,0,0,0
+#define _FP_MINFRAC_4   0,0,0,1
+#define _FP_MAXFRAC_4  (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0), (~(_FP_WS_TYPE)0)
+
+#define _FP_FRAC_ZEROP_4(X)     ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
+#define _FP_FRAC_NEGP_4(X)      ((_FP_WS_TYPE)X##_f[3] < 0)
+#define _FP_FRAC_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
+#define _FP_FRAC_CLEAR_OVERP_4(fs,X)  (_FP_FRAC_HIGH_##fs(X) &= ~_FP_OVERFLOW_##fs)
+
+#define _FP_FRAC_EQ_4(X,Y)                             \
+ (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1]         \
+  && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
+
+#define _FP_FRAC_GT_4(X,Y)                             \
+ (X##_f[3] > Y##_f[3] ||                               \
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||     \
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||    \
+    (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0])      \
+   ))                                                  \
+  ))                                                   \
+ )
+
+#define _FP_FRAC_GE_4(X,Y)                             \
+ (X##_f[3] > Y##_f[3] ||                               \
+  (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] ||     \
+   (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] ||    \
+    (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0])     \
+   ))                                                  \
+  ))                                                   \
+ )
+
+
+#define _FP_FRAC_CLZ_4(R,X)            \
+  do {                                 \
+    if (X##_f[3])                      \
+    {                                  \
+       __FP_CLZ(R,X##_f[3]);           \
+    }                                  \
+    else if (X##_f[2])                 \
+    {                                  \
+       __FP_CLZ(R,X##_f[2]);           \
+       R += _FP_W_TYPE_SIZE;           \
+    }                                  \
+    else if (X##_f[1])                 \
+    {                                  \
+       __FP_CLZ(R,X##_f[1]);           \
+       R += _FP_W_TYPE_SIZE*2;         \
+    }                                  \
+    else                               \
+    {                                  \
+       __FP_CLZ(R,X##_f[0]);           \
+       R += _FP_W_TYPE_SIZE*3;         \
+    }                                  \
+  } while(0)
+
+
+#define _FP_UNPACK_RAW_4(fs, X, val)                           \
+  do {                                                         \
+    union _FP_UNION_##fs _flo; _flo.flt = (val);               \
+    X##_f[0] = _flo.bits.frac0;                                        \
+    X##_f[1] = _flo.bits.frac1;                                        \
+    X##_f[2] = _flo.bits.frac2;                                        \
+    X##_f[3] = _flo.bits.frac3;                                        \
+    X##_e  = _flo.bits.exp;                                    \
+    X##_s  = _flo.bits.sign;                                   \
+  } while (0)
+
+#define _FP_UNPACK_RAW_4_P(fs, X, val)                         \
+  do {                                                         \
+    union _FP_UNION_##fs *_flo =                               \
+      (union _FP_UNION_##fs *)(val);                           \
+                                                               \
+    X##_f[0] = _flo->bits.frac0;                               \
+    X##_f[1] = _flo->bits.frac1;                               \
+    X##_f[2] = _flo->bits.frac2;                               \
+    X##_f[3] = _flo->bits.frac3;                               \
+    X##_e  = _flo->bits.exp;                                   \
+    X##_s  = _flo->bits.sign;                                  \
+  } while (0)
+
+#define _FP_PACK_RAW_4(fs, val, X)                             \
+  do {                                                         \
+    union _FP_UNION_##fs _flo;                                 \
+    _flo.bits.frac0 = X##_f[0];                                        \
+    _flo.bits.frac1 = X##_f[1];                                        \
+    _flo.bits.frac2 = X##_f[2];                                        \
+    _flo.bits.frac3 = X##_f[3];                                        \
+    _flo.bits.exp   = X##_e;                                   \
+    _flo.bits.sign  = X##_s;                                   \
+    (val) = _flo.flt;                                          \
+  } while (0)
+
+#define _FP_PACK_RAW_4_P(fs, val, X)                           \
+  do {                                                         \
+    union _FP_UNION_##fs *_flo =                               \
+      (union _FP_UNION_##fs *)(val);                           \
+                                                               \
+    _flo->bits.frac0 = X##_f[0];                               \
+    _flo->bits.frac1 = X##_f[1];                               \
+    _flo->bits.frac2 = X##_f[2];                               \
+    _flo->bits.frac3 = X##_f[3];                               \
+    _flo->bits.exp   = X##_e;                                  \
+    _flo->bits.sign  = X##_s;                                  \
+  } while (0)
+
+/*
+ * Multiplication algorithms:
+ */
+
+/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
+
+#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit)                      \
+  do {                                                                     \
+    _FP_FRAC_DECL_8(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c);         \
+    _FP_FRAC_DECL_2(_d); _FP_FRAC_DECL_2(_e); _FP_FRAC_DECL_2(_f);         \
+                                                                           \
+    doit(_FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0), X##_f[0], Y##_f[0]); \
+    doit(_b_f1, _b_f0, X##_f[0], Y##_f[1]);                                \
+    doit(_c_f1, _c_f0, X##_f[1], Y##_f[0]);                                \
+    doit(_d_f1, _d_f0, X##_f[1], Y##_f[1]);                                \
+    doit(_e_f1, _e_f0, X##_f[0], Y##_f[2]);                                \
+    doit(_f_f1, _f_f0, X##_f[2], Y##_f[0]);                                \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),           \
+                   _FP_FRAC_WORD_8(_z,1), 0,_b_f1,_b_f0,                   \
+                   0,0,_FP_FRAC_WORD_8(_z,1));                             \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),           \
+                   _FP_FRAC_WORD_8(_z,1), 0,_c_f1,_c_f0,                   \
+                   _FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2),            \
+                   _FP_FRAC_WORD_8(_z,1));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),           \
+                   _FP_FRAC_WORD_8(_z,2), 0,_d_f1,_d_f0,                   \
+                   0,_FP_FRAC_WORD_8(_z,3),_FP_FRAC_WORD_8(_z,2));         \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),           \
+                   _FP_FRAC_WORD_8(_z,2), 0,_e_f1,_e_f0,                   \
+                   _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),            \
+                   _FP_FRAC_WORD_8(_z,2));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),           \
+                   _FP_FRAC_WORD_8(_z,2), 0,_f_f1,_f_f0,                   \
+                   _FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3),            \
+                   _FP_FRAC_WORD_8(_z,2));                                 \
+    doit(_b_f1, _b_f0, X##_f[0], Y##_f[3]);                                \
+    doit(_c_f1, _c_f0, X##_f[3], Y##_f[0]);                                \
+    doit(_d_f1, _d_f0, X##_f[1], Y##_f[2]);                                \
+    doit(_e_f1, _e_f0, X##_f[2], Y##_f[1]);                                \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),           \
+                   _FP_FRAC_WORD_8(_z,3), 0,_b_f1,_b_f0,                   \
+                   0,_FP_FRAC_WORD_8(_z,4),_FP_FRAC_WORD_8(_z,3));         \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),           \
+                   _FP_FRAC_WORD_8(_z,3), 0,_c_f1,_c_f0,                   \
+                   _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),            \
+                   _FP_FRAC_WORD_8(_z,3));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),           \
+                   _FP_FRAC_WORD_8(_z,3), 0,_d_f1,_d_f0,                   \
+                   _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),            \
+                   _FP_FRAC_WORD_8(_z,3));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),           \
+                   _FP_FRAC_WORD_8(_z,3), 0,_e_f1,_e_f0,                   \
+                   _FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4),            \
+                   _FP_FRAC_WORD_8(_z,3));                                 \
+    doit(_b_f1, _b_f0, X##_f[2], Y##_f[2]);                                \
+    doit(_c_f1, _c_f0, X##_f[1], Y##_f[3]);                                \
+    doit(_d_f1, _d_f0, X##_f[3], Y##_f[1]);                                \
+    doit(_e_f1, _e_f0, X##_f[2], Y##_f[3]);                                \
+    doit(_f_f1, _f_f0, X##_f[3], Y##_f[2]);                                \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),           \
+                   _FP_FRAC_WORD_8(_z,4), 0,_b_f1,_b_f0,                   \
+                   0,_FP_FRAC_WORD_8(_z,5),_FP_FRAC_WORD_8(_z,4));         \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),           \
+                   _FP_FRAC_WORD_8(_z,4), 0,_c_f1,_c_f0,                   \
+                   _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),            \
+                   _FP_FRAC_WORD_8(_z,4));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),           \
+                   _FP_FRAC_WORD_8(_z,4), 0,_d_f1,_d_f0,                   \
+                   _FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5),            \
+                   _FP_FRAC_WORD_8(_z,4));                                 \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),           \
+                   _FP_FRAC_WORD_8(_z,5), 0,_e_f1,_e_f0,                   \
+                   0,_FP_FRAC_WORD_8(_z,6),_FP_FRAC_WORD_8(_z,5));         \
+    __FP_FRAC_ADD_3(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),           \
+                   _FP_FRAC_WORD_8(_z,5), 0,_f_f1,_f_f0,                   \
+                   _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),            \
+                   _FP_FRAC_WORD_8(_z,5));                                 \
+    doit(_b_f1, _b_f0, X##_f[3], Y##_f[3]);                                \
+    __FP_FRAC_ADD_2(_FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6),           \
+                   _b_f1,_b_f0,                                            \
+                   _FP_FRAC_WORD_8(_z,7),_FP_FRAC_WORD_8(_z,6));           \
+                                                                           \
+    /* Normalize since we know where the msb of the multiplicands          \
+       were (bit B), we know that the msb of the of the product is         \
+       at either 2B or 2B-1.  */                                           \
+    _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits);                          \
+    __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2),       \
+                   _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0));          \
+  } while (0)
+
+#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y)                             \
+  do {                                                                     \
+    _FP_FRAC_DECL_8(_z);                                                   \
+                                                                           \
+    mpn_mul_n(_z_f, _x_f, _y_f, 4);                                        \
+                                                                           \
+    /* Normalize since we know where the msb of the multiplicands          \
+       were (bit B), we know that the msb of the of the product is         \
+       at either 2B or 2B-1.  */                                           \
+    _FP_FRAC_SRS_8(_z, wfracbits-1, 2*wfracbits);                          \
+    __FP_FRAC_SET_4(R, _FP_FRAC_WORD_8(_z,3), _FP_FRAC_WORD_8(_z,2),       \
+                   _FP_FRAC_WORD_8(_z,1), _FP_FRAC_WORD_8(_z,0));          \
+  } while (0)
+
+/*
+ * Helper utility for _FP_DIV_MEAT_4_udiv:
+ * pppp = m * nnn
+ */
+#define umul_ppppmnnn(p3,p2,p1,p0,m,n2,n1,n0)                              \
+  do {                                                                     \
+    UWtype _t;                                                             \
+    umul_ppmm(p1,p0,m,n0);                                                 \
+    umul_ppmm(p2,_t,m,n1);                                                 \
+    __FP_FRAC_ADDI_2(p2,p1,_t);                                                    \
+    umul_ppmm(p3,_t,m,n2);                                                 \
+    __FP_FRAC_ADDI_2(p3,p2,_t);                                                    \
+  } while (0)
+
+/*
+ * Division algorithms:
+ */
+
+#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y)                                   \
+  do {                                                                     \
+    int _i;                                                                \
+    _FP_FRAC_DECL_4(_n); _FP_FRAC_DECL_4(_m);                              \
+    _FP_FRAC_SET_4(_n, _FP_ZEROFRAC_4);                                            \
+    if (_FP_FRAC_GT_4(X, Y))                                               \
+      {                                                                            \
+       _n_f[3] = X##_f[0] << (_FP_W_TYPE_SIZE - 1);                        \
+       _FP_FRAC_SRL_4(X, 1);                                               \
+      }                                                                            \
+    else                                                                   \
+      R##_e--;                                                             \
+                                                                           \
+    /* Normalize, i.e. make the most significant bit of the                \
+       denominator set. */                                                 \
+    _FP_FRAC_SLL_4(Y, _FP_WFRACXBITS_##fs);                                \
+                                                                           \
+    for (_i = 3; ; _i--)                                                   \
+      {                                                                            \
+        if (X##_f[3] == Y##_f[3])                                          \
+          {                                                                \
+            /* This is a special case, not an optimization                 \
+               (X##_f[3]/Y##_f[3] would not fit into UWtype).              \
+               As X## is guaranteed to be < Y,  R##_f[_i] can be either            \
+               (UWtype)-1 or (UWtype)-2.  */                               \
+            R##_f[_i] = -1;                                                \
+            if (!_i)                                                       \
+             break;                                                        \
+            __FP_FRAC_SUB_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0],        \
+                           Y##_f[2], Y##_f[1], Y##_f[0], 0,                \
+                           X##_f[2], X##_f[1], X##_f[0], _n_f[_i]);        \
+            _FP_FRAC_SUB_4(X, Y, X);                                       \
+            if (X##_f[3] > Y##_f[3])                                       \
+              {                                                                    \
+                R##_f[_i] = -2;                                                    \
+                _FP_FRAC_ADD_4(X, Y, X);                                   \
+              }                                                                    \
+          }                                                                \
+        else                                                               \
+          {                                                                \
+            udiv_qrnnd(R##_f[_i], X##_f[3], X##_f[3], X##_f[2], Y##_f[3]);  \
+            umul_ppppmnnn(_m_f[3], _m_f[2], _m_f[1], _m_f[0],              \
+                         R##_f[_i], Y##_f[2], Y##_f[1], Y##_f[0]);         \
+            X##_f[2] = X##_f[1];                                           \
+            X##_f[1] = X##_f[0];                                           \
+            X##_f[0] = _n_f[_i];                                           \
+            if (_FP_FRAC_GT_4(_m, X))                                      \
+              {                                                                    \
+                R##_f[_i]--;                                               \
+                _FP_FRAC_ADD_4(X, Y, X);                                   \
+                if (_FP_FRAC_GE_4(X, Y) && _FP_FRAC_GT_4(_m, X))           \
+                  {                                                        \
+                   R##_f[_i]--;                                            \
+                   _FP_FRAC_ADD_4(X, Y, X);                                \
+                  }                                                        \
+              }                                                                    \
+            _FP_FRAC_DEC_4(X, _m);                                         \
+            if (!_i)                                                       \
+             {                                                             \
+               if (!_FP_FRAC_EQ_4(X, _m))                                  \
+                 R##_f[0] |= _FP_WORK_STICKY;                              \
+               break;                                                      \
+             }                                                             \
+          }                                                                \
+      }                                                                            \
+  } while (0)
+
+
+/*
+ * Square root algorithms:
+ * We have just one right now, maybe Newton approximation
+ * should be added for those machines where division is fast.
+ */
+#define _FP_SQRT_MEAT_4(R, S, T, X, q)                         \
+  do {                                                         \
+    while (q)                                                  \
+      {                                                                \
+       T##_f[3] = S##_f[3] + q;                                \
+       if (T##_f[3] <= X##_f[3])                               \
+         {                                                     \
+           S##_f[3] = T##_f[3] + q;                            \
+           X##_f[3] -= T##_f[3];                               \
+           R##_f[3] += q;                                      \
+         }                                                     \
+       _FP_FRAC_SLL_4(X, 1);                                   \
+       q >>= 1;                                                \
+      }                                                                \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                        \
+    while (q)                                                  \
+      {                                                                \
+       T##_f[2] = S##_f[2] + q;                                \
+       T##_f[3] = S##_f[3];                                    \
+       if (T##_f[3] < X##_f[3] ||                              \
+           (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2]))     \
+         {                                                     \
+           S##_f[2] = T##_f[2] + q;                            \
+           S##_f[3] += (T##_f[2] > S##_f[2]);                  \
+           __FP_FRAC_DEC_2(X##_f[3], X##_f[2],                 \
+                           T##_f[3], T##_f[2]);                \
+           R##_f[2] += q;                                      \
+         }                                                     \
+       _FP_FRAC_SLL_4(X, 1);                                   \
+       q >>= 1;                                                \
+      }                                                                \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                        \
+    while (q)                                                  \
+      {                                                                \
+       T##_f[1] = S##_f[1] + q;                                \
+       T##_f[2] = S##_f[2];                                    \
+       T##_f[3] = S##_f[3];                                    \
+       if (T##_f[3] < X##_f[3] ||                              \
+           (T##_f[3] == X##_f[3] && (T##_f[2] < X##_f[2] ||    \
+            (T##_f[2] == X##_f[2] && T##_f[1] <= X##_f[1]))))  \
+         {                                                     \
+           S##_f[1] = T##_f[1] + q;                            \
+           S##_f[2] += (T##_f[1] > S##_f[1]);                  \
+           S##_f[3] += (T##_f[2] > S##_f[2]);                  \
+           __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1],       \
+                           T##_f[3], T##_f[2], T##_f[1]);      \
+           R##_f[1] += q;                                      \
+         }                                                     \
+       _FP_FRAC_SLL_4(X, 1);                                   \
+       q >>= 1;                                                \
+      }                                                                \
+    q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);                        \
+    while (q != _FP_WORK_ROUND)                                        \
+      {                                                                \
+       T##_f[0] = S##_f[0] + q;                                \
+       T##_f[1] = S##_f[1];                                    \
+       T##_f[2] = S##_f[2];                                    \
+       T##_f[3] = S##_f[3];                                    \
+       if (_FP_FRAC_GE_4(X,T))                                 \
+         {                                                     \
+           S##_f[0] = T##_f[0] + q;                            \
+           S##_f[1] += (T##_f[0] > S##_f[0]);                  \
+           S##_f[2] += (T##_f[1] > S##_f[1]);                  \
+           S##_f[3] += (T##_f[2] > S##_f[2]);                  \
+           _FP_FRAC_DEC_4(X, T);                               \
+           R##_f[0] += q;                                      \
+         }                                                     \
+       _FP_FRAC_SLL_4(X, 1);                                   \
+       q >>= 1;                                                \
+      }                                                                \
+    if (!_FP_FRAC_ZEROP_4(X))                                  \
+      {                                                                \
+       if (_FP_FRAC_GT_4(X,S))                                 \
+         R##_f[0] |= _FP_WORK_ROUND;                           \
+       R##_f[0] |= _FP_WORK_STICKY;                            \
+      }                                                                \
+  } while (0)
+
+
+/*
+ * Internals 
+ */
+
+#define __FP_FRAC_SET_4(X,I3,I2,I1,I0)                                 \
+  (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
+
+#ifndef __FP_FRAC_ADD_3
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)            \
+  do {                                                         \
+    _FP_W_TYPE _c1, _c2;                                       \
+    r0 = x0 + y0;                                              \
+    _c1 = r0 < x0;                                             \
+    r1 = x1 + y1;                                              \
+    _c2 = r1 < x1;                                             \
+    r1 += _c1;                                                 \
+    _c2 |= r1 < _c1;                                           \
+    r2 = x2 + y2 + _c2;                                                \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_ADD_4
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)   \
+  do {                                                         \
+    _FP_W_TYPE _c1, _c2, _c3;                                  \
+    r0 = x0 + y0;                                              \
+    _c1 = r0 < x0;                                             \
+    r1 = x1 + y1;                                              \
+    _c2 = r1 < x1;                                             \
+    r1 += _c1;                                                 \
+    _c2 |= r1 < _c1;                                           \
+    r2 = x2 + y2;                                              \
+    _c3 = r2 < x2;                                             \
+    r2 += _c2;                                                 \
+    _c3 |= r2 < _c2;                                           \
+    r3 = x3 + y3 + _c3;                                                \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_SUB_3
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)            \
+  do {                                                         \
+    _FP_W_TYPE _c1, _c2;                                       \
+    r0 = x0 - y0;                                              \
+    _c1 = r0 > x0;                                             \
+    r1 = x1 - y1;                                              \
+    _c2 = r1 > x1;                                             \
+    r1 -= _c1;                                                 \
+    _c2 |= r1 > _c1;                                           \
+    r2 = x2 - y2 - _c2;                                                \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_SUB_4
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)   \
+  do {                                                         \
+    _FP_W_TYPE _c1, _c2, _c3;                                  \
+    r0 = x0 - y0;                                              \
+    _c1 = r0 > x0;                                             \
+    r1 = x1 - y1;                                              \
+    _c2 = r1 > x1;                                             \
+    r1 -= _c1;                                                 \
+    _c2 |= r1 > _c1;                                           \
+    r2 = x2 - y2;                                              \
+    _c3 = r2 > x2;                                             \
+    r2 -= _c2;                                                 \
+    _c3 |= r2 > _c2;                                           \
+    r3 = x3 - y3 - _c3;                                                \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_DEC_3
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0)                             \
+  do {                                                                 \
+    UWtype _t0, _t1, _t2;                                              \
+    _t0 = x0, _t1 = x1, _t2 = x2;                                      \
+    __FP_FRAC_SUB_3 (x2, x1, x0, _t2, _t1, _t0, y2, y1, y0);           \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_DEC_4
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0)                       \
+  do {                                                                 \
+    UWtype _t0, _t1, _t2, _t3;                                         \
+    _t0 = x0, _t1 = x1, _t2 = x2, _t3 = x3;                            \
+    __FP_FRAC_SUB_4 (x3,x2,x1,x0,_t3,_t2,_t1,_t0, y3,y2,y1,y0);                \
+  } while (0)
+#endif
+
+#ifndef __FP_FRAC_ADDI_4
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
+  do {                                                                 \
+    UWtype _t;                                                         \
+    _t = ((x0 += i) < i);                                              \
+    x1 += _t; _t = (x1 < _t);                                          \
+    x2 += _t; _t = (x2 < _t);                                          \
+    x3 += _t;                                                          \
+  } while (0)
+#endif
+
+/* Convert FP values between word sizes. This appears to be more
+ * complicated than I'd have expected it to be, so these might be
+ * wrong... These macros are in any case somewhat bogus because they
+ * use information about what various FRAC_n variables look like 
+ * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
+ * the ones in op-2.h and op-1.h. 
+ */
+#define _FP_FRAC_COPY_1_4(D, S)                (D##_f = S##_f[0])
+
+#define _FP_FRAC_COPY_2_4(D, S)                        \
+do {                                           \
+  D##_f0 = S##_f[0];                           \
+  D##_f1 = S##_f[1];                           \
+} while (0)
+
+/* Assembly/disassembly for converting to/from integral types.  
+ * No shifting or overflow handled here.
+ */
+/* Put the FP value X into r, which is an integer of size rsize. */
+#define _FP_FRAC_ASSEMBLE_4(r, X, rsize)                               \
+  do {                                                                 \
+    if (rsize <= _FP_W_TYPE_SIZE)                                      \
+      r = X##_f[0];                                                    \
+    else if (rsize <= 2*_FP_W_TYPE_SIZE)                               \
+    {                                                                  \
+      r = X##_f[1];                                                    \
+      r <<= _FP_W_TYPE_SIZE;                                           \
+      r += X##_f[0];                                                   \
+    }                                                                  \
+    else                                                               \
+    {                                                                  \
+      /* I'm feeling lazy so we deal with int == 3words (implausible)*/        \
+      /* and int == 4words as a single case.                    */     \
+      r = X##_f[3];                                                    \
+      r <<= _FP_W_TYPE_SIZE;                                           \
+      r += X##_f[2];                                                   \
+      r <<= _FP_W_TYPE_SIZE;                                           \
+      r += X##_f[1];                                                   \
+      r <<= _FP_W_TYPE_SIZE;                                           \
+      r += X##_f[0];                                                   \
+    }                                                                  \
+  } while (0)
+
+/* "No disassemble Number Five!" */
+/* move an integer of size rsize into X's fractional part. We rely on
+ * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
+ * having to mask the values we store into it.
+ */
+#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize)                            \
+  do {                                                                 \
+    X##_f[0] = r;                                                      \
+    X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);  \
+    X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
+    X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
+  } while (0);
+
+#define _FP_FRAC_COPY_4_1(D, S)                        \
+do {                                           \
+  D##_f[0] = S##_f;                            \
+  D##_f[1] = D##_f[2] = D##_f[3] = 0;          \
+} while (0)
+
+#define _FP_FRAC_COPY_4_2(D, S)                        \
+do {                                           \
+  D##_f[0] = S##_f0;                           \
+  D##_f[1] = S##_f1;                           \
+  D##_f[2] = D##_f[3] = 0;                     \
+} while (0)
diff --git a/gcc/config/soft-fp/op-8.h b/gcc/config/soft-fp/op-8.h
new file mode 100644 (file)
index 0000000..e0612a5
--- /dev/null
@@ -0,0 +1,111 @@
+/* Software floating-point emulation.
+   Basic eight-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* We need just a few things from here for op-4, if we ever need some
+   other macros, they can be added. */
+#define _FP_FRAC_DECL_8(X)     _FP_W_TYPE X##_f[8]
+#define _FP_FRAC_HIGH_8(X)     (X##_f[7])
+#define _FP_FRAC_LOW_8(X)      (X##_f[0])
+#define _FP_FRAC_WORD_8(X,w)   (X##_f[w])
+
+#define _FP_FRAC_SLL_8(X,N)                                            \
+  do {                                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                                  \
+    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
+    _up = (N) % _FP_W_TYPE_SIZE;                                       \
+    _down = _FP_W_TYPE_SIZE - _up;                                     \
+    if (!_up)                                                          \
+      for (_i = 7; _i >= _skip; --_i)                                  \
+       X##_f[_i] = X##_f[_i-_skip];                                    \
+    else                                                               \
+      {                                                                        \
+       for (_i = 7; _i > _skip; --_i)                                  \
+         X##_f[_i] = X##_f[_i-_skip] << _up                            \
+                     | X##_f[_i-_skip-1] >> _down;                     \
+       X##_f[_i--] = X##_f[0] << _up;                                  \
+      }                                                                        \
+    for (; _i >= 0; --_i)                                              \
+      X##_f[_i] = 0;                                                   \
+  } while (0)
+
+#define _FP_FRAC_SRL_8(X,N)                                            \
+  do {                                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                                  \
+    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
+    _down = (N) % _FP_W_TYPE_SIZE;                                     \
+    _up = _FP_W_TYPE_SIZE - _down;                                     \
+    if (!_down)                                                                \
+      for (_i = 0; _i <= 7-_skip; ++_i)                                        \
+       X##_f[_i] = X##_f[_i+_skip];                                    \
+    else                                                               \
+      {                                                                        \
+       for (_i = 0; _i < 7-_skip; ++_i)                                \
+         X##_f[_i] = X##_f[_i+_skip] >> _down                          \
+                     | X##_f[_i+_skip+1] << _up;                       \
+       X##_f[_i++] = X##_f[7] >> _down;                                \
+      }                                                                        \
+    for (; _i < 8; ++_i)                                               \
+      X##_f[_i] = 0;                                                   \
+  } while (0)
+
+
+/* Right shift with sticky-lsb. 
+ * What this actually means is that we do a standard right-shift,
+ * but that if any of the bits that fall off the right hand side
+ * were one then we always set the LSbit.
+ */
+#define _FP_FRAC_SRS_8(X,N,size)                                       \
+  do {                                                                 \
+    _FP_I_TYPE _up, _down, _skip, _i;                                  \
+    _FP_W_TYPE _s;                                                     \
+    _skip = (N) / _FP_W_TYPE_SIZE;                                     \
+    _down = (N) % _FP_W_TYPE_SIZE;                                     \
+    _up = _FP_W_TYPE_SIZE - _down;                                     \
+    for (_s = _i = 0; _i < _skip; ++_i)                                        \
+      _s |= X##_f[_i];                                                 \
+    if (!_down)                                                                \
+      for (_i = 0; _i <= 7-_skip; ++_i)                                        \
+       X##_f[_i] = X##_f[_i+_skip];                                    \
+    else                                                               \
+      {                                                                        \
+       _s |= X##_f[_i] << _up;                                         \
+       for (_i = 0; _i < 7-_skip; ++_i)                                \
+         X##_f[_i] = X##_f[_i+_skip] >> _down                          \
+                     | X##_f[_i+_skip+1] << _up;                       \
+       X##_f[_i++] = X##_f[7] >> _down;                                \
+      }                                                                        \
+    for (; _i < 8; ++_i)                                               \
+      X##_f[_i] = 0;                                                   \
+    /* don't fix the LSB until the very end when we're sure f[0] is stable */  \
+    X##_f[0] |= (_s != 0);                                             \
+  } while (0)
+
diff --git a/gcc/config/soft-fp/op-common.h b/gcc/config/soft-fp/op-common.h
new file mode 100644 (file)
index 0000000..4ec7fad
--- /dev/null
@@ -0,0 +1,1330 @@
+/* Software floating-point emulation. Common operations.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define _FP_DECL(wc, X)                                                \
+  _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e;      \
+  _FP_FRAC_DECL_##wc(X)
+
+/*
+ * Finish truely unpacking a native fp value by classifying the kind
+ * of fp value and normalizing both the exponent and the fraction.
+ */
+
+#define _FP_UNPACK_CANONICAL(fs, wc, X)                                        \
+do {                                                                   \
+  switch (X##_e)                                                       \
+  {                                                                    \
+  default:                                                             \
+    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;                     \
+    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);                                        \
+    X##_e -= _FP_EXPBIAS_##fs;                                         \
+    X##_c = FP_CLS_NORMAL;                                             \
+    break;                                                             \
+                                                                       \
+  case 0:                                                              \
+    if (_FP_FRAC_ZEROP_##wc(X))                                                \
+      X##_c = FP_CLS_ZERO;                                             \
+    else                                                               \
+      {                                                                        \
+       /* a denormalized number */                                     \
+       _FP_I_TYPE _shift;                                              \
+       _FP_FRAC_CLZ_##wc(_shift, X);                                   \
+       _shift -= _FP_FRACXBITS_##fs;                                   \
+       _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));                    \
+       X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;                         \
+       X##_c = FP_CLS_NORMAL;                                          \
+       FP_SET_EXCEPTION(FP_EX_DENORM);                                 \
+      }                                                                        \
+    break;                                                             \
+                                                                       \
+  case _FP_EXPMAX_##fs:                                                        \
+    if (_FP_FRAC_ZEROP_##wc(X))                                                \
+      X##_c = FP_CLS_INF;                                              \
+    else                                                               \
+      {                                                                        \
+       X##_c = FP_CLS_NAN;                                             \
+       /* Check for signaling NaN */                                   \
+       if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))            \
+         FP_SET_EXCEPTION(FP_EX_INVALID);                              \
+      }                                                                        \
+    break;                                                             \
+  }                                                                    \
+} while (0)
+
+/* Finish unpacking an fp value in semi-raw mode: the mantissa is
+   shifted by _FP_WORKBITS but the implicit MSB is not inserted and
+   other classification is not done.  */
+#define _FP_UNPACK_SEMIRAW(fs, wc, X)  _FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
+
+/* A semi-raw value has overflowed to infinity.  Adjust the mantissa
+   and exponent appropriately.  */
+#define _FP_OVERFLOW_SEMIRAW(fs, wc, X)                        \
+do {                                                   \
+  if (FP_ROUNDMODE == FP_RND_NEAREST                   \
+      || (FP_ROUNDMODE == FP_RND_PINF && !X##_s)       \
+      || (FP_ROUNDMODE == FP_RND_MINF && X##_s))       \
+    {                                                  \
+      X##_e = _FP_EXPMAX_##fs;                         \
+      _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);         \
+    }                                                  \
+  else                                                 \
+    {                                                  \
+      X##_e = _FP_EXPMAX_##fs - 1;                     \
+      FP_SET_EXCEPTION(FP_EX_OVERFLOW);                        \
+      FP_SET_EXCEPTION(FP_EX_INEXACT);                 \
+      _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);          \
+    }                                                  \
+} while (0)
+
+/* Check for a semi-raw value being a signaling NaN and raise the
+   invalid exception if so.  */
+#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X)                    \
+do {                                                           \
+  if (X##_e == _FP_EXPMAX_##fs                                 \
+      && !_FP_FRAC_ZEROP_##wc(X)                               \
+      && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs))       \
+    FP_SET_EXCEPTION(FP_EX_INVALID);                           \
+} while (0)
+
+/* Choose a NaN result from an operation on two semi-raw NaN
+   values.  */
+#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP)                     \
+do {                                                                   \
+  /* _FP_CHOOSENAN expects raw values, so shift as required.  */       \
+  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                                  \
+  _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS);                                  \
+  _FP_CHOOSENAN(fs, wc, R, X, Y, OP);                                  \
+  _FP_FRAC_SLL_##wc(R, _FP_WORKBITS);                                  \
+} while (0)
+
+/* Test whether a biased exponent is normal (not zero or maximum).  */
+#define _FP_EXP_NORMAL(fs, wc, X)      (((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
+
+/* Prepare to pack an fp value in semi-raw mode: the mantissa is
+   rounded and shifted right, with the rounding possibly increasing
+   the exponent (including changing a finite value to infinity).  */
+#define _FP_PACK_SEMIRAW(fs, wc, X)                            \
+do {                                                           \
+  _FP_ROUND(wc, X);                                            \
+  if (_FP_FRAC_HIGH_##fs(X)                                    \
+      & (_FP_OVERFLOW_##fs >> 1))                              \
+    {                                                          \
+      _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1);      \
+      X##_e++;                                                 \
+      if (X##_e == _FP_EXPMAX_##fs)                            \
+       _FP_OVERFLOW_SEMIRAW(fs, wc, X);                        \
+    }                                                          \
+  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                          \
+  if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X))   \
+    {                                                          \
+      if (X##_e == 0)                                          \
+       FP_SET_EXCEPTION(FP_EX_UNDERFLOW);                      \
+      else                                                     \
+       {                                                       \
+         if (!_FP_KEEPNANFRACP)                                \
+           {                                                   \
+             _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);           \
+             X##_s = _FP_NANSIGN_##fs;                         \
+           }                                                   \
+         else                                                  \
+           _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;      \
+       }                                                       \
+    }                                                          \
+} while (0)
+
+/*
+ * Before packing the bits back into the native fp result, take care
+ * of such mundane things as rounding and overflow.  Also, for some
+ * kinds of fp values, the original parts may not have been fully
+ * extracted -- but that is ok, we can regenerate them now.
+ */
+
+#define _FP_PACK_CANONICAL(fs, wc, X)                          \
+do {                                                           \
+  switch (X##_c)                                               \
+  {                                                            \
+  case FP_CLS_NORMAL:                                          \
+    X##_e += _FP_EXPBIAS_##fs;                                 \
+    if (X##_e > 0)                                             \
+      {                                                                \
+       _FP_ROUND(wc, X);                                       \
+       if (_FP_FRAC_OVERP_##wc(fs, X))                         \
+         {                                                     \
+           _FP_FRAC_CLEAR_OVERP_##wc(fs, X);                   \
+           X##_e++;                                            \
+         }                                                     \
+       _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                     \
+       if (X##_e >= _FP_EXPMAX_##fs)                           \
+         {                                                     \
+           /* overflow */                                      \
+           switch (FP_ROUNDMODE)                               \
+             {                                                 \
+             case FP_RND_NEAREST:                              \
+               X##_c = FP_CLS_INF;                             \
+               break;                                          \
+             case FP_RND_PINF:                                 \
+               if (!X##_s) X##_c = FP_CLS_INF;                 \
+               break;                                          \
+             case FP_RND_MINF:                                 \
+               if (X##_s) X##_c = FP_CLS_INF;                  \
+               break;                                          \
+             }                                                 \
+           if (X##_c == FP_CLS_INF)                            \
+             {                                                 \
+               /* Overflow to infinity */                      \
+               X##_e = _FP_EXPMAX_##fs;                        \
+               _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
+             }                                                 \
+           else                                                \
+             {                                                 \
+               /* Overflow to maximum normal */                \
+               X##_e = _FP_EXPMAX_##fs - 1;                    \
+               _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);         \
+             }                                                 \
+           FP_SET_EXCEPTION(FP_EX_OVERFLOW);                   \
+            FP_SET_EXCEPTION(FP_EX_INEXACT);                   \
+         }                                                     \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       /* we've got a denormalized number */                   \
+       X##_e = -X##_e + 1;                                     \
+       if (X##_e <= _FP_WFRACBITS_##fs)                        \
+         {                                                     \
+           _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);    \
+           _FP_ROUND(wc, X);                                   \
+           if (_FP_FRAC_HIGH_##fs(X)                           \
+               & (_FP_OVERFLOW_##fs >> 1))                     \
+             {                                                 \
+               X##_e = 1;                                      \
+               _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
+             }                                                 \
+           else                                                \
+             {                                                 \
+               X##_e = 0;                                      \
+               _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);             \
+               FP_SET_EXCEPTION(FP_EX_UNDERFLOW);              \
+             }                                                 \
+         }                                                     \
+       else                                                    \
+         {                                                     \
+           /* underflow to zero */                             \
+           X##_e = 0;                                          \
+           if (!_FP_FRAC_ZEROP_##wc(X))                        \
+             {                                                 \
+               _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);         \
+               _FP_ROUND(wc, X);                               \
+               _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);        \
+             }                                                 \
+           FP_SET_EXCEPTION(FP_EX_UNDERFLOW);                  \
+         }                                                     \
+      }                                                                \
+    break;                                                     \
+                                                               \
+  case FP_CLS_ZERO:                                            \
+    X##_e = 0;                                                 \
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                   \
+    break;                                                     \
+                                                               \
+  case FP_CLS_INF:                                             \
+    X##_e = _FP_EXPMAX_##fs;                                   \
+    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                   \
+    break;                                                     \
+                                                               \
+  case FP_CLS_NAN:                                             \
+    X##_e = _FP_EXPMAX_##fs;                                   \
+    if (!_FP_KEEPNANFRACP)                                     \
+      {                                                                \
+       _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);                 \
+       X##_s = _FP_NANSIGN_##fs;                               \
+      }                                                                \
+    else                                                       \
+      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;           \
+    break;                                                     \
+  }                                                            \
+} while (0)
+
+/* This one accepts raw argument and not cooked,  returns
+ * 1 if X is a signaling NaN.
+ */
+#define _FP_ISSIGNAN(fs, wc, X)                                        \
+({                                                             \
+  int __ret = 0;                                               \
+  if (X##_e == _FP_EXPMAX_##fs)                                        \
+    {                                                          \
+      if (!_FP_FRAC_ZEROP_##wc(X)                              \
+         && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))   \
+       __ret = 1;                                              \
+    }                                                          \
+  __ret;                                                       \
+})
+
+
+
+
+
+/* Addition on semi-raw values.  */
+#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)                           \
+do {                                                                    \
+  if (X##_s == Y##_s)                                                   \
+    {                                                                   \
+      /* Addition.  */                                                  \
+      R##_s = X##_s;                                                    \
+      int ediff = X##_e - Y##_e;                                        \
+      if (ediff > 0)                                                    \
+       {                                                                \
+         R##_e = X##_e;                                                 \
+         if (Y##_e == 0)                                                \
+           {                                                            \
+             /* Y is zero or denormalized.  */                          \
+             if (_FP_FRAC_ZEROP_##wc(Y))                                \
+               {                                                        \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                   \
+                 _FP_FRAC_COPY_##wc(R, X);                              \
+                 goto add_done;                                         \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+                 ediff--;                                               \
+                 if (ediff == 0)                                        \
+                   {                                                    \
+                     _FP_FRAC_ADD_##wc(R, X, Y);                        \
+                     goto add3;                                         \
+                   }                                                    \
+                 if (X##_e == _FP_EXPMAX_##fs)                          \
+                   {                                                    \
+                     _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);               \
+                     _FP_FRAC_COPY_##wc(R, X);                          \
+                     goto add_done;                                     \
+                   }                                                    \
+                 goto add1;                                             \
+               }                                                        \
+           }                                                            \
+         else if (X##_e == _FP_EXPMAX_##fs)                             \
+           {                                                            \
+             /* X is NaN or Inf, Y is normal.  */                       \
+             _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                       \
+             _FP_FRAC_COPY_##wc(R, X);                                  \
+             goto add_done;                                             \
+           }                                                            \
+                                                                        \
+         /* Insert implicit MSB of Y.  */                               \
+         _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs;                  \
+                                                                        \
+       add1:                                                            \
+         /* Shift the mantissa of Y to the right EDIFF steps;           \
+            remember to account later for the implicit MSB of X.  */    \
+         if (ediff <= _FP_WFRACBITS_##fs)                               \
+           _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs);             \
+         else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
+           _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
+         _FP_FRAC_ADD_##wc(R, X, Y);                                    \
+       }                                                                \
+      else if (ediff < 0)                                               \
+       {                                                                \
+         ediff = -ediff;                                                \
+         R##_e = Y##_e;                                                 \
+         if (X##_e == 0)                                                \
+           {                                                            \
+             /* X is zero or denormalized.  */                          \
+             if (_FP_FRAC_ZEROP_##wc(X))                                \
+               {                                                        \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                   \
+                 _FP_FRAC_COPY_##wc(R, Y);                              \
+                 goto add_done;                                         \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+                 ediff--;                                               \
+                 if (ediff == 0)                                        \
+                   {                                                    \
+                     _FP_FRAC_ADD_##wc(R, Y, X);                        \
+                     goto add3;                                         \
+                   }                                                    \
+                 if (Y##_e == _FP_EXPMAX_##fs)                          \
+                   {                                                    \
+                     _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);               \
+                     _FP_FRAC_COPY_##wc(R, Y);                          \
+                     goto add_done;                                     \
+                   }                                                    \
+                 goto add2;                                             \
+               }                                                        \
+           }                                                            \
+         else if (Y##_e == _FP_EXPMAX_##fs)                             \
+           {                                                            \
+             /* Y is NaN or Inf, X is normal.  */                       \
+             _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                       \
+             _FP_FRAC_COPY_##wc(R, Y);                                  \
+             goto add_done;                                             \
+           }                                                            \
+                                                                        \
+         /* Insert implicit MSB of X.  */                               \
+         _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs;                  \
+                                                                        \
+       add2:                                                            \
+         /* Shift the mantissa of X to the right EDIFF steps;           \
+            remember to account later for the implicit MSB of Y.  */    \
+         if (ediff <= _FP_WFRACBITS_##fs)                               \
+           _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs);             \
+         else if (!_FP_FRAC_ZEROP_##wc(X))                              \
+           _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                      \
+         _FP_FRAC_ADD_##wc(R, Y, X);                                    \
+       }                                                                \
+      else                                                              \
+       {                                                                \
+         /* ediff == 0.  */                                             \
+         if (!_FP_EXP_NORMAL(fs, wc, X))                                \
+           {                                                            \
+             if (X##_e == 0)                                            \
+               {                                                        \
+                 /* X and Y are zero or denormalized.  */               \
+                 R##_e = 0;                                             \
+                 if (_FP_FRAC_ZEROP_##wc(X))                            \
+                   {                                                    \
+                     if (!_FP_FRAC_ZEROP_##wc(Y))                       \
+                       FP_SET_EXCEPTION(FP_EX_DENORM);                  \
+                     _FP_FRAC_COPY_##wc(R, Y);                          \
+                     goto add_done;                                     \
+                   }                                                    \
+                 else if (_FP_FRAC_ZEROP_##wc(Y))                       \
+                   {                                                    \
+                     FP_SET_EXCEPTION(FP_EX_DENORM);                    \
+                     _FP_FRAC_COPY_##wc(R, X);                          \
+                     goto add_done;                                     \
+                   }                                                    \
+                 else                                                   \
+                   {                                                    \
+                     FP_SET_EXCEPTION(FP_EX_DENORM);                    \
+                     _FP_FRAC_ADD_##wc(R, X, Y);                        \
+                     if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)   \
+                       {                                                \
+                         /* Normalized result.  */                      \
+                         _FP_FRAC_HIGH_##fs(R)                          \
+                           &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;         \
+                         R##_e = 1;                                     \
+                       }                                                \
+                     goto add_done;                                     \
+                   }                                                    \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 /* X and Y are NaN or Inf.  */                         \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                   \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                   \
+                 R##_e = _FP_EXPMAX_##fs;                               \
+                 if (_FP_FRAC_ZEROP_##wc(X))                            \
+                   _FP_FRAC_COPY_##wc(R, Y);                            \
+                 else if (_FP_FRAC_ZEROP_##wc(Y))                       \
+                   _FP_FRAC_COPY_##wc(R, X);                            \
+                 else                                                   \
+                   _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP);          \
+                 goto add_done;                                         \
+               }                                                        \
+           }                                                            \
+         /* The exponents of X and Y, both normal, are equal.  The      \
+            implicit MSBs will always add to increase the               \
+            exponent.  */                                               \
+         _FP_FRAC_ADD_##wc(R, X, Y);                                    \
+         R##_e = X##_e + 1;                                             \
+         _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
+         if (R##_e == _FP_EXPMAX_##fs)                                  \
+           /* Overflow to infinity (depending on rounding mode).  */    \
+           _FP_OVERFLOW_SEMIRAW(fs, wc, R);                             \
+         goto add_done;                                                 \
+       }                                                                \
+    add3:                                                               \
+      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)                  \
+       {                                                                \
+         /* Overflow.  */                                               \
+         _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;     \
+         R##_e++;                                                       \
+         _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
+         if (R##_e == _FP_EXPMAX_##fs)                                  \
+           /* Overflow to infinity (depending on rounding mode).  */    \
+           _FP_OVERFLOW_SEMIRAW(fs, wc, R);                             \
+       }                                                                \
+    add_done: ;                                                                 \
+    }                                                                   \
+  else                                                                  \
+    {                                                                   \
+      /* Subtraction.  */                                               \
+      int ediff = X##_e - Y##_e;                                        \
+      if (ediff > 0)                                                    \
+       {                                                                \
+         R##_e = X##_e;                                                 \
+         R##_s = X##_s;                                                 \
+         if (Y##_e == 0)                                                \
+           {                                                            \
+             /* Y is zero or denormalized.  */                          \
+             if (_FP_FRAC_ZEROP_##wc(Y))                                \
+               {                                                        \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                   \
+                 _FP_FRAC_COPY_##wc(R, X);                              \
+                 goto sub_done;                                         \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+                 ediff--;                                               \
+                 if (ediff == 0)                                        \
+                   {                                                    \
+                     _FP_FRAC_SUB_##wc(R, X, Y);                        \
+                     goto sub3;                                         \
+                   }                                                    \
+                 if (X##_e == _FP_EXPMAX_##fs)                          \
+                   {                                                    \
+                     _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);               \
+                     _FP_FRAC_COPY_##wc(R, X);                          \
+                     goto sub_done;                                     \
+                   }                                                    \
+                 goto sub1;                                             \
+               }                                                        \
+           }                                                            \
+         else if (X##_e == _FP_EXPMAX_##fs)                             \
+           {                                                            \
+             /* X is NaN or Inf, Y is normal.  */                       \
+             _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                       \
+             _FP_FRAC_COPY_##wc(R, X);                                  \
+             goto sub_done;                                             \
+           }                                                            \
+                                                                        \
+         /* Insert implicit MSB of Y.  */                               \
+         _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs;                  \
+                                                                        \
+       sub1:                                                            \
+         /* Shift the mantissa of Y to the right EDIFF steps;           \
+            remember to account later for the implicit MSB of X.  */    \
+         if (ediff <= _FP_WFRACBITS_##fs)                               \
+           _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs);             \
+         else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
+           _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
+         _FP_FRAC_SUB_##wc(R, X, Y);                                    \
+       }                                                                \
+      else if (ediff < 0)                                               \
+       {                                                                \
+         ediff = -ediff;                                                \
+         R##_e = Y##_e;                                                 \
+         R##_s = Y##_s;                                                 \
+         if (X##_e == 0)                                                \
+           {                                                            \
+             /* X is zero or denormalized.  */                          \
+             if (_FP_FRAC_ZEROP_##wc(X))                                \
+               {                                                        \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                   \
+                 _FP_FRAC_COPY_##wc(R, Y);                              \
+                 goto sub_done;                                         \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 FP_SET_EXCEPTION(FP_EX_DENORM);                        \
+                 ediff--;                                               \
+                 if (ediff == 0)                                        \
+                   {                                                    \
+                     _FP_FRAC_SUB_##wc(R, Y, X);                        \
+                     goto sub3;                                         \
+                   }                                                    \
+                 if (Y##_e == _FP_EXPMAX_##fs)                          \
+                   {                                                    \
+                     _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);               \
+                     _FP_FRAC_COPY_##wc(R, Y);                          \
+                     goto sub_done;                                     \
+                   }                                                    \
+                 goto sub2;                                             \
+               }                                                        \
+           }                                                            \
+         else if (Y##_e == _FP_EXPMAX_##fs)                             \
+           {                                                            \
+             /* Y is NaN or Inf, X is normal.  */                       \
+             _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                       \
+             _FP_FRAC_COPY_##wc(R, Y);                                  \
+             goto sub_done;                                             \
+           }                                                            \
+                                                                        \
+         /* Insert implicit MSB of X.  */                               \
+         _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs;                  \
+                                                                        \
+       sub2:                                                            \
+         /* Shift the mantissa of X to the right EDIFF steps;           \
+            remember to account later for the implicit MSB of Y.  */    \
+         if (ediff <= _FP_WFRACBITS_##fs)                               \
+           _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs);             \
+         else if (!_FP_FRAC_ZEROP_##wc(X))                              \
+           _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                      \
+         _FP_FRAC_SUB_##wc(R, Y, X);                                    \
+       }                                                                \
+      else                                                              \
+       {                                                                \
+         /* ediff == 0.  */                                             \
+         if (!_FP_EXP_NORMAL(fs, wc, X))                                \
+           {                                                            \
+             if (X##_e == 0)                                            \
+               {                                                        \
+                 /* X and Y are zero or denormalized.  */               \
+                 R##_e = 0;                                             \
+                 if (_FP_FRAC_ZEROP_##wc(X))                            \
+                   {                                                    \
+                     _FP_FRAC_COPY_##wc(R, Y);                          \
+                     if (_FP_FRAC_ZEROP_##wc(Y))                        \
+                       R##_s = (FP_ROUNDMODE == FP_RND_MINF);           \
+                     else                                               \
+                       {                                                \
+                         FP_SET_EXCEPTION(FP_EX_DENORM);                \
+                         R##_s = Y##_s;                                 \
+                       }                                                \
+                     goto sub_done;                                     \
+                   }                                                    \
+                 else if (_FP_FRAC_ZEROP_##wc(Y))                       \
+                   {                                                    \
+                     FP_SET_EXCEPTION(FP_EX_DENORM);                    \
+                     _FP_FRAC_COPY_##wc(R, X);                          \
+                     R##_s = X##_s;                                     \
+                     goto sub_done;                                     \
+                   }                                                    \
+                 else                                                   \
+                   {                                                    \
+                     FP_SET_EXCEPTION(FP_EX_DENORM);                    \
+                     _FP_FRAC_SUB_##wc(R, X, Y);                        \
+                     R##_s = X##_s;                                     \
+                     if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)   \
+                       {                                                \
+                         /* |X| < |Y|, negate result.  */               \
+                         _FP_FRAC_SUB_##wc(R, Y, X);                    \
+                         R##_s = Y##_s;                                 \
+                       }                                                \
+                     else if (_FP_FRAC_ZEROP_##wc(R))                   \
+                       R##_s = (FP_ROUNDMODE == FP_RND_MINF);           \
+                     goto sub_done;                                     \
+                   }                                                    \
+               }                                                        \
+             else                                                       \
+               {                                                        \
+                 /* X and Y are NaN or Inf, of opposite signs.  */      \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);                   \
+                 _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);                   \
+                 R##_e = _FP_EXPMAX_##fs;                               \
+                 if (_FP_FRAC_ZEROP_##wc(X))                            \
+                   {                                                    \
+                     if (_FP_FRAC_ZEROP_##wc(Y))                        \
+                       {                                                \
+                         /* Inf - Inf.  */                              \
+                         R##_s = _FP_NANSIGN_##fs;                      \
+                         _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);        \
+                         _FP_FRAC_SLL_##wc(R, _FP_WORKBITS);            \
+                         FP_SET_EXCEPTION(FP_EX_INVALID);               \
+                       }                                                \
+                     else                                               \
+                       {                                                \
+                         /* Inf - NaN.  */                              \
+                         R##_s = Y##_s;                                 \
+                         _FP_FRAC_COPY_##wc(R, Y);                      \
+                       }                                                \
+                   }                                                    \
+                 else                                                   \
+                   {                                                    \
+                     if (_FP_FRAC_ZEROP_##wc(Y))                        \
+                       {                                                \
+                         /* NaN - Inf.  */                              \
+                         R##_s = X##_s;                                 \
+                         _FP_FRAC_COPY_##wc(R, X);                      \
+                       }                                                \
+                     else                                               \
+                       {                                                \
+                         /* NaN - NaN.  */                              \
+                         _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP);    \
+                       }                                                \
+                   }                                                    \
+                 goto sub_done;                                         \
+               }                                                        \
+           }                                                            \
+         /* The exponents of X and Y, both normal, are equal.  The      \
+            implicit MSBs cancel.  */                                   \
+         R##_e = X##_e;                                                 \
+         _FP_FRAC_SUB_##wc(R, X, Y);                                    \
+         R##_s = X##_s;                                                 \
+         if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)               \
+           {                                                            \
+             /* |X| < |Y|, negate result.  */                           \
+             _FP_FRAC_SUB_##wc(R, Y, X);                                \
+             R##_s = Y##_s;                                             \
+           }                                                            \
+         else if (_FP_FRAC_ZEROP_##wc(R))                               \
+           {                                                            \
+             R##_e = 0;                                                 \
+             R##_s = (FP_ROUNDMODE == FP_RND_MINF);                     \
+             goto sub_done;                                             \
+           }                                                            \
+         goto norm;                                                     \
+       }                                                                \
+    sub3:                                                               \
+      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)                  \
+       {                                                                \
+         int diff;                                                      \
+         /* Carry into most significant bit of larger one of X and Y,   \
+            canceling it; renormalize.  */                              \
+         _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1;              \
+       norm:                                                            \
+         _FP_FRAC_CLZ_##wc(diff, R);                                    \
+         diff -= _FP_WFRACXBITS_##fs;                                   \
+         _FP_FRAC_SLL_##wc(R, diff);                                    \
+         if (R##_e <= diff)                                             \
+           {                                                            \
+             /* R is denormalized.  */                                  \
+             diff = diff - R##_e + 1;                                   \
+             _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs);            \
+             R##_e = 0;                                                 \
+           }                                                            \
+         else                                                           \
+           {                                                            \
+             R##_e -= diff;                                             \
+             _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
+           }                                                            \
+       }                                                                \
+    sub_done: ;                                                                 \
+    }                                                                   \
+} while (0)
+
+#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
+#define _FP_SUB(fs, wc, R, X, Y)                                           \
+  do {                                                                     \
+    if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
+    _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');                                \
+  } while (0)
+
+
+/*
+ * Main negation routine.  FIXME -- when we care about setting exception
+ * bits reliably, this will not do.  We should examine all of the fp classes.
+ */
+
+#define _FP_NEG(fs, wc, R, X)          \
+  do {                                 \
+    _FP_FRAC_COPY_##wc(R, X);          \
+    R##_c = X##_c;                     \
+    R##_e = X##_e;                     \
+    R##_s = 1 ^ X##_s;                 \
+  } while (0)
+
+
+/*
+ * Main multiplication routine.  The input values should be cooked.
+ */
+
+#define _FP_MUL(fs, wc, R, X, Y)                       \
+do {                                                   \
+  R##_s = X##_s ^ Y##_s;                               \
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))               \
+  {                                                    \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):   \
+    R##_c = FP_CLS_NORMAL;                             \
+    R##_e = X##_e + Y##_e + 1;                         \
+                                                       \
+    _FP_MUL_MEAT_##fs(R,X,Y);                          \
+                                                       \
+    if (_FP_FRAC_OVERP_##wc(fs, R))                    \
+      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);     \
+    else                                               \
+      R##_e--;                                         \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):         \
+    _FP_CHOOSENAN(fs, wc, R, X, Y, '*');               \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):      \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):         \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                \
+    R##_s = X##_s;                                     \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):     \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):       \
+    _FP_FRAC_COPY_##wc(R, X);                          \
+    R##_c = X##_c;                                     \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):      \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):         \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                \
+    R##_s = Y##_s;                                     \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):      \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
+    _FP_FRAC_COPY_##wc(R, Y);                          \
+    R##_c = Y##_c;                                     \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                \
+    R##_s = _FP_NANSIGN_##fs;                          \
+    R##_c = FP_CLS_NAN;                                        \
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
+    FP_SET_EXCEPTION(FP_EX_INVALID);                   \
+    break;                                             \
+                                                       \
+  default:                                             \
+    abort();                                           \
+  }                                                    \
+} while (0)
+
+
+/*
+ * Main division routine.  The input values should be cooked.
+ */
+
+#define _FP_DIV(fs, wc, R, X, Y)                       \
+do {                                                   \
+  R##_s = X##_s ^ Y##_s;                               \
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))               \
+  {                                                    \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):   \
+    R##_c = FP_CLS_NORMAL;                             \
+    R##_e = X##_e - Y##_e;                             \
+                                                       \
+    _FP_DIV_MEAT_##fs(R,X,Y);                          \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):         \
+    _FP_CHOOSENAN(fs, wc, R, X, Y, '/');               \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):      \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):         \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                \
+    R##_s = X##_s;                                     \
+    _FP_FRAC_COPY_##wc(R, X);                          \
+    R##_c = X##_c;                                     \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):      \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):         \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                \
+    R##_s = Y##_s;                                     \
+    _FP_FRAC_COPY_##wc(R, Y);                          \
+    R##_c = Y##_c;                                     \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):      \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):     \
+    R##_c = FP_CLS_ZERO;                               \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
+    FP_SET_EXCEPTION(FP_EX_DIVZERO);                   \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
+    R##_c = FP_CLS_INF;                                        \
+    break;                                             \
+                                                       \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):       \
+    R##_s = _FP_NANSIGN_##fs;                          \
+    R##_c = FP_CLS_NAN;                                        \
+    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);            \
+    FP_SET_EXCEPTION(FP_EX_INVALID);                   \
+    break;                                             \
+                                                       \
+  default:                                             \
+    abort();                                           \
+  }                                                    \
+} while (0)
+
+
+/*
+ * Main differential comparison routine.  The inputs should be raw not
+ * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
+ */
+
+#define _FP_CMP(fs, wc, ret, X, Y, un)                                 \
+  do {                                                                 \
+    /* NANs are unordered */                                           \
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))          \
+       || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))       \
+      {                                                                        \
+       ret = un;                                                       \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       int __is_zero_x;                                                \
+       int __is_zero_y;                                                \
+                                                                       \
+       __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;       \
+       __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;       \
+                                                                       \
+       if (__is_zero_x && __is_zero_y)                                 \
+               ret = 0;                                                \
+       else if (__is_zero_x)                                           \
+               ret = Y##_s ? 1 : -1;                                   \
+       else if (__is_zero_y)                                           \
+               ret = X##_s ? -1 : 1;                                   \
+       else if (X##_s != Y##_s)                                        \
+         ret = X##_s ? -1 : 1;                                         \
+       else if (X##_e > Y##_e)                                         \
+         ret = X##_s ? -1 : 1;                                         \
+       else if (X##_e < Y##_e)                                         \
+         ret = X##_s ? 1 : -1;                                         \
+       else if (_FP_FRAC_GT_##wc(X, Y))                                \
+         ret = X##_s ? -1 : 1;                                         \
+       else if (_FP_FRAC_GT_##wc(Y, X))                                \
+         ret = X##_s ? 1 : -1;                                         \
+       else                                                            \
+         ret = 0;                                                      \
+      }                                                                        \
+  } while (0)
+
+
+/* Simplification for strict equality.  */
+
+#define _FP_CMP_EQ(fs, wc, ret, X, Y)                                      \
+  do {                                                                     \
+    /* NANs are unordered */                                               \
+    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))              \
+       || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))           \
+      {                                                                            \
+       ret = 1;                                                            \
+      }                                                                            \
+    else                                                                   \
+      {                                                                            \
+       ret = !(X##_e == Y##_e                                              \
+               && _FP_FRAC_EQ_##wc(X, Y)                                   \
+               && (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
+      }                                                                            \
+  } while (0)
+
+/* Version to test unordered.  */
+
+#define _FP_CMP_UNORD(fs, wc, ret, X, Y)                               \
+  do {                                                                 \
+    ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))       \
+          || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)));   \
+  } while (0)
+
+/*
+ * Main square root routine.  The input value should be cooked.
+ */
+
+#define _FP_SQRT(fs, wc, R, X)                                         \
+do {                                                                   \
+    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);                      \
+    _FP_W_TYPE q;                                                      \
+    switch (X##_c)                                                     \
+    {                                                                  \
+    case FP_CLS_NAN:                                                   \
+       _FP_FRAC_COPY_##wc(R, X);                                       \
+       R##_s = X##_s;                                                  \
+       R##_c = FP_CLS_NAN;                                             \
+       break;                                                          \
+    case FP_CLS_INF:                                                   \
+       if (X##_s)                                                      \
+         {                                                             \
+           R##_s = _FP_NANSIGN_##fs;                                   \
+           R##_c = FP_CLS_NAN; /* NAN */                               \
+           _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
+           FP_SET_EXCEPTION(FP_EX_INVALID);                            \
+         }                                                             \
+       else                                                            \
+         {                                                             \
+           R##_s = 0;                                                  \
+           R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */                 \
+         }                                                             \
+       break;                                                          \
+    case FP_CLS_ZERO:                                                  \
+       R##_s = X##_s;                                                  \
+       R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                      \
+       break;                                                          \
+    case FP_CLS_NORMAL:                                                        \
+       R##_s = 0;                                                      \
+        if (X##_s)                                                     \
+          {                                                            \
+           R##_c = FP_CLS_NAN; /* sNAN */                              \
+           R##_s = _FP_NANSIGN_##fs;                                   \
+           _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
+           FP_SET_EXCEPTION(FP_EX_INVALID);                            \
+           break;                                                      \
+          }                                                            \
+       R##_c = FP_CLS_NORMAL;                                          \
+        if (X##_e & 1)                                                 \
+          _FP_FRAC_SLL_##wc(X, 1);                                     \
+        R##_e = X##_e >> 1;                                            \
+        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);                       \
+        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);                       \
+        q = _FP_OVERFLOW_##fs >> 1;                                    \
+        _FP_SQRT_MEAT_##wc(R, S, T, X, q);                             \
+    }                                                                  \
+  } while (0)
+
+/*
+ * Convert from FP to integer.  Input is raw.
+ */
+
+/* RSIGNED can have following values:
+ * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
+ *     the result is either 0 or (2^rsize)-1 depending on the sign in such
+ *     case.
+ * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
+ *     NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
+ *     depending on the sign in such case.
+ * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
+ *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
+ *     depending on the sign in such case.
+ */
+#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                       \
+do {                                                                   \
+  if (X##_e < _FP_EXPBIAS_##fs)                                                \
+    {                                                                  \
+      r = 0;                                                           \
+      if (X##_e == 0)                                                  \
+       {                                                               \
+         if (!_FP_FRAC_ZEROP_##wc(X))                                  \
+           {                                                           \
+             FP_SET_EXCEPTION(FP_EX_INEXACT);                          \
+             FP_SET_EXCEPTION(FP_EX_DENORM);                           \
+           }                                                           \
+       }                                                               \
+      else                                                             \
+       FP_SET_EXCEPTION(FP_EX_INEXACT);                                \
+    }                                                                  \
+  else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s)  \
+          || (!rsigned && X##_s))                                      \
+    {                                                                  \
+      /* Overflow or converting to the most negative integer.  */      \
+      if (rsigned)                                                     \
+       {                                                               \
+         r = 1;                                                        \
+         r <<= rsize - 1;                                              \
+         r -= 1 - X##_s;                                               \
+       } else {                                                        \
+         r = 0;                                                        \
+         if (X##_s)                                                    \
+           r = ~r;                                                     \
+       }                                                               \
+                                                                       \
+      if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1)   \
+       {                                                               \
+         /* Possibly converting to most negative integer; check the    \
+            mantissa.  */                                              \
+         int inexact = 0;                                              \
+         (void)((_FP_FRACBITS_##fs > rsize)                            \
+                ? ({ _FP_FRAC_SRST_##wc(X, inexact,                    \
+                                        _FP_FRACBITS_##fs - rsize,     \
+                                        _FP_FRACBITS_##fs); 0; })      \
+                : 0);                                                  \
+         if (!_FP_FRAC_ZEROP_##wc(X))                                  \
+           FP_SET_EXCEPTION(FP_EX_INVALID);                            \
+         else if (inexact)                                             \
+           FP_SET_EXCEPTION(FP_EX_INEXACT);                            \
+       }                                                               \
+      else                                                             \
+       FP_SET_EXCEPTION(FP_EX_INVALID);                                \
+    }                                                                  \
+  else                                                                 \
+    {                                                                  \
+      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;                   \
+      if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)           \
+       {                                                               \
+         _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                          \
+         r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         int inexact;                                                  \
+         _FP_FRAC_SRST_##wc(X, inexact,                                \
+                           (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1   \
+                            - X##_e),                                  \
+                           _FP_FRACBITS_##fs);                         \
+         if (inexact)                                                  \
+           FP_SET_EXCEPTION(FP_EX_INEXACT);                            \
+         _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                          \
+       }                                                               \
+      if (rsigned && X##_s)                                            \
+       r = -r;                                                         \
+    }                                                                  \
+} while (0)
+
+/* Convert integer to fp.  Output is raw.  RTYPE is unsigned even if
+   input is signed.  */
+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                            \
+  do {                                                                      \
+    if (r)                                                                  \
+      {                                                                             \
+       rtype ur_;                                                           \
+                                                                            \
+       if ((X##_s = (r < 0)))                                               \
+         r = -(rtype)r;                                                     \
+                                                                            \
+       ur_ = (rtype) r;                                                     \
+       (void)((rsize <= _FP_W_TYPE_SIZE)                                    \
+              ? ({                                                          \
+                   int lz_;                                                 \
+                   __FP_CLZ(lz_, (_FP_W_TYPE)ur_);                          \
+                   X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_;    \
+                 })                                                         \
+              : ((rsize <= 2 * _FP_W_TYPE_SIZE)                             \
+                 ? ({                                                       \
+                      int lz_;                                              \
+                      __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
+                                 (_FP_W_TYPE)ur_);                          \
+                      X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1   \
+                               - lz_);                                      \
+                    })                                                      \
+                 : (abort(), 0)));                                          \
+                                                                            \
+       if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs                  \
+           && X##_e >= _FP_EXPMAX_##fs)                                     \
+         {                                                                  \
+           /* Exponent too big; overflow to infinity.  (May also            \
+              happen after rounding below.)  */                             \
+           _FP_OVERFLOW_SEMIRAW(fs, wc, X);                                 \
+           goto pack_semiraw;                                               \
+         }                                                                  \
+                                                                            \
+       if (rsize <= _FP_FRACBITS_##fs                                       \
+           || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs)                 \
+         {                                                                  \
+           /* Exactly representable; shift left.  */                        \
+           _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);                        \
+           _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs                           \
+                                 + _FP_FRACBITS_##fs - 1 - X##_e));         \
+         }                                                                  \
+       else                                                                 \
+         {                                                                  \
+           /* More bits in integer than in floating type; need to           \
+              round.  */                                                    \
+           if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e)           \
+             ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs                       \
+                             - _FP_WFRACBITS_##fs + 1))                     \
+                    | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs           \
+                                         - _FP_WFRACBITS_##fs + 1)))        \
+                       != 0));                                              \
+           _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);                        \
+           if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0)     \
+             _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs                         \
+                                   + _FP_WFRACBITS_##fs - 1 - X##_e));      \
+           _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;       \
+         pack_semiraw:                                                      \
+           _FP_PACK_SEMIRAW(fs, wc, X);                                     \
+         }                                                                  \
+      }                                                                             \
+    else                                                                    \
+      {                                                                             \
+       X##_s = 0;                                                           \
+       X##_e = 0;                                                           \
+       _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                             \
+      }                                                                             \
+  } while (0)
+
+
+/* Extend from a narrower floating-point format to a wider one.  Input
+   and output are raw.  */
+#define FP_EXTEND(dfs,sfs,dwc,swc,D,S)                                  \
+do {                                                                    \
+  if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs                           \
+      || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs                          \
+         < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs)                        \
+      || _FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1) \
+    abort();                                                            \
+  D##_s = S##_s;                                                        \
+  _FP_FRAC_COPY_##dwc##_##swc(D, S);                                    \
+  if (_FP_EXP_NORMAL(sfs, swc, S))                                      \
+    {                                                                   \
+      D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;            \
+      _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs));         \
+    }                                                                   \
+  else                                                                  \
+    {                                                                   \
+      if (S##_e == 0)                                                   \
+       {                                                                \
+         if (_FP_FRAC_ZEROP_##swc(S))                                   \
+           D##_e = 0;                                                   \
+         else                                                           \
+           {                                                            \
+             int _lz;                                                   \
+             FP_SET_EXCEPTION(FP_EX_DENORM);                            \
+             _FP_FRAC_CLZ_##swc(_lz, S);                                \
+             _FP_FRAC_SLL_##dwc(D,                                      \
+                                _lz + _FP_FRACBITS_##dfs                \
+                                - _FP_FRACTBITS_##sfs);                 \
+             D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1         \
+                      + _FP_FRACXBITS_##sfs - _lz);                     \
+           }                                                            \
+       }                                                                \
+      else                                                              \
+       {                                                                \
+         D##_e = _FP_EXPMAX_##dfs;                                      \
+         if (!_FP_FRAC_ZEROP_##swc(S))                                  \
+           {                                                            \
+             if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs))     \
+               FP_SET_EXCEPTION(FP_EX_INVALID);                         \
+             _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs                  \
+                                    - _FP_FRACBITS_##sfs));             \
+           }                                                            \
+       }                                                                \
+    }                                                                   \
+} while (0)
+
+/* Truncate from a wider floating-point format to a narrower one.
+   Input and output are semi-raw.  */
+#define FP_TRUNC(dfs,sfs,dwc,swc,D,S)                                       \
+do {                                                                        \
+  if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs                               \
+      || _FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)     \
+    abort();                                                                \
+  D##_s = S##_s;                                                            \
+  if (_FP_EXP_NORMAL(sfs, swc, S))                                          \
+    {                                                                       \
+      D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;                \
+      if (D##_e >= _FP_EXPMAX_##dfs)                                        \
+       _FP_OVERFLOW_SEMIRAW(dfs, dwc, D);                                   \
+      else                                                                  \
+       {                                                                    \
+         if (D##_e <= 0)                                                    \
+           {                                                                \
+             if (D##_e <= 1 - _FP_FRACBITS_##dfs)                           \
+               _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc);                   \
+             else                                                           \
+               {                                                            \
+                 _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs;            \
+                 _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs                 \
+                                        - _FP_WFRACBITS_##dfs + 1 - D##_e), \
+                                    _FP_WFRACBITS_##sfs);                   \
+               }                                                            \
+             D##_e = 0;                                                     \
+           }                                                                \
+         else                                                               \
+           _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs                       \
+                                  - _FP_WFRACBITS_##dfs),                   \
+                              _FP_WFRACBITS_##sfs);                         \
+         _FP_FRAC_COPY_##dwc##_##swc(D, S);                                 \
+       }                                                                    \
+    }                                                                       \
+  else                                                                      \
+    {                                                                       \
+      if (S##_e == 0)                                                       \
+       {                                                                    \
+         D##_e = 0;                                                         \
+         _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);                         \
+         if (!_FP_FRAC_ZEROP_##swc(S))                                      \
+           {                                                                \
+             FP_SET_EXCEPTION(FP_EX_DENORM);                                \
+             FP_SET_EXCEPTION(FP_EX_INEXACT);                               \
+           }                                                                \
+       }                                                                    \
+      else                                                                  \
+       {                                                                    \
+         D##_e = _FP_EXPMAX_##dfs;                                          \
+         if (_FP_FRAC_ZEROP_##swc(S))                                       \
+           _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);                       \
+         else                                                               \
+           {                                                                \
+             _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S);                         \
+             _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs                     \
+                                    - _FP_WFRACBITS_##dfs));                \
+             _FP_FRAC_COPY_##dwc##_##swc(D, S);                             \
+             _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs;                \
+           }                                                                \
+       }                                                                    \
+    }                                                                       \
+} while (0)
+
+/*
+ * Helper primitives.
+ */
+
+/* Count leading zeros in a word.  */
+
+#ifndef __FP_CLZ
+/* GCC 3.4 and later provide the builtins for us.  */
+#define __FP_CLZ(r, x)                                                       \
+  do {                                                                       \
+    if (sizeof (_FP_W_TYPE) == sizeof (unsigned int))                        \
+      r = __builtin_clz (x);                                                 \
+    else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long))                  \
+      r = __builtin_clzl (x);                                                \
+    else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long))             \
+      r = __builtin_clzll (x);                                               \
+    else                                                                     \
+      abort ();                                                                      \
+  } while (0)
+#endif /* ndef __FP_CLZ */
+
+#define _FP_DIV_HELP_imm(q, r, n, d)           \
+  do {                                         \
+    q = n / d, r = n % d;                      \
+  } while (0)
+
+
+/* A restoring bit-by-bit division primitive.  */
+
+#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y)                           \
+  do {                                                                 \
+    int count = _FP_WFRACBITS_##fs;                                    \
+    _FP_FRAC_DECL_##wc (u);                                            \
+    _FP_FRAC_DECL_##wc (v);                                            \
+    _FP_FRAC_COPY_##wc (u, X);                                         \
+    _FP_FRAC_COPY_##wc (v, Y);                                         \
+    _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);                          \
+    /* Normalize U and V.  */                                          \
+    _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs);                                \
+    _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs);                                \
+    /* First round.  Since the operands are normalized, either the     \
+       first or second bit will be set in the fraction.  Produce a     \
+       normalized result by checking which and adjusting the loop      \
+       count and exponent accordingly.  */                             \
+    if (_FP_FRAC_GE_1 (u, v))                                          \
+      {                                                                        \
+       _FP_FRAC_SUB_##wc (u, u, v);                                    \
+       _FP_FRAC_LOW_##wc (R) |= 1;                                     \
+       count--;                                                        \
+      }                                                                        \
+    else                                                               \
+      R##_e--;                                                         \
+    /* Subsequent rounds.  */                                          \
+    do {                                                               \
+      int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0;              \
+      _FP_FRAC_SLL_##wc (u, 1);                                                \
+      _FP_FRAC_SLL_##wc (R, 1);                                                \
+      if (msb || _FP_FRAC_GE_1 (u, v))                                 \
+       {                                                               \
+         _FP_FRAC_SUB_##wc (u, u, v);                                  \
+         _FP_FRAC_LOW_##wc (R) |= 1;                                   \
+       }                                                               \
+    } while (--count > 0);                                             \
+    /* If there's anything left in U, the result is inexact.  */       \
+    _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u);                 \
+  } while (0)
+
+#define _FP_DIV_MEAT_1_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
+#define _FP_DIV_MEAT_2_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
+#define _FP_DIV_MEAT_4_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
diff --git a/gcc/config/soft-fp/quad.h b/gcc/config/soft-fp/quad.h
new file mode 100644 (file)
index 0000000..d7840ff
--- /dev/null
@@ -0,0 +1,271 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Quad Precision.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel, kid. Go buy yourself a real computer."
+#endif
+
+#if _FP_W_TYPE_SIZE < 64
+#define _FP_FRACTBITS_Q         (4*_FP_W_TYPE_SIZE)
+#else
+#define _FP_FRACTBITS_Q                (2*_FP_W_TYPE_SIZE)
+#endif
+
+#define _FP_FRACBITS_Q         113
+#define _FP_FRACXBITS_Q                (_FP_FRACTBITS_Q - _FP_FRACBITS_Q)
+#define _FP_WFRACBITS_Q                (_FP_WORKBITS + _FP_FRACBITS_Q)
+#define _FP_WFRACXBITS_Q       (_FP_FRACTBITS_Q - _FP_WFRACBITS_Q)
+#define _FP_EXPBITS_Q          15
+#define _FP_EXPBIAS_Q          16383
+#define _FP_EXPMAX_Q           32767
+
+#define _FP_QNANBIT_Q          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2) % _FP_W_TYPE_SIZE)
+#define _FP_QNANBIT_SH_Q               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_Q          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
+#define _FP_IMPLBIT_SH_Q               \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_Q         \
+       ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
+
+typedef float TFtype __attribute__((mode(TF)));
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_Q
+{
+   TFtype flt;
+   struct 
+   {
+#if __BYTE_ORDER == __BIG_ENDIAN
+      unsigned sign : 1;
+      unsigned exp : _FP_EXPBITS_Q;
+      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+      unsigned long frac2 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+      unsigned long frac0 : _FP_W_TYPE_SIZE;
+      unsigned long frac1 : _FP_W_TYPE_SIZE;
+      unsigned long frac2 : _FP_W_TYPE_SIZE;
+      unsigned long frac3 : _FP_FRACBITS_Q - (_FP_IMPLBIT_Q != 0)-(_FP_W_TYPE_SIZE * 3);
+      unsigned exp : _FP_EXPBITS_Q;
+      unsigned sign : 1;
+#endif /* not bigendian */
+   } bits __attribute__((packed));
+};
+
+
+#define FP_DECL_Q(X)           _FP_DECL(4,X)
+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_4(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val)        _FP_UNPACK_RAW_4_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X)   _FP_PACK_RAW_4(Q,val,X)
+#define FP_PACK_RAW_QP(val,X)          \
+  do {                                 \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_4_P(Q,val,X);       \
+  } while (0)
+
+#define FP_UNPACK_Q(X,val)             \
+  do {                                 \
+    _FP_UNPACK_RAW_4(Q,X,val);         \
+    _FP_UNPACK_CANONICAL(Q,4,X);       \
+  } while (0)
+
+#define FP_UNPACK_QP(X,val)            \
+  do {                                 \
+    _FP_UNPACK_RAW_4_P(Q,X,val);       \
+    _FP_UNPACK_CANONICAL(Q,4,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_Q(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_4(Q,X,val);         \
+    _FP_UNPACK_SEMIRAW(Q,4,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_QP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_4_P(Q,X,val);       \
+    _FP_UNPACK_SEMIRAW(Q,4,X);         \
+  } while (0)
+
+#define FP_PACK_Q(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(Q,4,X);         \
+    _FP_PACK_RAW_4(Q,val,X);           \
+  } while (0)
+
+#define FP_PACK_QP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(Q,4,X);         \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_4_P(Q,val,X);       \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_Q(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(Q,4,X);           \
+    _FP_PACK_RAW_4(Q,val,X);           \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_QP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(Q,4,X);           \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_4_P(Q,val,X);       \
+  } while (0)
+
+#define FP_ISSIGNAN_Q(X)               _FP_ISSIGNAN(Q,4,X)
+#define FP_NEG_Q(R,X)                  _FP_NEG(Q,4,R,X)
+#define FP_ADD_Q(R,X,Y)                        _FP_ADD(Q,4,R,X,Y)
+#define FP_SUB_Q(R,X,Y)                        _FP_SUB(Q,4,R,X,Y)
+#define FP_MUL_Q(R,X,Y)                        _FP_MUL(Q,4,R,X,Y)
+#define FP_DIV_Q(R,X,Y)                        _FP_DIV(Q,4,R,X,Y)
+#define FP_SQRT_Q(R,X)                 _FP_SQRT(Q,4,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q)     _FP_SQRT_MEAT_4(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un)     _FP_CMP(Q,4,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y)     _FP_CMP_EQ(Q,4,r,X,Y)
+#define FP_CMP_UNORD_Q(r,X,Y)  _FP_CMP_UNORD(Q,4,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg)       _FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt)       _FP_FROM_INT(Q,4,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X)     _FP_FRAC_HIGH_4(X)
+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_4(X)
+
+#else   /* not _FP_W_TYPE_SIZE < 64 */
+union _FP_UNION_Q
+{
+  TFtype flt /* __attribute__((mode(TF))) */ ;
+  struct {
+    _FP_W_TYPE a, b;
+  } longs;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign  : 1;
+    unsigned exp   : _FP_EXPBITS_Q;
+    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+    unsigned long frac0 : _FP_W_TYPE_SIZE;
+#else
+    unsigned long frac0 : _FP_W_TYPE_SIZE;
+    unsigned long frac1 : _FP_FRACBITS_Q-(_FP_IMPLBIT_Q != 0)-_FP_W_TYPE_SIZE;
+    unsigned exp   : _FP_EXPBITS_Q;
+    unsigned sign  : 1;
+#endif
+  } bits;
+};
+
+#define FP_DECL_Q(X)           _FP_DECL(2,X)
+#define FP_UNPACK_RAW_Q(X,val) _FP_UNPACK_RAW_2(Q,X,val)
+#define FP_UNPACK_RAW_QP(X,val)        _FP_UNPACK_RAW_2_P(Q,X,val)
+#define FP_PACK_RAW_Q(val,X)   _FP_PACK_RAW_2(Q,val,X)
+#define FP_PACK_RAW_QP(val,X)          \
+  do {                                 \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(Q,val,X);       \
+  } while (0)
+
+#define FP_UNPACK_Q(X,val)             \
+  do {                                 \
+    _FP_UNPACK_RAW_2(Q,X,val);         \
+    _FP_UNPACK_CANONICAL(Q,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_QP(X,val)            \
+  do {                                 \
+    _FP_UNPACK_RAW_2_P(Q,X,val);       \
+    _FP_UNPACK_CANONICAL(Q,2,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_Q(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_2(Q,X,val);         \
+    _FP_UNPACK_SEMIRAW(Q,2,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_QP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_2_P(Q,X,val);       \
+    _FP_UNPACK_SEMIRAW(Q,2,X);         \
+  } while (0)
+
+#define FP_PACK_Q(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(Q,2,X);         \
+    _FP_PACK_RAW_2(Q,val,X);           \
+  } while (0)
+
+#define FP_PACK_QP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(Q,2,X);         \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(Q,val,X);       \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_Q(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(Q,2,X);           \
+    _FP_PACK_RAW_2(Q,val,X);           \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_QP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(Q,2,X);           \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_2_P(Q,val,X);       \
+  } while (0)
+
+#define FP_ISSIGNAN_Q(X)               _FP_ISSIGNAN(Q,2,X)
+#define FP_NEG_Q(R,X)                  _FP_NEG(Q,2,R,X)
+#define FP_ADD_Q(R,X,Y)                        _FP_ADD(Q,2,R,X,Y)
+#define FP_SUB_Q(R,X,Y)                        _FP_SUB(Q,2,R,X,Y)
+#define FP_MUL_Q(R,X,Y)                        _FP_MUL(Q,2,R,X,Y)
+#define FP_DIV_Q(R,X,Y)                        _FP_DIV(Q,2,R,X,Y)
+#define FP_SQRT_Q(R,X)                 _FP_SQRT(Q,2,R,X)
+#define _FP_SQRT_MEAT_Q(R,S,T,X,Q)     _FP_SQRT_MEAT_2(R,S,T,X,Q)
+
+#define FP_CMP_Q(r,X,Y,un)     _FP_CMP(Q,2,r,X,Y,un)
+#define FP_CMP_EQ_Q(r,X,Y)     _FP_CMP_EQ(Q,2,r,X,Y)
+#define FP_CMP_UNORD_Q(r,X,Y)  _FP_CMP_UNORD(Q,2,r,X,Y)
+
+#define FP_TO_INT_Q(r,X,rsz,rsg)       _FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_FROM_INT_Q(X,r,rs,rt)       _FP_FROM_INT(Q,2,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_Q(X)     _FP_FRAC_HIGH_2(X)
+#define _FP_FRAC_HIGH_RAW_Q(X) _FP_FRAC_HIGH_2(X)
+
+#endif /* not _FP_W_TYPE_SIZE < 64 */
diff --git a/gcc/config/soft-fp/single.h b/gcc/config/soft-fp/single.h
new file mode 100644 (file)
index 0000000..9c3734a
--- /dev/null
@@ -0,0 +1,151 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Single Precision.
+   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACTBITS_S                _FP_W_TYPE_SIZE
+
+#define _FP_FRACBITS_S         24
+#define _FP_FRACXBITS_S                (_FP_FRACTBITS_S - _FP_FRACBITS_S)
+#define _FP_WFRACBITS_S                (_FP_WORKBITS + _FP_FRACBITS_S)
+#define _FP_WFRACXBITS_S       (_FP_FRACTBITS_S - _FP_WFRACBITS_S)
+#define _FP_EXPBITS_S          8
+#define _FP_EXPBIAS_S          127
+#define _FP_EXPMAX_S           255
+#define _FP_QNANBIT_S          ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
+#define _FP_QNANBIT_SH_S       ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2+_FP_WORKBITS))
+#define _FP_IMPLBIT_S          ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
+#define _FP_IMPLBIT_SH_S       ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1+_FP_WORKBITS))
+#define _FP_OVERFLOW_S         ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
+
+/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
+   chosen by the target machine.  */
+
+typedef float SFtype __attribute__((mode(SF)));
+
+union _FP_UNION_S
+{
+  SFtype flt;
+  struct {
+#if __BYTE_ORDER == __BIG_ENDIAN
+    unsigned sign : 1;
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+#else
+    unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
+    unsigned exp  : _FP_EXPBITS_S;
+    unsigned sign : 1;
+#endif
+  } bits __attribute__((packed));
+};
+
+#define FP_DECL_S(X)           _FP_DECL(1,X)
+#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
+#define FP_UNPACK_RAW_SP(X,val)        _FP_UNPACK_RAW_1_P(S,X,val)
+#define FP_PACK_RAW_S(val,X)   _FP_PACK_RAW_1(S,val,X)
+#define FP_PACK_RAW_SP(val,X)          \
+  do {                                 \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(S,val,X);       \
+  } while (0)
+
+#define FP_UNPACK_S(X,val)             \
+  do {                                 \
+    _FP_UNPACK_RAW_1(S,X,val);         \
+    _FP_UNPACK_CANONICAL(S,1,X);       \
+  } while (0)
+
+#define FP_UNPACK_SP(X,val)            \
+  do {                                 \
+    _FP_UNPACK_RAW_1_P(S,X,val);       \
+    _FP_UNPACK_CANONICAL(S,1,X);       \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_S(X,val)     \
+  do {                                 \
+    _FP_UNPACK_RAW_1(S,X,val);         \
+    _FP_UNPACK_SEMIRAW(S,1,X);         \
+  } while (0)
+
+#define FP_UNPACK_SEMIRAW_SP(X,val)    \
+  do {                                 \
+    _FP_UNPACK_RAW_1_P(S,X,val);       \
+    _FP_UNPACK_SEMIRAW(S,1,X);         \
+  } while (0)
+
+#define FP_PACK_S(val,X)               \
+  do {                                 \
+    _FP_PACK_CANONICAL(S,1,X);         \
+    _FP_PACK_RAW_1(S,val,X);           \
+  } while (0)
+
+#define FP_PACK_SP(val,X)              \
+  do {                                 \
+    _FP_PACK_CANONICAL(S,1,X);         \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(S,val,X);       \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_S(val,X)       \
+  do {                                 \
+    _FP_PACK_SEMIRAW(S,1,X);           \
+    _FP_PACK_RAW_1(S,val,X);           \
+  } while (0)
+
+#define FP_PACK_SEMIRAW_SP(val,X)      \
+  do {                                 \
+    _FP_PACK_SEMIRAW(S,1,X);           \
+    if (!FP_INHIBIT_RESULTS)           \
+      _FP_PACK_RAW_1_P(S,val,X);       \
+  } while (0)
+
+#define FP_ISSIGNAN_S(X)               _FP_ISSIGNAN(S,1,X)
+#define FP_NEG_S(R,X)                  _FP_NEG(S,1,R,X)
+#define FP_ADD_S(R,X,Y)                        _FP_ADD(S,1,R,X,Y)
+#define FP_SUB_S(R,X,Y)                        _FP_SUB(S,1,R,X,Y)
+#define FP_MUL_S(R,X,Y)                        _FP_MUL(S,1,R,X,Y)
+#define FP_DIV_S(R,X,Y)                        _FP_DIV(S,1,R,X,Y)
+#define FP_SQRT_S(R,X)                 _FP_SQRT(S,1,R,X)
+#define _FP_SQRT_MEAT_S(R,S,T,X,Q)     _FP_SQRT_MEAT_1(R,S,T,X,Q)
+
+#define FP_CMP_S(r,X,Y,un)     _FP_CMP(S,1,r,X,Y,un)
+#define FP_CMP_EQ_S(r,X,Y)     _FP_CMP_EQ(S,1,r,X,Y)
+#define FP_CMP_UNORD_S(r,X,Y)  _FP_CMP_UNORD(S,1,r,X,Y)
+
+#define FP_TO_INT_S(r,X,rsz,rsg)       _FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_FROM_INT_S(X,r,rs,rt)       _FP_FROM_INT(S,1,X,r,rs,rt)
+
+#define _FP_FRAC_HIGH_S(X)     _FP_FRAC_HIGH_1(X)
+#define _FP_FRAC_HIGH_RAW_S(X) _FP_FRAC_HIGH_1(X)
diff --git a/gcc/config/soft-fp/soft-fp.h b/gcc/config/soft-fp/soft-fp.h
new file mode 100644 (file)
index 0000000..dbf080e
--- /dev/null
@@ -0,0 +1,209 @@
+/* Software floating-point emulation.
+   Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006
+       Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+                 Jakub Jelinek (jj@ultra.linux.cz),
+                 David S. Miller (davem@redhat.com) and
+                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef SOFT_FP_H
+#define SOFT_FP_H
+
+#ifdef _LIBC
+#include <sfp-machine.h>
+#else
+#include "sfp-machine.h"
+#endif
+
+/* Allow sfp-machine to have its own byte order definitions. */
+#ifndef __BYTE_ORDER
+#ifdef _LIBC
+#include <endian.h>
+#else
+#error "endianness not defined by sfp-machine.h"
+#endif
+#endif
+
+#define _FP_WORKBITS           3
+#define _FP_WORK_LSB           ((_FP_W_TYPE)1 << 3)
+#define _FP_WORK_ROUND         ((_FP_W_TYPE)1 << 2)
+#define _FP_WORK_GUARD         ((_FP_W_TYPE)1 << 1)
+#define _FP_WORK_STICKY                ((_FP_W_TYPE)1 << 0)
+
+#ifndef FP_RND_NEAREST
+# define FP_RND_NEAREST                0
+# define FP_RND_ZERO           1
+# define FP_RND_PINF           2
+# define FP_RND_MINF           3
+#endif
+#ifndef FP_ROUNDMODE
+# define FP_ROUNDMODE          FP_RND_NEAREST
+#endif
+
+/* By default don't care about exceptions. */
+#ifndef FP_EX_INVALID
+#define FP_EX_INVALID          0
+#endif
+#ifndef FP_EX_OVERFLOW
+#define FP_EX_OVERFLOW         0
+#endif
+#ifndef FP_EX_UNDERFLOW
+#define FP_EX_UNDERFLOW                0
+#endif
+#ifndef FP_EX_DIVZERO
+#define FP_EX_DIVZERO          0
+#endif
+#ifndef FP_EX_INEXACT
+#define FP_EX_INEXACT          0
+#endif
+#ifndef FP_EX_DENORM
+#define FP_EX_DENORM           0
+#endif
+
+#ifdef _FP_DECL_EX
+#define FP_DECL_EX                                     \
+  int _fex = 0;                                                \
+  _FP_DECL_EX
+#else
+#define FP_DECL_EX int _fex = 0
+#endif
+
+#ifndef FP_INIT_ROUNDMODE
+#define FP_INIT_ROUNDMODE do {} while (0)
+#endif
+
+#ifndef FP_HANDLE_EXCEPTIONS
+#define FP_HANDLE_EXCEPTIONS do {} while (0)
+#endif
+
+#ifndef FP_INHIBIT_RESULTS
+/* By default we write the results always.
+ * sfp-machine may override this and e.g.
+ * check if some exceptions are unmasked
+ * and inhibit it in such a case.
+ */
+#define FP_INHIBIT_RESULTS 0
+#endif
+
+#define FP_SET_EXCEPTION(ex)                           \
+  _fex |= (ex)
+
+#define FP_UNSET_EXCEPTION(ex)                         \
+  _fex &= ~(ex)
+
+#define FP_CLEAR_EXCEPTIONS                            \
+  _fex = 0
+
+#define _FP_ROUND_NEAREST(wc, X)                       \
+do {                                                   \
+    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);           \
+} while (0)
+
+#define _FP_ROUND_ZERO(wc, X)          (void)0
+
+#define _FP_ROUND_PINF(wc, X)                          \
+do {                                                   \
+    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))          \
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);             \
+} while (0)
+
+#define _FP_ROUND_MINF(wc, X)                          \
+do {                                                   \
+    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))           \
+      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);             \
+} while (0)
+
+#define _FP_ROUND(wc, X)                       \
+do {                                           \
+       if (_FP_FRAC_LOW_##wc(X) & 7)           \
+         FP_SET_EXCEPTION(FP_EX_INEXACT);      \
+       switch (FP_ROUNDMODE)                   \
+       {                                       \
+         case FP_RND_NEAREST:                  \
+           _FP_ROUND_NEAREST(wc,X);            \
+           break;                              \
+         case FP_RND_ZERO:                     \
+           _FP_ROUND_ZERO(wc,X);               \
+           break;                              \
+         case FP_RND_PINF:                     \
+           _FP_ROUND_PINF(wc,X);               \
+           break;                              \
+         case FP_RND_MINF:                     \
+           _FP_ROUND_MINF(wc,X);               \
+           break;                              \
+       }                                       \
+} while (0)
+
+#define FP_CLS_NORMAL          0
+#define FP_CLS_ZERO            1
+#define FP_CLS_INF             2
+#define FP_CLS_NAN             3
+
+#define _FP_CLS_COMBINE(x,y)   (((x) << 2) | (y))
+
+#include "op-1.h"
+#include "op-2.h"
+#include "op-4.h"
+#include "op-8.h"
+#include "op-common.h"
+
+/* Sigh.  Silly things longlong.h needs.  */
+#define UWtype         _FP_W_TYPE
+#define W_TYPE_SIZE    _FP_W_TYPE_SIZE
+
+typedef int QItype __attribute__((mode(QI)));
+typedef int SItype __attribute__((mode(SI)));
+typedef int DItype __attribute__((mode(DI)));
+typedef unsigned int UQItype __attribute__((mode(QI)));
+typedef unsigned int USItype __attribute__((mode(SI)));
+typedef unsigned int UDItype __attribute__((mode(DI)));
+#if _FP_W_TYPE_SIZE == 32
+typedef unsigned int UHWtype __attribute__((mode(HI)));
+#elif _FP_W_TYPE_SIZE == 64
+typedef USItype UHWtype;
+#endif
+
+#define SI_BITS                (__CHAR_BIT__ * (int)sizeof(SItype))
+#define DI_BITS                (__CHAR_BIT__ * (int)sizeof(DItype))
+
+#ifndef umul_ppmm
+#ifdef _LIBC
+#include <stdlib/longlong.h>
+#else
+#include "longlong.h"
+#endif
+#endif
+
+#ifdef _LIBC
+#include <stdlib.h>
+#else
+extern void abort (void);
+#endif
+
+#endif
diff --git a/gcc/config/soft-fp/subdf3.c b/gcc/config/soft-fp/subdf3.c
new file mode 100644 (file)
index 0000000..3978b52
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DFtype __subdf3(DFtype a, DFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_D(A, a);
+  FP_UNPACK_SEMIRAW_D(B, b);
+  FP_SUB_D(R, A, B);
+  FP_PACK_SEMIRAW_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/subsf3.c b/gcc/config/soft-fp/subsf3.c
new file mode 100644 (file)
index 0000000..f1cbdd1
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SFtype __subsf3(SFtype a, SFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_S(A, a);
+  FP_UNPACK_SEMIRAW_S(B, b);
+  FP_SUB_S(R, A, B);
+  FP_PACK_SEMIRAW_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/subtf3.c b/gcc/config/soft-fp/subtf3.c
new file mode 100644 (file)
index 0000000..7ba4c8c
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+TFtype __subtf3(TFtype a, TFtype b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  TFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_Q(A, a);
+  FP_UNPACK_SEMIRAW_Q(B, b);
+  FP_SUB_Q(R, A, B);
+  FP_PACK_SEMIRAW_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/t-softfp b/gcc/config/soft-fp/t-softfp
new file mode 100644 (file)
index 0000000..4a3f91e
--- /dev/null
@@ -0,0 +1,108 @@
+# Copyright (C) 2006 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING.  If not, write to
+# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+# Boston MA 02110-1301, USA.
+
+# Targets using soft-fp should define the following variables:
+#
+# softfp_float_modes: a list of soft-float floating-point modes,
+#                     e.g. sf df
+# softfp_int_modes: a list of integer modes for which to define conversions,
+#                   e.g. si di
+# softfp_extensions: a list of extensions between floating-point modes,
+#                    e.g. sfdf
+# softfp_truncations: a list of truncations between floating-point modes,
+#                     e.g. dfsf
+# softfp_machine_header: the target sfp-machine.h file (relative to config/),
+#                        e.g. rs6000/sfp-machine.h
+#
+# Extensions and truncations should include those where only one mode
+# is a soft-float mode; for example, sftf where sf is hard-float and
+# tf is soft-float.
+#
+# If the libgcc2.c functions should not be replaced, also define:
+#
+# softfp_exclude_libgcc2 := y
+#
+# Avoiding replacing the libgcc2.c functions is a temporary measure
+# for targets with both hard-float and soft-float multilibs, since
+# these variables apply for all multilibs.  With toplevel libgcc,
+# soft-fp can be used conditionally on the multilib instead.
+#
+# If the code should not be compiled at all for some multilibs, define:
+#
+# softfp_wrap_start: text to put at the start of wrapper source files,
+#                    output with echo
+#                    e.g. '#ifndef __powerpc64__'
+# softfp_wrap_end: text to put at the end of wrapper source files,
+#                  e.g. '#endif'
+#
+# This is another temporary measure.
+
+softfp_float_funcs = add$(m)3 div$(m)3 eq$(m)2 ge$(m)2 le$(m)2 mul$(m)3 \
+  neg$(m)2 sub$(m)3 unord$(m)2
+softfp_floatint_funcs = fix$(m)$(i) fixuns$(m)$(i) \
+  float$(i)$(m) floatun$(i)$(m)
+
+softfp_func_list := \
+  $(foreach m,$(softfp_float_modes), \
+              $(softfp_float_funcs) \
+              $(foreach i,$(softfp_int_modes), \
+                          $(softfp_floatint_funcs))) \
+  $(foreach e,$(softfp_extensions),extend$(e)2) \
+  $(foreach t,$(softfp_truncations),trunc$(t)2)
+
+ifeq ($(softfp_exclude_libgcc2),y)
+# This list is taken from mklibgcc.in and doesn't presently allow for
+# 64-bit targets where si should become di and di should become ti.
+softfp_func_list := $(filter-out floatdidf floatdisf fixunsdfsi fixunssfsi \
+  fixunsdfdi fixdfdi fixunssfdi fixsfdi fixxfdi fixunsxfdi \
+  floatdixf fixunsxfsi fixtfdi fixunstfdi floatditf \
+  floatundidf floatundisf floatundixf floatunditf,$(softfp_func_list))
+endif
+
+ifeq ($(softfp_wrap_start),)
+softfp_file_list := \
+  $(addsuffix .c,$(addprefix $(srcdir)/config/soft-fp/,$(softfp_func_list)))
+else
+softfp_file_list := $(addsuffix .c,$(softfp_func_list))
+
+$(softfp_file_list):
+       echo $(softfp_wrap_start) > $@
+       echo '#include "config/soft-fp/$@"' >> $@
+       echo $(softfp_wrap_end) >> $@
+endif
+
+LIB2FUNCS_EXTRA += $(softfp_file_list)
+
+ifneq ($(softfp_exclude_libgcc2),y)
+# Functions in libgcc2.c are excluded for each soft-float mode (a
+# target may have both soft-float and hard-float modes), for the fixed
+# list of integer modes (si and di) for which libgcc2.c defines any
+# such functions.  Depending on the target, the si and di symbols may
+# in fact define di and ti functions.
+
+LIB2FUNCS_EXCLUDE += \
+  $(addprefix _,$(foreach m,$(softfp_float_modes), \
+                            $(foreach i,si di, \
+                                        $(softfp_floatint_funcs))))
+endif
+
+SFP_MACHINE := sfp-machine.h
+
+$(SFP_MACHINE): $(srcdir)/config/$(softfp_machine_header)
+       cp $(srcdir)/config/$(softfp_machine_header) $(SFP_MACHINE)
diff --git a/gcc/config/soft-fp/truncdfsf2.c b/gcc/config/soft-fp/truncdfsf2.c
new file mode 100644 (file)
index 0000000..bd95391
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Truncate IEEE double into IEEE single
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+SFtype __truncdfsf2(DFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_D(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_TRUNC(S,D,1,2,R,A);
+#else
+  FP_TRUNC(S,D,1,1,R,A);
+#endif
+  FP_PACK_SEMIRAW_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/trunctfdf2.c b/gcc/config/soft-fp/trunctfdf2.c
new file mode 100644 (file)
index 0000000..c3827b0
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Truncate IEEE quad into IEEE double
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+DFtype __trunctfdf2(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_D(R);
+  DFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_TRUNC(D,Q,2,4,R,A);
+#else
+  FP_TRUNC(D,Q,1,2,R,A);
+#endif
+  FP_PACK_SEMIRAW_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/trunctfsf2.c b/gcc/config/soft-fp/trunctfsf2.c
new file mode 100644 (file)
index 0000000..676c937
--- /dev/null
@@ -0,0 +1,54 @@
+/* Software floating-point emulation.
+   Truncate IEEE quad into IEEE single
+   Copyright (C) 1997,1999,2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+                 Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+SFtype __trunctfsf2(TFtype a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_S(R);
+  SFtype r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_SEMIRAW_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_TRUNC(S,Q,1,4,R,A);
+#else
+  FP_TRUNC(S,Q,1,2,R,A);
+#endif
+  FP_PACK_SEMIRAW_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/unorddf2.c b/gcc/config/soft-fp/unorddf2.c
new file mode 100644 (file)
index 0000000..c83a563
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return 1 iff a or b is a NaN, 0 otherwise.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Joseph Myers (joseph@codesourcery.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int
+__unorddf2(DFtype a, DFtype b)
+{
+  FP_DECL_D(A); FP_DECL_D(B);
+  int r;
+
+  FP_UNPACK_RAW_D(A, a);
+  FP_UNPACK_RAW_D(B, b);
+  FP_CMP_UNORD_D(r, A, B);
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/unordsf2.c b/gcc/config/soft-fp/unordsf2.c
new file mode 100644 (file)
index 0000000..8de7563
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Return 1 iff a or b is a NaN, 0 otherwise.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Joseph Myers (joseph@codesourcery.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int
+__unordsf2(SFtype a, SFtype b)
+{
+  FP_DECL_S(A);
+  FP_DECL_S(B);
+  int r;
+
+  FP_UNPACK_RAW_S(A, a);
+  FP_UNPACK_RAW_S(B, b);
+  FP_CMP_UNORD_S(r, A, B);
+
+  return r;
+}
diff --git a/gcc/config/soft-fp/unordtf2.c b/gcc/config/soft-fp/unordtf2.c
new file mode 100644 (file)
index 0000000..134b1d0
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   Return 1 iff a or b is a NaN, 0 otherwise.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Joseph Myers (joseph@codesourcery.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file into
+   combinations with other programs, and to distribute those
+   combinations without any restriction coming from the use of this
+   file.  (The Lesser General Public License restrictions do apply in
+   other respects; for example, they cover modification of the file,
+   and distribution when not linked into a combine executable.)
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int
+__unordtf2(TFtype a, TFtype b)
+{
+  FP_DECL_Q(A);
+  FP_DECL_Q(B);
+  int r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+  FP_CMP_UNORD_Q(r, A, B);
+
+  return r;
+}
index 8ec9e4037b1ee08b83bee1da916628f09d825c24..bf320d9e5538e5bef243465d4d8d55070be5953b 100644 (file)
@@ -11,6 +11,7 @@
 # objext
 # LIB1ASMFUNCS
 # LIB2FUNCS_ST
+# LIB2FUNCS_EXCLUDE
 # LIBGCOV
 # LIB2ADD
 # LIB2ADD_ST 
@@ -158,8 +159,9 @@ else
 fi
 
 # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
-# defined as optimized assembly code in LIB1ASMFUNCS.
-for name in $LIB1ASMFUNCS; do
+# defined as optimized assembly code in LIB1ASMFUNCS or as C code
+# in LIB2FUNCS_EXCLUDE.
+for name in $LIB1ASMFUNCS $LIB2FUNCS_EXCLUDE; do
   lib2funcs=`echo $lib2funcs | sed -e 's/^'$name' //' \
                                   -e 's/ '$name' / /' \
                                   -e 's/ '$name'$//'`