Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 29 Dec 1999 18:11:48 +0000 (18:11 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 29 Dec 1999 18:11:48 +0000 (18:11 +0000)
1999-12-29  Ulrich Drepper  <drepper@cygnus.com>

* soft-fp/*: Tons of new files to implement floating-point arithmetic
in software.
Contributed by  Richard Henderson, Jakub Jelinek and others.

136 files changed:
ChangeLog
linuxthreads/ChangeLog
soft-fp/Banner [new file with mode: 0644]
soft-fp/ChangeLog [new file with mode: 0644]
soft-fp/Makefile [new file with mode: 0644]
soft-fp/adddf3.c [new file with mode: 0644]
soft-fp/addsf3.c [new file with mode: 0644]
soft-fp/addtf3.c [new file with mode: 0644]
soft-fp/configure [new file with mode: 0755]
soft-fp/divdf3.c [new file with mode: 0644]
soft-fp/divsf3.c [new file with mode: 0644]
soft-fp/divtf3.c [new file with mode: 0644]
soft-fp/double.h [new file with mode: 0644]
soft-fp/eqdf2.c [new file with mode: 0644]
soft-fp/eqsf2.c [new file with mode: 0644]
soft-fp/eqtf2.c [new file with mode: 0644]
soft-fp/extenddftf2.c [new file with mode: 0644]
soft-fp/extended.h [new file with mode: 0644]
soft-fp/extendsfdf2.c [new file with mode: 0644]
soft-fp/extendsftf2.c [new file with mode: 0644]
soft-fp/fixdfdi.c [new file with mode: 0644]
soft-fp/fixdfsi.c [new file with mode: 0644]
soft-fp/fixsfdi.c [new file with mode: 0644]
soft-fp/fixsfsi.c [new file with mode: 0644]
soft-fp/fixtfdi.c [new file with mode: 0644]
soft-fp/fixtfsi.c [new file with mode: 0644]
soft-fp/fixunsdfdi.c [new file with mode: 0644]
soft-fp/fixunsdfsi.c [new file with mode: 0644]
soft-fp/fixunssfdi.c [new file with mode: 0644]
soft-fp/fixunssfsi.c [new file with mode: 0644]
soft-fp/fixunstfdi.c [new file with mode: 0644]
soft-fp/fixunstfsi.c [new file with mode: 0644]
soft-fp/floatdidf.c [new file with mode: 0644]
soft-fp/floatdisf.c [new file with mode: 0644]
soft-fp/floatditf.c [new file with mode: 0644]
soft-fp/floatsidf.c [new file with mode: 0644]
soft-fp/floatsisf.c [new file with mode: 0644]
soft-fp/floatsitf.c [new file with mode: 0644]
soft-fp/gedf2.c [new file with mode: 0644]
soft-fp/gesf2.c [new file with mode: 0644]
soft-fp/getf2.c [new file with mode: 0644]
soft-fp/ledf2.c [new file with mode: 0644]
soft-fp/lesf2.c [new file with mode: 0644]
soft-fp/letf2.c [new file with mode: 0644]
soft-fp/muldf3.c [new file with mode: 0644]
soft-fp/mulsf3.c [new file with mode: 0644]
soft-fp/multf3.c [new file with mode: 0644]
soft-fp/negdf2.c [new file with mode: 0644]
soft-fp/negsf2.c [new file with mode: 0644]
soft-fp/negtf2.c [new file with mode: 0644]
soft-fp/op-1.h [new file with mode: 0644]
soft-fp/op-2.h [new file with mode: 0644]
soft-fp/op-4.h [new file with mode: 0644]
soft-fp/op-8.h [new file with mode: 0644]
soft-fp/op-common.h [new file with mode: 0644]
soft-fp/quad.h [new file with mode: 0644]
soft-fp/single.h [new file with mode: 0644]
soft-fp/soft-fp.h [new file with mode: 0644]
soft-fp/sqrtdf2.c [new file with mode: 0644]
soft-fp/sqrtsf2.c [new file with mode: 0644]
soft-fp/sqrttf2.c [new file with mode: 0644]
soft-fp/subdf3.c [new file with mode: 0644]
soft-fp/subsf3.c [new file with mode: 0644]
soft-fp/subtf3.c [new file with mode: 0644]
soft-fp/sysdeps/alpha/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/i386/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/mips/mips64/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/mips/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/powerpc/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/Makefile [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_add.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_cmp.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_cmpe.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_div.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_dtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_feq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_fge.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_fgt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_fle.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_flt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_fne.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_itoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_mul.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_neg.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtod.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtoi.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtos.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtoui.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtoux.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_qtox.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_sqrt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_stoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_sub.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_uitoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_util.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_uxtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/q_xtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc32/sfp-machine.h [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/Makefile [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/Versions [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_add.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_cmp.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_cmpe.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_div.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_dtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_feq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_fge.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_fgt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_fle.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_flt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_fne.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_itoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_mul.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_neg.S [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtod.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtoi.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtos.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtoui.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtoux.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_qtox.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_sqrt.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_stoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_sub.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_uitoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_util.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_uxtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/qp_xtoq.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/s_frexpl.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/s_ilogbl.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/s_scalblnl.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/s_scalbnl.c [new file with mode: 0644]
soft-fp/sysdeps/sparc/sparc64/sfp-machine.h [new file with mode: 0644]
soft-fp/testit.c [new file with mode: 0644]
soft-fp/truncdfsf2.c [new file with mode: 0644]
soft-fp/trunctfdf2.c [new file with mode: 0644]
soft-fp/trunctfsf2.c [new file with mode: 0644]

index eb9c9e1..30ed6d2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+1999-12-29  Ulrich Drepper  <drepper@cygnus.com>
+
+       * soft-fp/*: Tons of new files to implement floating-point arithmetic
+       in software.
+       Contributed by  Richard Henderson, Jakub Jelinek and others.
+
 1999-12-29  Andreas Jaeger  <aj@suse.de>
 
        * sysdeps/unix/sysv/linux/alpha/sys/io.h: Don't include
index 994f7e6..47ba655 100644 (file)
@@ -1,3 +1,7 @@
+1999-12-29  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/pthread/pthread.h: Fix typos, reformat comments.
+
 1999-12-28  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/alpha/pt-machine.h: Move stack_pointer definition to the
diff --git a/soft-fp/Banner b/soft-fp/Banner
new file mode 100644 (file)
index 0000000..940395c
--- /dev/null
@@ -0,0 +1 @@
+software FPU emulation by Richard Henderson, Jakub Jelinek and others
diff --git a/soft-fp/ChangeLog b/soft-fp/ChangeLog
new file mode 100644 (file)
index 0000000..f4e8bea
--- /dev/null
@@ -0,0 +1,135 @@
+1999-10-29  Jakub Jelinek  <jakub@redhat.com>
+
+       * Makefile: New file.
+       * adddf3.c: New file.
+       * addsf3.c: New file.
+       * addtf3.c: New file.
+       * divdf3.c: New file.
+       * divsf3.c: New file.
+       * divtf3.c: New file.
+       * double.h: New file.
+       * eqdf2.c: New file.
+       * eqsf2.c: New file.
+       * eqtf2.c: New file.
+       * extenddftf2.c: New file.
+       * extendsfdf2.c: New file.
+       * extendsftf2.c: New file.
+       * fixdfdi.c: New file.
+       * fixdfsi.c: New file.
+       * fixsfdi.c: New file.
+       * fixsfsi.c: New file.
+       * fixtfdi.c: New file.
+       * fixtfsi.c: New file.
+       * fixunsdfdi.c: New file.
+       * fixunsdfsi.c: New file.
+       * fixunssfdi.c: New file.
+       * fixunssfsi.c: New file.
+       * fixunstfdi.c: New file.
+       * fixunstfsi.c: New file.
+       * floatdidf.c: New file.
+       * floatdisf.c: New file.
+       * floatditf.c: New file.
+       * floatsidf.c: New file.
+       * floatsisf.c: New file.
+       * floatsitf.c: New file.
+       * gedf2.c: New file.
+       * gesf2.c: New file.
+       * getf2.c: New file.
+       * ledf2.c: New file.
+       * lesf2.c: New file.
+       * letf2.c: New file.
+       * muldf3.c: New file.
+       * mulsf3.c: New file.
+       * multf3.c: New file.
+       * negdf2.c: New file.
+       * negsf2.c: New file.
+       * negtf2.c: New file.
+       * op-1.h: New file.
+       * op-2.h: New file.
+       * op-4.h: New file.
+       * op-common.h: New file.
+       * quad.h: New file.
+       * single.h: New file.
+       * soft-fp.h: New file.
+       * subdf3.c: New file.
+       * subsf3.c: New file.
+       * subtf3.c: New file.
+       * testit.c: New file.
+       * truncdfsf2.c: New file.
+       * trunctfdf2.c: New file.
+       * trunctfsf2.c: New file.
+       * Banner: New file.
+       * configure: New file.
+       * op-8.h: New file.
+       * sqrtdf2.c: New file.
+       * extended.h: New file.
+       * sqrtsf2.c: New file.
+       * sqrttf2.c: New file.
+       * sysdeps/i386/sfp-machine.h: New file.
+       * sysdeps/alpha/sfp-machine.h: New file.
+       * sysdeps/sparc/sparc64/sfp-machine.h: New file.
+       * sysdeps/sparc/sparc64/Makefile: New file.
+       * sysdeps/sparc/sparc64/qp_qtoux.c: New file.
+       * sysdeps/sparc/sparc64/qp_add.c: New file.
+       * sysdeps/sparc/sparc64/qp_div.c: New file.
+       * sysdeps/sparc/sparc64/qp_dtoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_feq.c: New file.
+       * sysdeps/sparc/sparc64/qp_fge.c: New file.
+       * sysdeps/sparc/sparc64/qp_fle.c: New file.
+       * sysdeps/sparc/sparc64/qp_itoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_mul.c: New file.
+       * sysdeps/sparc/sparc64/qp_qtod.c: New file.
+       * sysdeps/sparc/sparc64/qp_qtoi.c: New file.
+       * sysdeps/sparc/sparc64/qp_qtos.c: New file.
+       * sysdeps/sparc/sparc64/Versions: New file.
+       * sysdeps/sparc/sparc64/qp_stoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_sub.c: New file.
+       * sysdeps/sparc/sparc64/qp_fne.c: New file.
+       * sysdeps/sparc/sparc64/qp_cmp.c: New file.
+       * sysdeps/sparc/sparc64/qp_uxtoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_fgt.c: New file.
+       * sysdeps/sparc/sparc64/qp_cmpe.c: New file.
+       * sysdeps/sparc/sparc64/s_frexpl.c: New file.
+       * sysdeps/sparc/sparc64/qp_qtox.c: New file.
+       * sysdeps/sparc/sparc64/qp_flt.c: New file.
+       * sysdeps/sparc/sparc64/qp_xtoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_sqrt.c: New file.
+       * sysdeps/sparc/sparc64/s_ilogbl.c: New file.
+       * sysdeps/sparc/sparc64/s_scalblnl.c: New file.
+       * sysdeps/sparc/sparc64/s_scalbnl.c: New file.
+       * sysdeps/sparc/sparc64/qp_util.c: New file.
+       * sysdeps/sparc/sparc64/qp_neg.S: New file.
+       * sysdeps/sparc/sparc64/qp_uitoq.c: New file.
+       * sysdeps/sparc/sparc64/qp_qtoui.c: New file.
+       * sysdeps/sparc/sparc32/sfp-machine.h: New file.
+       * sysdeps/sparc/sparc32/Makefile: New file.
+       * sysdeps/sparc/sparc32/q_qtox.c: New file.
+       * sysdeps/sparc/sparc32/q_cmp.c: New file.
+       * sysdeps/sparc/sparc32/q_dtoq.c: New file.
+       * sysdeps/sparc/sparc32/q_feq.c: New file.
+       * sysdeps/sparc/sparc32/q_fge.c: New file.
+       * sysdeps/sparc/sparc32/q_fgt.c: New file.
+       * sysdeps/sparc/sparc32/q_flt.c: New file.
+       * sysdeps/sparc/sparc32/q_mul.c: New file.
+       * sysdeps/sparc/sparc32/q_neg.c: New file.
+       * sysdeps/sparc/sparc32/q_qtod.c: New file.
+       * sysdeps/sparc/sparc32/q_qtoi.c: New file.
+       * sysdeps/sparc/sparc32/q_qtos.c: New file.
+       * sysdeps/sparc/sparc32/q_qtoui.c: New file.
+       * sysdeps/sparc/sparc32/q_sqrt.c: New file.
+       * sysdeps/sparc/sparc32/q_sub.c: New file.
+       * sysdeps/sparc/sparc32/q_uitoq.c: New file.
+       * sysdeps/sparc/sparc32/q_itoq.c: New file.
+       * sysdeps/sparc/sparc32/q_cmpe.c: New file.
+       * sysdeps/sparc/sparc32/q_xtoq.c: New file.
+       * sysdeps/sparc/sparc32/q_fle.c: New file.
+       * sysdeps/sparc/sparc32/q_div.c: New file.
+       * sysdeps/sparc/sparc32/q_stoq.c: New file.
+       * sysdeps/sparc/sparc32/q_fne.c: New file.
+       * sysdeps/sparc/sparc32/q_uxtoq.c: New file.
+       * sysdeps/sparc/sparc32/q_util.c: New file.
+       * sysdeps/sparc/sparc32/q_qtoux.c: New file.
+       * sysdeps/sparc/sparc32/q_add.c: New file.
+       * sysdeps/mips/sfp-machine.h: New file.
+       * sysdeps/mips/mips64/sfp-machine.h: New file.
+       * sysdeps/powerpc/sfp-machine.h: New file.
diff --git a/soft-fp/Makefile b/soft-fp/Makefile
new file mode 100644 (file)
index 0000000..e72e7f2
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (C) 1997, 1999  Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+#
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB.  If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+#
+#      Makefile for software floating-point routines
+#
+subdir := soft-fp
+
+gcc-single-routines := negsf2 addsf3 subsf3 mulsf3 divsf3 eqsf2 \
+       lesf2 gesf2 fixsfsi fixunssfsi floatsisf fixsfdi        \
+       fixunssfdi floatdisf sqrtsf2
+
+gcc-double-routines := negdf2 adddf3 subdf3 muldf3 divdf3 eqdf2 \
+       ledf2 gedf2 fixdfsi fixunsdfsi floatsidf fixdfdi        \
+       fixunsdfdi floatdidf extendsfdf2 truncdfsf2 sqrtdf2
+
+gcc-quad-routines := negtf2 addtf3 subtf3 multf3 divtf3 eqtf2 \
+       letf2 getf2 fixtfsi fixunstfsi floatsitf fixtfdi      \
+       fixunstfdi floatditf extendsftf2 trunctfsf2 extenddftf2 \
+       trunctfdf2 sqrttf2
+
+distribute := double.h op-1.h op-2.h op-4.h op-common.h quad.h \
+       single.h soft-fp.h extended.h
+
+include ../Rules
diff --git a/soft-fp/adddf3.c b/soft-fp/adddf3.c
new file mode 100644 (file)
index 0000000..373bbb1
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __adddf3(double a, double b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+  FP_UNPACK_D(B, b);
+  FP_ADD_D(R, A, B);
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/addsf3.c b/soft-fp/addsf3.c
new file mode 100644 (file)
index 0000000..6ee36c5
--- /dev/null
@@ -0,0 +1,41 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __addsf3(float a, float b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+  FP_UNPACK_S(B, b);
+  FP_ADD_S(R, A, B);
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
diff --git a/soft-fp/addtf3.c b/soft-fp/addtf3.c
new file mode 100644 (file)
index 0000000..5919df1
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __addtf3(long double a, long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  long double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_ADD_Q(R, A, B);
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/configure b/soft-fp/configure
new file mode 100755 (executable)
index 0000000..d40d2d7
--- /dev/null
@@ -0,0 +1,2 @@
+# This is only to keep the GNU C library configure mechanism happy.
+exit 0
diff --git a/soft-fp/divdf3.c b/soft-fp/divdf3.c
new file mode 100644 (file)
index 0000000..f0bbbfd
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __divdf3(double a, double b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  double 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/soft-fp/divsf3.c b/soft-fp/divsf3.c
new file mode 100644 (file)
index 0000000..37d691b
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __divsf3(float a, float b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  float 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/soft-fp/divtf3.c b/soft-fp/divtf3.c
new file mode 100644 (file)
index 0000000..dfc4c01
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __divtf3(long double a, long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  long double 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/soft-fp/double.h b/soft-fp/double.h
new file mode 100644 (file)
index 0000000..ee581c2
--- /dev/null
@@ -0,0 +1,197 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Double Precision
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_IMPLBIT_D          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_D         \
+       ((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_D
+{
+  double 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_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_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_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
+{
+  double 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_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_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_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/soft-fp/eqdf2.c b/soft-fp/eqdf2.c
new file mode 100644 (file)
index 0000000..b32b4e1
--- /dev/null
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __eqdf2(double a, double 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/soft-fp/eqsf2.c b/soft-fp/eqsf2.c
new file mode 100644 (file)
index 0000000..93373f1
--- /dev/null
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __eqsf2(float a, float 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/soft-fp/eqtf2.c b/soft-fp/eqtf2.c
new file mode 100644 (file)
index 0000000..7af2f92
--- /dev/null
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+   Return 0 iff a == b, 1 otherwise
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __eqtf2(long double a, long double 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/soft-fp/extenddftf2.c b/soft-fp/extenddftf2.c
new file mode 100644 (file)
index 0000000..36a4d49
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE quad
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+long double __extenddftf2(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_Q(R);
+  long double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,D,4,2,R,A);
+#else
+  FP_CONV(Q,D,2,1,R,A);
+#endif
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/extended.h b/soft-fp/extended.h
new file mode 100644 (file)
index 0000000..4a1d7e7
--- /dev/null
@@ -0,0 +1,388 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Extended Precision.
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_IMPLBIT_E          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_E         \
+       ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_E
+{
+   long double 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_2_P(X,val);          \
+    _FP_UNPACK_CANONICAL(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_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_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
+{
+  long double flt /* __attribute__((mode(TF))) */ ;
+  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_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_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_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/soft-fp/extendsfdf2.c b/soft-fp/extendsfdf2.c
new file mode 100644 (file)
index 0000000..8e5fefe
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE double
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+double __extendsfdf2(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_CONV(D,S,2,1,R,A);
+#else
+  FP_CONV(D,S,1,1,R,A);
+#endif
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/extendsftf2.c b/soft-fp/extendsftf2.c
new file mode 100644 (file)
index 0000000..8902683
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return a converted to IEEE quad
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+long double __extendsftf2(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_Q(R);
+  long double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,S,4,1,R,A);
+#else
+  FP_CONV(Q,S,2,1,R,A);
+#endif
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixdfdi.c b/soft-fp/fixdfdi.c
new file mode 100644 (file)
index 0000000..5805d97
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+DItype __fixdfdi(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  DItype r;
+
+  FP_UNPACK_D(A, a);
+  FP_TO_INT_D(r, A, 64, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixdfsi.c b/soft-fp/fixdfsi.c
new file mode 100644 (file)
index 0000000..e7dcea8
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+SItype __fixdfsi(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  SItype r;
+
+  FP_UNPACK_D(A, a);
+  FP_TO_INT_D(r, A, 32, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixsfdi.c b/soft-fp/fixsfdi.c
new file mode 100644 (file)
index 0000000..76ca858
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+DItype __fixsfdi(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  DItype r;
+
+  FP_UNPACK_S(A, a);
+  FP_TO_INT_S(r, A, 64, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixsfsi.c b/soft-fp/fixsfsi.c
new file mode 100644 (file)
index 0000000..7e745dc
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+SItype __fixsfsi(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  SItype r;
+
+  FP_UNPACK_S(A, a);
+  FP_TO_INT_S(r, A, 32, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixtfdi.c b/soft-fp/fixtfdi.c
new file mode 100644 (file)
index 0000000..80c2528
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+DItype __fixtfdi(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  DItype r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 64, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixtfsi.c b/soft-fp/fixtfsi.c
new file mode 100644 (file)
index 0000000..11eb7d6
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit signed integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+SItype __fixtfsi(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  SItype r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 32, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunsdfdi.c b/soft-fp/fixunsdfdi.c
new file mode 100644 (file)
index 0000000..92db75c
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+UDItype __fixunsdfdi(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  UDItype r;
+
+  FP_UNPACK_D(A, a);
+  FP_TO_INT_D(r, A, 64, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunsdfsi.c b/soft-fp/fixunsdfsi.c
new file mode 100644 (file)
index 0000000..deee666
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+USItype __fixunsdfsi(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  USItype r;
+
+  FP_UNPACK_D(A, a);
+  FP_TO_INT_D(r, A, 32, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunssfdi.c b/soft-fp/fixunssfdi.c
new file mode 100644 (file)
index 0000000..de5fc4f
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+UDItype __fixunssfdi(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  UDItype r;
+
+  FP_UNPACK_S(A, a);
+  FP_TO_INT_S(r, A, 64, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunssfsi.c b/soft-fp/fixunssfsi.c
new file mode 100644 (file)
index 0000000..76166fc
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+USItype __fixunssfsi(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  USItype r;
+
+  FP_UNPACK_S(A, a);
+  FP_TO_INT_S(r, A, 32, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunstfdi.c b/soft-fp/fixunstfdi.c
new file mode 100644 (file)
index 0000000..c48580b
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 64bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+UDItype __fixunstfdi(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  UDItype r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 64, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/fixunstfsi.c b/soft-fp/fixunstfsi.c
new file mode 100644 (file)
index 0000000..94927e4
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a to 32bit unsigned integer
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+USItype __fixunstfsi(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  USItype r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 32, 0);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/floatdidf.c b/soft-fp/floatdidf.c
new file mode 100644 (file)
index 0000000..fd3088e
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE double
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __floatdidf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  double a;
+
+  FP_FROM_INT_D(A, i, 64, long long);
+  FP_PACK_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatdisf.c b/soft-fp/floatdisf.c
new file mode 100644 (file)
index 0000000..36a6555
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE single
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+double __floatdisf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  float a;
+
+  FP_FROM_INT_S(A, i, 64, long long);
+  FP_PACK_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatditf.c b/soft-fp/floatditf.c
new file mode 100644 (file)
index 0000000..89a67ac
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 64bit signed integer to IEEE quad
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __floatditf(DItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long double a;
+
+  FP_FROM_INT_Q(A, i, 64, long long);
+  FP_PACK_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatsidf.c b/soft-fp/floatsidf.c
new file mode 100644 (file)
index 0000000..9e042df
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE double
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __floatsidf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  double a;
+
+  FP_FROM_INT_D(A, i, 32, int);
+  FP_PACK_D(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatsisf.c b/soft-fp/floatsisf.c
new file mode 100644 (file)
index 0000000..3d508fb
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE single
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __floatsisf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  float a;
+
+  FP_FROM_INT_S(A, i, 32, int);
+  FP_PACK_S(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/floatsitf.c b/soft-fp/floatsitf.c
new file mode 100644 (file)
index 0000000..0460942
--- /dev/null
@@ -0,0 +1,37 @@
+/* Software floating-point emulation.
+   Convert a 32bit signed integer to IEEE quad
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __floatsitf(SItype i)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long double a;
+
+  FP_FROM_INT_Q(A, i, 32, int);
+  FP_PACK_Q(a, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return a;
+}
diff --git a/soft-fp/gedf2.c b/soft-fp/gedf2.c
new file mode 100644 (file)
index 0000000..c68f7d2
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __gedf2(double a, double 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/soft-fp/gesf2.c b/soft-fp/gesf2.c
new file mode 100644 (file)
index 0000000..41adadf
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __gesf2(float a, float 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/soft-fp/getf2.c b/soft-fp/getf2.c
new file mode 100644 (file)
index 0000000..fa16c45
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __getf2(long double a, long double 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/soft-fp/ledf2.c b/soft-fp/ledf2.c
new file mode 100644 (file)
index 0000000..015cb79
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+int __ledf2(double a, double 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/soft-fp/lesf2.c b/soft-fp/lesf2.c
new file mode 100644 (file)
index 0000000..029c589
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+int __lesf2(float a, float 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/soft-fp/letf2.c b/soft-fp/letf2.c
new file mode 100644 (file)
index 0000000..97c539c
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int __letf2(long double a, long double 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/soft-fp/muldf3.c b/soft-fp/muldf3.c
new file mode 100644 (file)
index 0000000..7c05ebe
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __muldf3(double a, double b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  double 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/soft-fp/mulsf3.c b/soft-fp/mulsf3.c
new file mode 100644 (file)
index 0000000..63f1671
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __mulsf3(float a, float b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  float 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/soft-fp/multf3.c b/soft-fp/multf3.c
new file mode 100644 (file)
index 0000000..03c7f1a
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __multf3(long double a, long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  long double 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/soft-fp/negdf2.c b/soft-fp/negdf2.c
new file mode 100644 (file)
index 0000000..eb76712
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __negdf2(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(R);
+  double 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/soft-fp/negsf2.c b/soft-fp/negsf2.c
new file mode 100644 (file)
index 0000000..e0a3cbb
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __negsf2(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(R);
+  float 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/soft-fp/negtf2.c b/soft-fp/negtf2.c
new file mode 100644 (file)
index 0000000..975f011
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return -a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __negtf2(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(R);
+  long double 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/soft-fp/op-1.h b/soft-fp/op-1.h
new file mode 100644 (file)
index 0000000..48bf4ce
--- /dev/null
@@ -0,0 +1,297 @@
+/* Software floating-point emulation.
+   Basic one-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
+
+#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_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;                                       \
+                                                                       \
+    /* Normalize Y -- i.e. make the most significant bit set.  */      \
+    Y##_f <<= _FP_WFRACXBITS_##fs - 1;                                 \
+                                                                       \
+    /* Shift X op correspondingly high, that is, up one full word.  */ \
+    if (X##_f <= Y##_f)                                                        \
+      {                                                                        \
+       _nl = 0;                                                        \
+       _nh = X##_f;                                                    \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       R##_e++;                                                        \
+       _nl = X##_f << (_FP_W_TYPE_SIZE-1);                             \
+       _nh = X##_f >> 1;                                               \
+      }                                                                        \
+                                                                       \
+    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);                               \
+    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_CONV_1_1(dfs, sfs, D, S)                              \
+  do {                                                                 \
+    D##_f = S##_f;                                                     \
+    if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs)                     \
+      {                                                                        \
+       if (S##_c != FP_CLS_NAN)                                        \
+         _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs),  \
+                        _FP_WFRACBITS_##sfs);                          \
+       else                                                            \
+         _FP_FRAC_SRL_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs)); \
+      }                                                                        \
+    else                                                               \
+      D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs;             \
+  } while (0)
diff --git a/soft-fp/op-2.h b/soft-fp/op-2.h
new file mode 100644 (file)
index 0000000..ad3fbc5
--- /dev/null
@@ -0,0 +1,608 @@
+/* Software floating-point emulation.
+   Basic two-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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)                                            \
+  do {                                                                 \
+    if ((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);                                             \
+         }                                                             \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE);                     \
+       X##_f0 = 0;                                                     \
+      }                                                                        \
+  } while (0)
+
+#define _FP_FRAC_SRL_2(X,N)                                            \
+  do {                                                                 \
+    if ((N) < _FP_W_TYPE_SIZE)                                         \
+      {                                                                        \
+       X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N));     \
+       X##_f1 >>= (N);                                                 \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE);                     \
+       X##_f1 = 0;                                                     \
+      }                                                                        \
+  } while (0)
+
+/* Right shift with sticky-lsb.  */
+#define _FP_FRAC_SRS_2(X,N,sz)                                         \
+  do {                                                                 \
+    if ((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);                                                 \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) |                   \
+                 (((X##_f1 << (sz - (N))) | X##_f0) != 0));            \
+       X##_f1 = 0;                                                     \
+      }                                                                        \
+  } while (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_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)       \
+  do {                                         \
+    if (rsize <= _FP_W_TYPE_SIZE)              \
+      r = X##_f0;                              \
+    else                                       \
+      {                                                \
+       r = X##_f1;                             \
+       r <<= _FP_W_TYPE_SIZE;                  \
+       r += X##_f0;                            \
+      }                                                \
+  } while (0)
+
+#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_CONV_1_2(dfs, sfs, D, S)                              \
+  do {                                                                 \
+    if (S##_c != FP_CLS_NAN)                                           \
+      _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),   \
+                    _FP_WFRACBITS_##sfs);                              \
+    else                                                               \
+      _FP_FRAC_SRL_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs));  \
+    D##_f = S##_f0;                                                    \
+  } while (0)
+
+#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S)                              \
+  do {                                                                 \
+    D##_f0 = S##_f;                                                    \
+    D##_f1 = 0;                                                                \
+    _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));    \
+  } while (0)
+
diff --git a/soft-fp/op-4.h b/soft-fp/op-4.h
new file mode 100644 (file)
index 0000000..f5235f5
--- /dev/null
@@ -0,0 +1,661 @@
+/* Software floating-point emulation.
+   Basic four-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_SRS_4(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];                                                 \
+    _s |= X##_f[_i] << _up;                                            \
+/* s is now != 0 if we want to set the LSbit */                                \
+    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;                                                   \
+    /* don't fix the LSB until the very end when we're sure f[0] is stable */  \
+    X##_f[0] |= (_s != 0);                                             \
+  } 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_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[2]);           \
+       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)                    \
+  (r0 = x0 + y0,                                                       \
+   r1 = x1 + y1 + (r0 < x0),                                           \
+   r2 = x2 + y2 + (r1 < x1))
+#endif
+
+#ifndef __FP_FRAC_ADD_4
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  (r0 = x0 + y0,                                                       \
+   r1 = x1 + y1 + (r0 < x0),                                           \
+   r2 = x2 + y2 + (r1 < x1),                                           \
+   r3 = x3 + y3 + (r2 < x2))
+#endif
+
+#ifndef __FP_FRAC_SUB_3
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  (r0 = x0 - y0,                                                       \
+   r1 = x1 - y1 - (r0 > x0),                                           \
+   r2 = x2 - y2 - (r1 > x1))
+#endif
+
+#ifndef __FP_FRAC_SUB_4
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  (r0 = x0 - y0,                                                       \
+   r1 = x1 - y1 - (r0 > x0),                                           \
+   r2 = x2 - y2 - (r1 > x1),                                           \
+   r3 = x3 - y3 - (r2 > x2))
+#endif
+
+#ifndef __FP_FRAC_DEC_3
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0)                             \
+  do {                                                                 \
+    UWtype _t0, _t1;                                                   \
+    _t0 = x0;                                                          \
+    x0 -= y0;                                                          \
+    _t1 = x1;                                                          \
+    x1 -= y1 + (x0 > _t0);                                             \
+    x2 -= y2 + (x1 > _t1);                                             \
+  } 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;                                                   \
+    _t0 = x0;                                                          \
+    x0 -= y0;                                                          \
+    _t1 = x1;                                                          \
+    x1 -= y1 + (x0 > _t0);                                             \
+    _t0 = x2;                                                          \
+    x2 -= y2 + (x1 > _t1);                                             \
+    x3 -= y3 + (x2 > _t0);                                             \
+  } 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_CONV_1_4(dfs, sfs, D, S)                              \
+   do {                                                                        \
+     if (S##_c != FP_CLS_NAN)                                          \
+       _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),  \
+                         _FP_WFRACBITS_##sfs);                         \
+     else                                                              \
+       _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \
+     D##_f = S##_f[0];                                                 \
+  } while (0)
+
+#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S)                              \
+   do {                                                                        \
+     if (S##_c != FP_CLS_NAN)                                          \
+       _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs),  \
+                     _FP_WFRACBITS_##sfs);                             \
+     else                                                              \
+       _FP_FRAC_SRL_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs)); \
+     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_CONV_4_1(dfs, sfs, D, S)                              \
+   do {                                                                        \
+     D##_f[0] = S##_f;                                                 \
+     D##_f[1] = D##_f[2] = D##_f[3] = 0;                               \
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));   \
+   } while (0)
+
+#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S)                              \
+   do {                                                                        \
+     D##_f[0] = S##_f0;                                                        \
+     D##_f[1] = S##_f1;                                                        \
+     D##_f[2] = D##_f[3] = 0;                                          \
+     _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs));   \
+   } while (0)
+
diff --git a/soft-fp/op-8.h b/soft-fp/op-8.h
new file mode 100644 (file)
index 0000000..a9d7dbf
--- /dev/null
@@ -0,0 +1,103 @@
+/* Software floating-point emulation.
+   Basic eight-word fraction declaration and manipulation.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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];                                                 \
+    _s |= X##_f[_i] << _up;                                            \
+/* s is now != 0 if we want to set the LSbit */                                \
+    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;                                                   \
+    /* 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/soft-fp/op-common.h b/soft-fp/op-common.h
new file mode 100644 (file)
index 0000000..207aa77
--- /dev/null
@@ -0,0 +1,767 @@
+/* Software floating-point emulation. Common operations.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define _FP_DECL(wc, X)                        \
+  _FP_I_TYPE X##_c, 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)
+
+/*
+ * 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_SRL_##wc(X, (_FP_WORKBITS+1));             \
+           X##_e++;                                            \
+         }                                                     \
+       else                                                    \
+         _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;                                                       \
+})
+
+
+
+
+
+/*
+ * Main addition routine.  The input values should be cooked.
+ */
+
+#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)                               \
+do {                                                                        \
+  switch (_FP_CLS_COMBINE(X##_c, Y##_c))                                    \
+  {                                                                         \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):                        \
+    {                                                                       \
+      /* shift the smaller number so that its exponent matches the larger */ \
+      _FP_I_TYPE diff = X##_e - Y##_e;                                      \
+                                                                            \
+      if (diff < 0)                                                         \
+       {                                                                    \
+         diff = -diff;                                                      \
+         if (diff <= _FP_WFRACBITS_##fs)                                    \
+           _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);                  \
+         else if (!_FP_FRAC_ZEROP_##wc(X))                                  \
+           _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                          \
+         R##_e = Y##_e;                                                     \
+       }                                                                    \
+      else                                                                  \
+       {                                                                    \
+         if (diff > 0)                                                      \
+           {                                                                \
+             if (diff <= _FP_WFRACBITS_##fs)                                \
+               _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);              \
+             else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
+               _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
+           }                                                                \
+         R##_e = X##_e;                                                     \
+       }                                                                    \
+                                                                            \
+      R##_c = FP_CLS_NORMAL;                                                \
+                                                                            \
+      if (X##_s == Y##_s)                                                   \
+       {                                                                    \
+         R##_s = X##_s;                                                     \
+         _FP_FRAC_ADD_##wc(R, X, Y);                                        \
+         if (_FP_FRAC_OVERP_##wc(fs, R))                                    \
+           {                                                                \
+             _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
+             R##_e++;                                                       \
+           }                                                                \
+       }                                                                    \
+      else                                                                  \
+       {                                                                    \
+         R##_s = X##_s;                                                     \
+         _FP_FRAC_SUB_##wc(R, X, Y);                                        \
+         if (_FP_FRAC_ZEROP_##wc(R))                                        \
+           {                                                                \
+             /* return an exact zero */                                     \
+             if (FP_ROUNDMODE == FP_RND_MINF)                               \
+               R##_s |= Y##_s;                                              \
+             else                                                           \
+               R##_s &= Y##_s;                                              \
+             R##_c = FP_CLS_ZERO;                                           \
+           }                                                                \
+         else                                                               \
+           {                                                                \
+             if (_FP_FRAC_NEGP_##wc(R))                                     \
+               {                                                            \
+                 _FP_FRAC_SUB_##wc(R, Y, X);                                \
+                 R##_s = Y##_s;                                             \
+               }                                                            \
+                                                                            \
+             /* renormalize after subtraction */                            \
+             _FP_FRAC_CLZ_##wc(diff, R);                                    \
+             diff -= _FP_WFRACXBITS_##fs;                                   \
+             if (diff)                                                      \
+               {                                                            \
+                 R##_e -= diff;                                             \
+                 _FP_FRAC_SLL_##wc(R, diff);                                \
+               }                                                            \
+           }                                                                \
+       }                                                                    \
+      break;                                                                \
+    }                                                                       \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):                              \
+    _FP_CHOOSENAN(fs, wc, R, X, Y, OP);                                             \
+    break;                                                                  \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):                          \
+    R##_e = X##_e;                                                          \
+  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):                                     \
+    _FP_FRAC_COPY_##wc(R, X);                                               \
+    R##_s = X##_s;                                                          \
+    R##_c = X##_c;                                                          \
+    break;                                                                  \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                          \
+    R##_e = Y##_e;                                                          \
+  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):                                     \
+    _FP_FRAC_COPY_##wc(R, Y);                                               \
+    R##_s = Y##_s;                                                          \
+    R##_c = Y##_c;                                                          \
+    break;                                                                  \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):                              \
+    if (X##_s != Y##_s)                                                             \
+      {                                                                             \
+       /* +INF + -INF => NAN */                                             \
+       _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
+       R##_s = _FP_NANSIGN_##fs;                                            \
+       R##_c = FP_CLS_NAN;                                                  \
+       FP_SET_EXCEPTION(FP_EX_INVALID);                                     \
+       break;                                                               \
+      }                                                                             \
+    /* FALLTHRU */                                                          \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                           \
+  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                                     \
+    R##_s = X##_s;                                                          \
+    R##_c = FP_CLS_INF;                                                             \
+    break;                                                                  \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):                           \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                                     \
+    R##_s = Y##_s;                                                          \
+    R##_c = FP_CLS_INF;                                                             \
+    break;                                                                  \
+                                                                            \
+  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):                            \
+    /* make sure the sign is correct */                                             \
+    if (FP_ROUNDMODE == FP_RND_MINF)                                        \
+      R##_s = X##_s | Y##_s;                                                \
+    else                                                                    \
+      R##_s = X##_s & Y##_s;                                                \
+    R##_c = FP_CLS_ZERO;                                                    \
+    break;                                                                  \
+                                                                            \
+  default:                                                                  \
+    abort();                                                                \
+  }                                                                         \
+} 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##_c != FP_CLS_NAN) 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)
+
+/*
+ * 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
+ */
+
+/* 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 {                                                                         \
+    switch (X##_c)                                                             \
+      {                                                                                \
+      case FP_CLS_NORMAL:                                                      \
+       if (X##_e < 0)                                                          \
+         {                                                                     \
+           FP_SET_EXCEPTION(FP_EX_INEXACT);                                    \
+         case FP_CLS_ZERO:                                                     \
+           r = 0;                                                              \
+         }                                                                     \
+       else if (X##_e >= rsize - (rsigned > 0 || X##_s)                        \
+                || (!rsigned && X##_s))                                        \
+         {     /* overflow */                                                  \
+         case FP_CLS_NAN:                                                      \
+         case FP_CLS_INF:                                                      \
+           if (rsigned)                                                        \
+             {                                                                 \
+               r = 1;                                                          \
+               r <<= rsize - 1;                                                \
+               r -= 1 - X##_s;                                                 \
+             } else {                                                          \
+               r = 0;                                                          \
+               if (X##_s)                                                      \
+                 r = ~r;                                                       \
+             }                                                                 \
+           FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
+         }                                                                     \
+       else                                                                    \
+         {                                                                     \
+           if (_FP_W_TYPE_SIZE*wc < rsize)                                     \
+             {                                                                 \
+               _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
+               r <<= X##_e - _FP_WFRACBITS_##fs;                               \
+             }                                                                 \
+           else                                                                \
+             {                                                                 \
+               if (X##_e >= _FP_WFRACBITS_##fs)                                \
+                 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));       \
+               else if (X##_e < _FP_WFRACBITS_##fs - 1)                        \
+                 {                                                             \
+                   _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),      \
+                                     _FP_WFRACBITS_##fs);                      \
+                   if (_FP_FRAC_LOW_##wc(X) & 1)                               \
+                     FP_SET_EXCEPTION(FP_EX_INEXACT);                          \
+                   _FP_FRAC_SRL_##wc(X, 1);                                    \
+                 }                                                             \
+               _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
+             }                                                                 \
+           if (rsigned && X##_s)                                               \
+             r = -r;                                                           \
+         }                                                                     \
+       break;                                                                  \
+      }                                                                                \
+  } while (0)
+
+#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                       \
+  do {                                                                 \
+    if (r)                                                             \
+      {                                                                        \
+       X##_c = FP_CLS_NORMAL;                                          \
+                                                                       \
+       if ((X##_s = (r < 0)))                                          \
+         r = -r;                                                       \
+                                                                       \
+       if (rsize <= _FP_W_TYPE_SIZE)                                   \
+         __FP_CLZ(X##_e, r);                                           \
+       else                                                            \
+         __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE),         \
+                    (_FP_W_TYPE)r);                                    \
+       if (rsize < _FP_W_TYPE_SIZE)                                    \
+               X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
+       X##_e = rsize - X##_e - 1;                                      \
+                                                                       \
+       if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e)    \
+         __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize);      \
+       r &= ~((rtype)1 << X##_e);                                      \
+       _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize);       \
+       _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));         \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+       X##_c = FP_CLS_ZERO, X##_s = 0;                                 \
+      }                                                                        \
+  } while (0)
+
+
+#define FP_CONV(dfs,sfs,dwc,swc,D,S)                   \
+  do {                                                 \
+    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);       \
+    D##_e = S##_e;                                     \
+    D##_c = S##_c;                                     \
+    D##_s = S##_s;                                     \
+  } while (0)
+
+/*
+ * Helper primitives.
+ */
+
+/* Count leading zeros in a word.  */
+
+#ifndef __FP_CLZ
+#if _FP_W_TYPE_SIZE < 64
+/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
+#define __FP_CLZ(r, x)                         \
+  do {                                         \
+    _FP_W_TYPE _t = (x);                       \
+    r = _FP_W_TYPE_SIZE - 1;                   \
+    if (_t > 0xffff) r -= 16;                  \
+    if (_t > 0xffff) _t >>= 16;                        \
+    if (_t > 0xff) r -= 8;                     \
+    if (_t > 0xff) _t >>= 8;                   \
+    if (_t & 0xf0) r -= 4;                     \
+    if (_t & 0xf0) _t >>= 4;                   \
+    if (_t & 0xc) r -= 2;                      \
+    if (_t & 0xc) _t >>= 2;                    \
+    if (_t & 0x2) r -= 1;                      \
+  } while (0)
+#else /* not _FP_W_TYPE_SIZE < 64 */
+#define __FP_CLZ(r, x)                         \
+  do {                                         \
+    _FP_W_TYPE _t = (x);                       \
+    r = _FP_W_TYPE_SIZE - 1;                   \
+    if (_t > 0xffffffff) r -= 32;              \
+    if (_t > 0xffffffff) _t >>= 32;            \
+    if (_t > 0xffff) r -= 16;                  \
+    if (_t > 0xffff) _t >>= 16;                        \
+    if (_t > 0xff) r -= 8;                     \
+    if (_t > 0xff) _t >>= 8;                   \
+    if (_t & 0xf0) r -= 4;                     \
+    if (_t & 0xf0) _t >>= 4;                   \
+    if (_t & 0xc) r -= 2;                      \
+    if (_t & 0xc) _t >>= 2;                    \
+    if (_t & 0x2) r -= 1;                      \
+  } while (0)
+#endif /* not _FP_W_TYPE_SIZE < 64 */
+#endif /* ndef __FP_CLZ */
+
+#define _FP_DIV_HELP_imm(q, r, n, d)           \
+  do {                                         \
+    q = n / d, r = n % d;                      \
+  } while (0)
+
diff --git a/soft-fp/quad.h b/soft-fp/quad.h
new file mode 100644 (file)
index 0000000..92a1e2b
--- /dev/null
@@ -0,0 +1,201 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Quad Precision.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_IMPLBIT_Q          \
+       ((_FP_W_TYPE)1 << (_FP_FRACBITS_Q-1) % _FP_W_TYPE_SIZE)
+#define _FP_OVERFLOW_Q         \
+       ((_FP_W_TYPE)1 << (_FP_WFRACBITS_Q % _FP_W_TYPE_SIZE))
+
+#if _FP_W_TYPE_SIZE < 64
+
+union _FP_UNION_Q
+{
+   long double 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_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_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_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
+{
+  long double flt /* __attribute__((mode(TF))) */ ;
+  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_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_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_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/soft-fp/single.h b/soft-fp/single.h
new file mode 100644 (file)
index 0000000..6504e52
--- /dev/null
@@ -0,0 +1,110 @@
+/* Software floating-point emulation.
+   Definitions for IEEE Single Precision.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if _FP_W_TYPE_SIZE < 32
+#error "Here's a nickel kid.  Go buy yourself a real computer."
+#endif
+
+#define _FP_FRACBITS_S         24
+#define _FP_FRACXBITS_S                (_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
+#define _FP_WFRACBITS_S                (_FP_WORKBITS + _FP_FRACBITS_S)
+#define _FP_WFRACXBITS_S       (_FP_W_TYPE_SIZE - _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_IMPLBIT_S          ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
+#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.  */
+
+union _FP_UNION_S
+{
+  float 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_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_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_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/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
new file mode 100644 (file)
index 0000000..3c5072e
--- /dev/null
@@ -0,0 +1,176 @@
+/* Software floating-point emulation.
+   Copyright (C) 1997,1998,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef SOFT_FP_H
+#define SOFT_FP_H
+
+#include "sfp-machine.h"
+
+/* Allow sfp-machine to have its own byte order definitions. */
+#ifndef __BYTE_ORDER
+#include <endian.h>
+#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
+#ifndef FP_ROUNDMODE
+# define FP_ROUNDMODE          FP_RND_NEAREST
+#endif
+#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                
+#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)          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 SItype __attribute__((mode(SI)));
+typedef int DItype __attribute__((mode(DI)));
+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
+
+#ifndef umul_ppmm
+#include <stdlib/longlong.h>
+#endif
+
+#endif
diff --git a/soft-fp/sqrtdf2.c b/soft-fp/sqrtdf2.c
new file mode 100644 (file)
index 0000000..7cdaa37
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return sqrt(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __sqrtdf2(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+  FP_SQRT_D(R, A);
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sqrtsf2.c b/soft-fp/sqrtsf2.c
new file mode 100644 (file)
index 0000000..dd83cb9
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return sqrt(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __sqrtsf2(float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+  FP_SQRT_S(R, A);
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sqrttf2.c b/soft-fp/sqrttf2.c
new file mode 100644 (file)
index 0000000..1c5123d
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return sqrt(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __sqrttf2(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(R);
+  long double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_SQRT_Q(R, A);
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/subdf3.c b/soft-fp/subdf3.c
new file mode 100644 (file)
index 0000000..11c01cb
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+
+double __subdf3(double a, double b)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A); FP_DECL_D(B); FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+  FP_UNPACK_D(B, b);
+  FP_SUB_D(R, A, B);
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/subsf3.c b/soft-fp/subsf3.c
new file mode 100644 (file)
index 0000000..5942479
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+
+float __subsf3(float a, float b)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A); FP_DECL_S(B); FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+  FP_UNPACK_S(B, b);
+  FP_SUB_S(R, A, B);
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/subtf3.c b/soft-fp/subtf3.c
new file mode 100644 (file)
index 0000000..f3d29af
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return a - b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __subtf3(long double a, long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(R);
+  long double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_SUB_Q(R, A, B);
+  FP_PACK_Q(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/alpha/sfp-machine.h b/soft-fp/sysdeps/alpha/sfp-machine.h
new file mode 100644 (file)
index 0000000..73b934d
--- /dev/null
@@ -0,0 +1,35 @@
+#define _FP_W_TYPE_SIZE                64
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+#define _alpha_mul_64_128(rhi, rlo, x, y)              \
+  __asm__("umulh %2,%3,%0; mulq %2,%3,%1"              \
+         : "=&r"(rhi), "=r"(rlo) : "r"(x), "r"(y))
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,_alpha_mul_64_128)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,_alpha_mul_64_128)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          _FP_QNANBIT_S
+#define _FP_NANFRAC_D          _FP_QNANBIT_D
+#define _FP_NANFRAC_Q          _FP_QNANBIT_Q, 0
+/* FIXME: This is just a wild guess */
+#define _FP_NANSIGN_S          1
+#define _FP_NANSIGN_D          1
+#define _FP_NANSIGN_Q          1
+
+#define _FP_KEEPNANFRACP 1
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    R##_s = Y##_s;                                             \
+    _FP_FRAC_COPY_##wc(R,Y);                                   \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
diff --git a/soft-fp/sysdeps/i386/sfp-machine.h b/soft-fp/sysdeps/i386/sfp-machine.h
new file mode 100644 (file)
index 0000000..047452b
--- /dev/null
@@ -0,0 +1,87 @@
+#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_FRAC_ADD_2(rh, rl, xh, xl, yh, yl)                                \
+  __asm__("addl %5,%1; adcl %3,%0"                                     \
+         : "=r"(rh), "=r"(rl)                                          \
+         : "%0"(xh), "g"(yh), "%1"(xl), "g"(yl)                        \
+         : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                         \
+    __asm__ volatile("addl %5,%1; adcl %3,%0"                          \
+                    : "=r"(r1), "=r"(r0)                               \
+                    : "%0"(x1), "g"(y1), "%1"(x0), "g"(y0)             \
+                    : "cc");                                           \
+    __asm__ volatile("adcl %5,%1; adcl %3,%0"                          \
+                    : "=r"(r3), "=r"(r2)                               \
+                    : "%0"(x3), "g"(y3), "%1"(x2), "g"(y2)             \
+                    : "cc");                                           \
+  } while (0)
+
+#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl)                                \
+  __asm__("subl %5,%1; sbbl %4,%0"                                     \
+         : "=r"(rh), "=r"(rl)                                          \
+         : "0"(xh), "1"(xl), "g"(yh), "g"(yl)                          \
+         : "cc")
+
+#define __FP_CLZ(r, x)                                                 \
+  do {                                                                 \
+    __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc");                   \
+    r ^= 31;                                                           \
+  } while (0)
+
+#define _i386_mul_32_64(rh, rl, x, y)                                  \
+  __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc")
+
+#define _i386_div_64_32(q, r, nh, nl, d)                               \
+  __asm__ ("divl %4" : "=a"(q), "=d"(r) : "0"(nl), "1"(nh), "g"(d) : "cc")
+
+
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,_i386_mul_32_64)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,_i386_mul_32_64)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+
+#define _FP_NANFRAC_S          _FP_QNANBIT_S
+#define _FP_NANFRAC_D          _FP_QNANBIT_D, 0
+#define _FP_NANSIGN_S          1
+#define _FP_NANSIGN_D          1
+
+#define _FP_KEEPNANFRACP 1
+/* Here is something Intel misdesigned: the specs don't define
+   the case where we have two NaNs with same mantissas, but
+   different sign. Different operations pick up different NaNs.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if (_FP_FRAC_GT_##wc(X, Y)                                 \
+       || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \
+      {                                                                \
+       R##_s = X##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,X);                               \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,Y);                               \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+#define FP_EX_INVALID           (1 << 0)
+#define FP_EX_DENORM           (1 << 1)
+#define FP_EX_DIVZERO           (1 << 2)
+#define FP_EX_OVERFLOW          (1 << 3)
+#define FP_EX_UNDERFLOW         (1 << 4)
+#define FP_EX_INEXACT           (1 << 5)
+
+#define FP_RND_NEAREST         0
+#define FP_RND_ZERO            3
+#define FP_RND_PINF            2
+#define FP_RND_MINF            1
diff --git a/soft-fp/sysdeps/mips/mips64/sfp-machine.h b/soft-fp/sysdeps/mips/mips64/sfp-machine.h
new file mode 100644 (file)
index 0000000..3f9d3ab
--- /dev/null
@@ -0,0 +1,47 @@
+#define _FP_W_TYPE_SIZE                64
+#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_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+/* From my experiments it seems X is chosen unless one of the
+   NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) |                           \
+        _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs)         \
+      {                                                                \
+       R##_s = _FP_NANSIGN_##fs;                               \
+        _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs);                 \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = X##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,X);                               \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+#define FP_EX_INVALID           (1 << 4)
+#define FP_EX_DIVZERO           (1 << 3)
+#define FP_EX_OVERFLOW          (1 << 2)
+#define FP_EX_UNDERFLOW         (1 << 1)
+#define FP_EX_INEXACT           (1 << 0)
diff --git a/soft-fp/sysdeps/mips/sfp-machine.h b/soft-fp/sysdeps/mips/sfp-machine.h
new file mode 100644 (file)
index 0000000..575225a
--- /dev/null
@@ -0,0 +1,47 @@
+#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_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 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
+/* From my experiments it seems X is chosen unless one of the
+   NaNs is sNaN,  in which case the result is NANSIGN/NANFRAC.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(X) |                           \
+        _FP_FRAC_HIGH_RAW_##fs(Y)) & _FP_QNANBIT_##fs)         \
+      {                                                                \
+       R##_s = _FP_NANSIGN_##fs;                               \
+        _FP_FRAC_SET_##wc(R,_FP_NANFRAC_##fs);                 \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = X##_s;                                          \
+        _FP_FRAC_COPY_##wc(R,X);                               \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+#define FP_EX_INVALID           (1 << 4)
+#define FP_EX_DIVZERO           (1 << 3)
+#define FP_EX_OVERFLOW          (1 << 2)
+#define FP_EX_UNDERFLOW         (1 << 1)
+#define FP_EX_INEXACT           (1 << 0)
diff --git a/soft-fp/sysdeps/powerpc/sfp-machine.h b/soft-fp/sysdeps/powerpc/sfp-machine.h
new file mode 100644 (file)
index 0000000..6d68f01
--- /dev/null
@@ -0,0 +1,48 @@
+#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_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 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)
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
diff --git a/soft-fp/sysdeps/sparc/sparc32/Makefile b/soft-fp/sysdeps/sparc/sparc32/Makefile
new file mode 100644 (file)
index 0000000..71a34f9
--- /dev/null
@@ -0,0 +1,31 @@
+#  Software floating-point emulation.
+#  Makefile for SPARC v8 long double utility functions (_Q_*).
+#  Copyright (C) 1999 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 Library General Public License as
+#  published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  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
+#  Library General Public License for more details.
+#
+#  You should have received a copy of the GNU Library General Public
+#  License along with the GNU C Library; see the file COPYING.LIB.  If
+#  not, write to the Free Software Foundation, Inc.,
+#  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#  Currently gcc does not support TFmode long double on sparc32
+#  so these routines are not used.
+#ifeq ($(subdir),soft-fp)
+#sparc32-quad-routines := q_add q_cmp q_cmpe q_div q_dtoq q_feq q_fge  \
+#      q_fgt q_fle q_flt q_fne q_itoq q_mul q_neg q_qtod q_qtoi        \
+#      q_qtos q_qtoui q_qtoux q_qtox q_sqrt q_stoq q_sub q_uitoq       \
+#      q_uxtoq q_xtoq q_util
+#routines += $(sparc32-quad-routines)
+#
+#endif
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_add.c b/soft-fp/sysdeps/sparc/sparc32/q_add.c
new file mode 100644 (file)
index 0000000..b2d3f2e
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return a + b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_add(const long double a, const long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_ADD_Q(C, A, B);
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_cmp.c b/soft-fp/sysdeps/sparc/sparc32/q_cmp.c
new file mode 100644 (file)
index 0000000..87535f9
--- /dev/null
@@ -0,0 +1,41 @@
+/* Software floating-point emulation.
+   Compare a and b, return float condition code.
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_cmp(const long double a, const long double 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, B, A, 3);
+  if (r == -1) r = 2;
+  if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_cmpe.c b/soft-fp/sysdeps/sparc/sparc32/q_cmpe.c
new file mode 100644 (file)
index 0000000..ddc880a
--- /dev/null
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+   Compare a and b, return float condition code.
+   Signal exception (unless masked) if unordered.
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_cmpe(const long double a, const long double 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, B, A, 3);
+  if (r == -1) r = 2;
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_div.c b/soft-fp/sysdeps/sparc/sparc32/q_div.c
new file mode 100644 (file)
index 0000000..477f397
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return a / b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_div(const long double a, const long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_DIV_Q(C, A, B);
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return long double;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_dtoq.c b/soft-fp/sysdeps/sparc/sparc32/q_dtoq.c
new file mode 100644 (file)
index 0000000..28daa2c
--- /dev/null
@@ -0,0 +1,44 @@
+/* Software floating-point emulation.
+   Return (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+long double _Q_dtoq(const double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,D,4,2,C,A);
+#else
+  FP_CONV(Q,D,2,1,C,A);
+#endif
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_feq.c b/soft-fp/sysdeps/sparc/sparc32/q_feq.c
new file mode 100644 (file)
index 0000000..5289116
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a == b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_feq(const long double a, const long double 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;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_fge.c b/soft-fp/sysdeps/sparc/sparc32/q_fge.c
new file mode 100644 (file)
index 0000000..f4bc613
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a >= b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fge(const long double a, const long double 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, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return (r <= 0);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_fgt.c b/soft-fp/sysdeps/sparc/sparc32/q_fgt.c
new file mode 100644 (file)
index 0000000..ad2c5cb
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a > b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fgt(const long double a, const long double 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, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return (r == -1);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_fle.c b/soft-fp/sysdeps/sparc/sparc32/q_fle.c
new file mode 100644 (file)
index 0000000..ffd3c00
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a <= b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fle(const long double a, const long double 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, B, A, -2);
+  if (r == -2)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return (r >= 0);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_flt.c b/soft-fp/sysdeps/sparc/sparc32/q_flt.c
new file mode 100644 (file)
index 0000000..20c2e1f
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a < b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_flt(const long double a, const long double 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, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  FP_HANDLE_EXCEPTIONS;
+
+  return (r == 1);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_fne.c b/soft-fp/sysdeps/sparc/sparc32/q_fne.c
new file mode 100644 (file)
index 0000000..f885ddb
--- /dev/null
@@ -0,0 +1,40 @@
+/* Software floating-point emulation.
+   Return 1 if a != b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_fne(const long double a, const long double 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;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_itoq.c b/soft-fp/sysdeps/sparc/sparc32/q_itoq.c
new file mode 100644 (file)
index 0000000..97af148
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_itoq(const int a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  int b = a;
+  long double c;
+
+  FP_FROM_INT_Q(C, b, 32, int);
+  FP_PACK_Q(c, C);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_mul.c b/soft-fp/sysdeps/sparc/sparc32/q_mul.c
new file mode 100644 (file)
index 0000000..2ce0ceb
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   Return a * b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_mul(const long double a, const long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_MUL_Q(C, A, B);
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_neg.c b/soft-fp/sysdeps/sparc/sparc32/q_neg.c
new file mode 100644 (file)
index 0000000..a1a5f2d
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Return !a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_neg(const long double a)
+{
+  FP_DECL_EX;
+  long double c = a;
+  
+#if (__BYTE_ORDER == __BIG_ENDIAN)
+  ((UWtype *)&c)[0] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 64)
+  ((UWtype *)&c)[1] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#elif (__BYTE_ORDER == __LITTLE_ENDIAN) && (W_TYPE_SIZE == 32)
+  ((UWtype *)&c)[3] ^= (((UWtype)1) << (W_TYPE_SIZE - 1));
+#else
+  FP_DECL_Q(A); FP_DECL_Q(C);
+
+  FP_UNPACK_Q(A, a);
+  FP_NEG_Q(C, A);
+  FP_PACK_Q(c, C);
+#endif
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtod.c b/soft-fp/sysdeps/sparc/sparc32/q_qtod.c
new file mode 100644 (file)
index 0000000..9287450
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return (double)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double _Q_qtod(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(D,Q,2,4,R,A);
+#else
+  FP_CONV(D,Q,1,2,R,A);
+#endif
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtoi.c b/soft-fp/sysdeps/sparc/sparc32/q_qtoi.c
new file mode 100644 (file)
index 0000000..b472364
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (int)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Q_qtoi(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  int r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 32, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtos.c b/soft-fp/sysdeps/sparc/sparc32/q_qtos.c
new file mode 100644 (file)
index 0000000..b0945cb
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Return (float)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float _Q_qtos(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(S,Q,1,4,R,A);
+#else
+  FP_CONV(S,Q,1,2,R,A);
+#endif
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtoui.c b/soft-fp/sysdeps/sparc/sparc32/q_qtoui.c
new file mode 100644 (file)
index 0000000..c2de37f
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (unsigned int)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned int _Q_qtoui(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  unsigned int r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 32, -1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtoux.c b/soft-fp/sysdeps/sparc/sparc32/q_qtoux.c
new file mode 100644 (file)
index 0000000..ff1e1a9
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (unsigned long)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned long long _Q_qtoux(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  unsigned long long r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 64, -1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_qtox.c b/soft-fp/sysdeps/sparc/sparc32/q_qtox.c
new file mode 100644 (file)
index 0000000..ba59160
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (long)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+long long _Q_qtox(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long long r;
+
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 64, 1);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_sqrt.c b/soft-fp/sysdeps/sparc/sparc32/q_sqrt.c
new file mode 100644 (file)
index 0000000..2f75928
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return sqrtl(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_sqrt(const long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_SQRT_Q(C, A);
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_stoq.c b/soft-fp/sysdeps/sparc/sparc32/q_stoq.c
new file mode 100644 (file)
index 0000000..ad5153d
--- /dev/null
@@ -0,0 +1,43 @@
+/* Software floating-point emulation.
+   c = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+long double _Q_stoq(const float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_Q(C);
+  long double c;
+
+  FP_UNPACK_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,S,4,1,C,A);
+#else
+  FP_CONV(Q,S,2,1,C,A);
+#endif
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_sub.c b/soft-fp/sysdeps/sparc/sparc32/q_sub.c
new file mode 100644 (file)
index 0000000..2cfd49d
--- /dev/null
@@ -0,0 +1,39 @@
+/* Software floating-point emulation.
+   c = a - b
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_sub(const long double a, const long double b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  long double c;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_UNPACK_Q(B, b);
+  FP_SUB_Q(C, A, B);
+  FP_PACK_Q(c, C);
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_uitoq.c b/soft-fp/sysdeps/sparc/sparc32/q_uitoq.c
new file mode 100644 (file)
index 0000000..8a3c664
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   c = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_uitoq(const unsigned int a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  long double c;
+  unsigned int b = a;
+
+  FP_FROM_INT_Q(C, b, 32, int);
+  FP_PACK_Q(c, C);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_util.c b/soft-fp/sysdeps/sparc/sparc32/q_util.c
new file mode 100644 (file)
index 0000000..df4d16c
--- /dev/null
@@ -0,0 +1,57 @@
+/* Software floating-point emulation.
+   Helper routine for _Q_* routines.
+   Simulate exceptions using double arithmetics.
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+
+unsigned long long ___Q_numbers [] = {
+0x0000000000000000ULL, /* Zero */
+0x0010100000000000ULL, /* Very tiny number */
+0x0010000000000000ULL, /* Minimum normalized number */
+0x7fef000000000000ULL, /* A huge double number */
+};
+
+double ___Q_simulate_exceptions(int exceptions)
+{
+  double d, *p = (double *)___Q_numbers;
+  if (exceptions & FP_EX_INVALID)
+    d = p[0]/p[0];
+  if (exceptions & FP_EX_OVERFLOW)
+    {
+      d = p[3] + p[3];
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_UNDERFLOW)
+    {
+      if (exceptions & FP_EX_INEXACT)
+        {
+         d = p[2] * p[2];
+         exceptions &= ~FP_EX_INEXACT;
+       }
+      else
+       d = p[1] - p[2];
+    }
+  if (exceptions & FP_EX_DIVZERO)
+    d = 1.0/p[0];
+  if (exceptions & FP_EX_INEXACT)
+    d = p[3] - p[2];
+  return d;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_uxtoq.c b/soft-fp/sysdeps/sparc/sparc32/q_uxtoq.c
new file mode 100644 (file)
index 0000000..ee68ca2
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_uxtoq(const unsigned long long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  long double c;
+  unsigned long long b = a;
+
+  FP_FROM_INT_Q(C, b, 64, long long);
+  FP_PACK_Q(c, C);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/q_xtoq.c b/soft-fp/sysdeps/sparc/sparc32/q_xtoq.c
new file mode 100644 (file)
index 0000000..3dd70b9
--- /dev/null
@@ -0,0 +1,38 @@
+/* Software floating-point emulation.
+   Return (long double)a
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double _Q_xtoq(const long long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  long double c;
+  long long b = a;
+
+  FP_FROM_INT_Q(C, b, 64, long long);
+  FP_PACK_Q(c, C);
+  FP_CLEAR_EXCEPTIONS;
+  FP_HANDLE_EXCEPTIONS;
+  return c;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc32/sfp-machine.h b/soft-fp/sysdeps/sparc/sparc32/sfp-machine.h
new file mode 100644 (file)
index 0000000..d3713b9
--- /dev/null
@@ -0,0 +1,221 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc userland (_Q_*) version.
+   Copyright (C) 1997,1998,1999 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
+                 David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   
+#include <fpu_control.h>
+
+#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_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 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
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#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)
+
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("addcc %r7,%8,%2
+           addxcc %r5,%6,%1
+           addx %r3,%4,%0"                                             \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)                    \
+  __asm__ ("subcc %r7,%8,%2
+           subxcc %r5,%6,%1
+           subx %r3,%4,%0"                                             \
+          : "=r" ((USItype)(r2)),                                      \
+            "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ ("
+           addcc %r8,%9,%1
+           addxcc %r6,%7,%0
+           addxcc %r4,%5,%%g2
+           addx %r2,%3,%%g1"                                           \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)           \
+  do {                                                                 \
+    /* We need to fool gcc,  as we need to pass more than 10           \
+       input/outputs.  */                                              \
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");           \
+    __asm__ __volatile__ ("
+           subcc %r8,%9,%1
+           subxcc %r6,%7,%0
+           subxcc %r4,%5,%%g2
+           subx %r2,%3,%%g1"                                           \
+          : "=&r" ((USItype)(r1)),                                     \
+            "=&r" ((USItype)(r0))                                      \
+          : "%rJ" ((USItype)(x3)),                                     \
+            "rI" ((USItype)(y3)),                                      \
+            "%rJ" ((USItype)(x2)),                                     \
+            "rI" ((USItype)(y2)),                                      \
+            "%rJ" ((USItype)(x1)),                                     \
+            "rI" ((USItype)(y1)),                                      \
+            "%rJ" ((USItype)(x0)),                                     \
+            "rI" ((USItype)(y0))                                       \
+          : "cc", "g1", "g2");                                         \
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));                        \
+    r3 = _t1; r2 = _t2;                                                        \
+  } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)                                        \
+  __asm__ ("addcc %3,%4,%3
+           addxcc %2,%%g0,%2
+           addxcc %1,%%g0,%1
+           addx %0,%%g0,%0"                                            \
+          : "=&r" ((USItype)(x3)),                                     \
+            "=&r" ((USItype)(x2)),                                     \
+            "=&r" ((USItype)(x1)),                                     \
+            "=&r" ((USItype)(x0))                                      \
+          : "rI" ((USItype)(i)),                                       \
+            "0" ((USItype)(x3)),                                       \
+            "1" ((USItype)(x2)),                                       \
+            "2" ((USItype)(x1)),                                       \
+            "3" ((USItype)(x0))                                        \
+          : "cc")
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE   ((_fcw >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define _FP_DECL_EX    fpu_control_t _fcw
+
+#define FP_INIT_ROUNDMODE                                      \
+do {                                                           \
+  _FPU_GETCW(_fcw);                                            \
+} while (0)
+
+/* Simulate exceptions using double arithmetics. */
+extern double ___Q_simulate_exceptions(int exc);
+
+#define FP_HANDLE_EXCEPTIONS                                   \
+do {                                                           \
+  if (!_fex)                                                   \
+    {                                                          \
+      /* This is the common case, so we do it inline.          \
+       * We need to clear cexc bits if any.                    \
+       */                                                      \
+      extern unsigned long long ___Q_numbers[];                        \
+      __asm__ __volatile__("
+       ldd [%0], %%f30
+       faddd %%f30, %%f30, %%f30
+       " : : "r" (___Q_numbers) : "f30");                      \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      __asm__ __volatile__("
+        mov %0, %%o0
+        mov %%o7, %%g1
+        call ___Q_simulate_exceptions
+         mov %%g1, %%o7
+        " : : "r" (_fex) :                                     \
+        "g1", "g2", "g3", "g4", "g5", "o0",                    \
+        "o1", "o2", "o3", "o4", "o5", "cc");                   \
+    }                                                          \
+} while (0)
diff --git a/soft-fp/sysdeps/sparc/sparc64/Makefile b/soft-fp/sysdeps/sparc/sparc64/Makefile
new file mode 100644 (file)
index 0000000..3e912e5
--- /dev/null
@@ -0,0 +1,33 @@
+#  Software floating-point emulation.
+#  Makefile for SPARC v9 ABI mandated long double utility
+#  functions (_Qp_*).
+#  Copyright (C) 1999 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 Library General Public License as
+#  published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  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
+#  Library General Public License for more details.
+#
+#  You should have received a copy of the GNU Library General Public
+#  License along with the GNU C Library; see the file COPYING.LIB.  If
+#  not, write to the Free Software Foundation, Inc.,
+#  59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ifeq ($(subdir),soft-fp)
+sparc64-quad-routines := qp_add qp_cmp qp_cmpe qp_div qp_dtoq qp_feq qp_fge \
+       qp_fgt qp_fle qp_flt qp_fne qp_itoq qp_mul qp_neg qp_qtod qp_qtoi   \
+       qp_qtos qp_qtoui qp_qtoux qp_qtox qp_sqrt qp_stoq qp_sub qp_uitoq   \
+       qp_uxtoq qp_xtoq qp_util
+routines += $(sparc64-quad-routines)
+endif
+
+ifeq ($(subdir),math)
+CPPFLAGS += -I../soft-fp/
+endif
diff --git a/soft-fp/sysdeps/sparc/sparc64/Versions b/soft-fp/sysdeps/sparc/sparc64/Versions
new file mode 100644 (file)
index 0000000..599708a
--- /dev/null
@@ -0,0 +1,7 @@
+libc {
+  GLIBC_2.1.1 {
+    _Qp_add; _Qp_cmp; _Qp_cmpe; _Qp_div; _Qp_dtoq; _Qp_feq; _Qp_fge; _Qp_fgt;
+    _Qp_fle; _Qp_flt; _Qp_fne; _Qp_itoq; _Qp_mul; _Qp_neg; _Qp_qtod; _Qp_qtoi;
+    _Qp_qtos; _Qp_qtoui; _Qp_qtoux; _Qp_qtox; _Qp_sqrt; _Qp_stoq; _Qp_sub;
+    _Qp_uitoq; _Qp_uxtoq; _Qp_xtoq; __Qp_handle_exceptions;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_add.c b/soft-fp/sysdeps/sparc/sparc64/qp_add.c
new file mode 100644 (file)
index 0000000..b77f4d4
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   (*c) = (*a) + (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_add(long double *c, const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_UNPACK_QP(B, b);
+  FP_ADD_Q(C, A, B);
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        ldd [%2], %%f56
+        ldd [%2+8], %%f58
+        faddq %%f52, %%f56, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_cmp.c b/soft-fp/sysdeps/sparc/sparc64/qp_cmp.c
new file mode 100644 (file)
index 0000000..739fb5e
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Compare (*a) and (*b), return float condition code.
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_cmp(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, 3);
+  if (r == -1) r = 2;
+  if (r == 3 && (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B)))
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3));
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_cmpe.c b/soft-fp/sysdeps/sparc/sparc64/qp_cmpe.c
new file mode 100644 (file)
index 0000000..d881f90
--- /dev/null
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+   Compare (*a) and (*b), return float condition code.
+   Signal exception (unless masked) if unordered.
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_cmpe(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, 3);
+  if (r == -1) r = 2;
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpeq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3));
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_div.c b/soft-fp/sysdeps/sparc/sparc64/qp_div.c
new file mode 100644 (file)
index 0000000..c79ac1b
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   (*c) = (*a) / (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_div(long double *c, const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_UNPACK_QP(B, b);
+  FP_DIV_Q(C, A, B);
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        ldd [%2], %%f56
+        ldd [%2+8], %%f58
+        fdivq %%f52, %%f56, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_dtoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_dtoq.c
new file mode 100644 (file)
index 0000000..079b6d0
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+void _Qp_dtoq(long double *c, const double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,D,4,2,C,A);
+#else
+  FP_CONV(Q,D,2,1,C,A);
+#endif
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "fdtoq %1, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "e" (a) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_feq.c b/soft-fp/sysdeps/sparc/sparc64/qp_feq.c
new file mode 100644 (file)
index 0000000..1d32ec6
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) == (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_feq(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(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);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3));
+
+  return !r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_fge.c b/soft-fp/sysdeps/sparc/sparc64/qp_fge.c
new file mode 100644 (file)
index 0000000..6d73745
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) >= (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fge(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpeq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 1));
+
+  return (r <= 0);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_fgt.c b/soft-fp/sysdeps/sparc/sparc64/qp_fgt.c
new file mode 100644 (file)
index 0000000..e389fd9
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) > (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fgt(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpeq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3) - 3);
+
+  return (r == -1);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_fle.c b/soft-fp/sysdeps/sparc/sparc64/qp_fle.c
new file mode 100644 (file)
index 0000000..2afe2af
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) <= (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fle(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, -2);
+  if (r == -2)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpeq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 2) ? -1 : 0);
+
+  return (r >= 0);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_flt.c b/soft-fp/sysdeps/sparc/sparc64/qp_flt.c
new file mode 100644 (file)
index 0000000..42c8659
--- /dev/null
@@ -0,0 +1,51 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) < (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_flt(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(B, b);
+  FP_CMP_Q(r, B, A, 3);
+  if (r == 3)
+    FP_SET_EXCEPTION(FP_EX_INVALID);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpeq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3));
+
+  return (r == 1);
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_fne.c b/soft-fp/sysdeps/sparc/sparc64/qp_fne.c
new file mode 100644 (file)
index 0000000..bcc1ec2
--- /dev/null
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+   Return 1 if (*a) != (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_fne(const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_RAW_QP(A, a);
+  FP_UNPACK_RAW_QP(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);
+
+  QP_HANDLE_EXCEPTIONS(
+       __asm (
+       "ldd [%0], %%f52
+        ldd [%0+8], %%f54
+        ldd [%1], %%f56
+        ldd [%1+8], %%f58
+        fcmpq %%fcc3, %%f52, %%f56
+       " : : "r" (a), "r" (b) : QP_CLOBBER_CC);
+       _FPU_GETCW(_fcw);
+       r = ((_fcw >> 36) & 3) != 0);
+
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_itoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_itoq.c
new file mode 100644 (file)
index 0000000..b1b80ac
--- /dev/null
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_itoq(long double *c, const int a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  int b = a;
+
+  FP_FROM_INT_Q(C, b, 32, int);
+  FP_PACK_QP(c, C);
+  QP_NO_EXCEPTIONS;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_mul.c b/soft-fp/sysdeps/sparc/sparc64/qp_mul.c
new file mode 100644 (file)
index 0000000..9dbc06b
--- /dev/null
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+   (*c) = (*a) * (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* As QP_HANDLE_EXCEPTIONS reloads FPU control word anyway,
+   avoid doing it twice.  */
+#define _FP_MUL_MEAT_RESET_FE do {} while (0)
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_mul(long double *c, const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_UNPACK_QP(B, b);
+  FP_MUL_Q(C, A, B);
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(
+       _FPU_SETCW(_fcw);
+       __asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        ldd [%2], %%f56
+        ldd [%2+8], %%f58
+        fmulq %%f52, %%f56, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_neg.S b/soft-fp/sysdeps/sparc/sparc64/qp_neg.S
new file mode 100644 (file)
index 0000000..4064a8d
--- /dev/null
@@ -0,0 +1,31 @@
+/* Quad floating-point emulation.
+   (*c) = !(*a)
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+ENTRY(_Qp_neg)
+       ldd     [%o1], %f60
+       ldd     [%o1 + 8], %f62
+       fnegd   %f60, %f60
+       std     %f60, [%o0]
+       jmpl    %o7 + 8, %g0
+        std    %f62, [%o0 + 8]
+END(_Qp_neg)
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtod.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtod.c
new file mode 100644 (file)
index 0000000..50c4402
--- /dev/null
@@ -0,0 +1,49 @@
+/* Software floating-point emulation.
+   Return (double)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double _Qp_qtod(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(D,Q,2,4,R,A);
+#else
+  FP_CONV(D,Q,1,2,R,A);
+#endif
+  FP_PACK_D(r, R);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtod %%f52, %0
+       " : "=&e" (r) : "r" (a) : QP_CLOBBER));
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtoi.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtoi.c
new file mode 100644 (file)
index 0000000..770c887
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Return (int)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+int _Qp_qtoi(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_TO_INT_Q(r, A, 32, 1);
+  QP_HANDLE_EXCEPTIONS(
+       int rx;
+       __asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtoi %%f52, %%f60
+        st %%f60, [%0]
+       " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+       r = rx);
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtos.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtos.c
new file mode 100644 (file)
index 0000000..630300e
--- /dev/null
@@ -0,0 +1,50 @@
+/* Software floating-point emulation.
+   Return (float)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float _Qp_qtos(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(S,Q,1,4,R,A);
+#else
+  FP_CONV(S,Q,1,2,R,A);
+#endif
+  FP_PACK_S(r, R);
+
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtos %%f52, %0
+       " : "=&f" (r) : "r" (a) : QP_CLOBBER));
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtoui.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtoui.c
new file mode 100644 (file)
index 0000000..011cf73
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Return (unsigned int)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned int _Qp_qtoui(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  unsigned int r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_TO_INT_Q(r, A, 32, -1);
+  QP_HANDLE_EXCEPTIONS(
+       int rx;
+       __asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtoi %%f52, %%f60
+        st %%f60, [%0]
+       " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+       r = rx);
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtoux.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtoux.c
new file mode 100644 (file)
index 0000000..f2a393a
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Return (unsigned long)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+unsigned long _Qp_qtoux(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  unsigned long r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_TO_INT_Q(r, A, 64, -1);
+  QP_HANDLE_EXCEPTIONS(
+       unsigned long rx;
+       __asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtoi %%f52, %%f60
+        std %%f60, [%0]
+       " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+       r = rx);
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_qtox.c b/soft-fp/sysdeps/sparc/sparc64/qp_qtox.c
new file mode 100644 (file)
index 0000000..a54c5c5
--- /dev/null
@@ -0,0 +1,47 @@
+/* Software floating-point emulation.
+   Return (long)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define FP_ROUNDMODE FP_RND_ZERO
+#include "soft-fp.h"
+#include "quad.h"
+
+long _Qp_qtox(const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_TO_INT_Q(r, A, 64, 1);
+  QP_HANDLE_EXCEPTIONS(
+       long rx;
+       __asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fqtoi %%f52, %%f60
+        std %%f60, [%0]
+       " : : "r" (&rx), "r" (a) : QP_CLOBBER);
+       r = rx);
+
+  return r;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_sqrt.c b/soft-fp/sysdeps/sparc/sparc64/qp_sqrt.c
new file mode 100644 (file)
index 0000000..00e3980
--- /dev/null
@@ -0,0 +1,42 @@
+/* Software floating-point emulation.
+   (*c) = sqrtl(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_sqrt(long double *c, const long double *a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_SQRT_Q(C, A);
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        fsqrtq %%f52, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "r" (a) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_stoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_stoq.c
new file mode 100644 (file)
index 0000000..ab0f49a
--- /dev/null
@@ -0,0 +1,46 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+void _Qp_stoq(long double *c, const float a)
+{
+  FP_DECL_EX;
+  FP_DECL_S(A);
+  FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_S(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(Q,S,4,1,C,A);
+#else
+  FP_CONV(Q,S,2,1,C,A);
+#endif
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "fstoq %1, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "f" (a) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_sub.c b/soft-fp/sysdeps/sparc/sparc64/qp_sub.c
new file mode 100644 (file)
index 0000000..9532f7b
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   (*c) = (*a) - (*b)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_sub(long double *c, const long double *a, const long double *b)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_QP(A, a);
+  FP_UNPACK_QP(B, b);
+  FP_SUB_Q(C, A, B);
+  FP_PACK_QP(c, C);
+  QP_HANDLE_EXCEPTIONS(__asm (
+       "ldd [%1], %%f52
+        ldd [%1+8], %%f54
+        ldd [%2], %%f56
+        ldd [%2+8], %%f58
+        fsubq %%f52, %%f56, %%f60
+        std %%f60, [%0]
+        std %%f62, [%0+8]
+       " : : "r" (c), "r" (a), "r" (b) : QP_CLOBBER));
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_uitoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_uitoq.c
new file mode 100644 (file)
index 0000000..e35f0c6
--- /dev/null
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_uitoq(long double *c, const unsigned int a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  unsigned int b = a;
+
+  FP_FROM_INT_Q(C, b, 32, int);
+  FP_PACK_QP(c, C);
+  QP_NO_EXCEPTIONS;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_util.c b/soft-fp/sysdeps/sparc/sparc64/qp_util.c
new file mode 100644 (file)
index 0000000..3009b22
--- /dev/null
@@ -0,0 +1,57 @@
+/* Software floating-point emulation.
+   Helper routine for _Qp_* routines.
+   Simulate exceptions using double arithmetics.
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+
+static unsigned long numbers [] = {
+0x7fef000000000000UL, /* A huge double number */
+0x0010100000000000UL, /* Very tiny number */
+0x0010000000000000UL, /* Minimum normalized number */
+0x0000000000000000UL, /* Zero */
+};
+
+double __Qp_handle_exceptions(int exceptions)
+{
+  double d, *p = (double *)numbers;
+  if (exceptions & FP_EX_INVALID)
+    d = p[3]/p[3];
+  if (exceptions & FP_EX_OVERFLOW)
+    {
+      d = p[0] + p[0];
+      exceptions &= ~FP_EX_INEXACT;
+    }
+  if (exceptions & FP_EX_UNDERFLOW)
+    {
+      if (exceptions & FP_EX_INEXACT)
+        {
+         d = p[2] * p[2];
+         exceptions &= ~FP_EX_INEXACT;
+       }
+      else
+       d = p[1] - p[2];
+    }
+  if (exceptions & FP_EX_DIVZERO)
+    d = 1.0/p[3];
+  if (exceptions & FP_EX_INEXACT)
+    d = p[0] - p[2];
+  return d;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_uxtoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_uxtoq.c
new file mode 100644 (file)
index 0000000..d7442cf
--- /dev/null
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_uxtoq(long double *c, const unsigned long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  unsigned long b = a;
+
+  FP_FROM_INT_Q(C, b, 64, long);
+  FP_PACK_QP(c, C);
+  QP_NO_EXCEPTIONS;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/qp_xtoq.c b/soft-fp/sysdeps/sparc/sparc64/qp_xtoq.c
new file mode 100644 (file)
index 0000000..06cfa9a
--- /dev/null
@@ -0,0 +1,35 @@
+/* Software floating-point emulation.
+   (*c) = (long double)(*a)
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+void _Qp_xtoq(long double *c, const long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  long b = a;
+
+  FP_FROM_INT_Q(C, b, 64, long);
+  FP_PACK_QP(c, C);
+  QP_NO_EXCEPTIONS;
+}
diff --git a/soft-fp/sysdeps/sparc/sparc64/s_frexpl.c b/soft-fp/sysdeps/sparc/sparc64/s_frexpl.c
new file mode 100644 (file)
index 0000000..a307a7e
--- /dev/null
@@ -0,0 +1,52 @@
+/* Software floating-point emulation.
+   frexpl(x, exp)
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/*
+ * for non-zero x
+ *      x = frexpl(arg,&exp);
+ * return a long double fp quantity x such that 0.5 <= |x| <1.0
+ * and the corresponding binary exponent "exp". That is
+ *      arg = x*2^exp.
+ * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
+ * with *exp=0.
+ */       
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __frexpl(long double arg, int *exp)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long double r;
+
+  *exp = 0;
+  FP_UNPACK_Q(A, arg);
+  if (A_c != FP_CLS_NORMAL)
+    return arg;
+  *exp = A_e + 1;
+  A_e = -1;
+  FP_PACK_Q(r, A);
+
+  return r;
+}
+
+weak_alias (__frexpl, frexpl)
diff --git a/soft-fp/sysdeps/sparc/sparc64/s_ilogbl.c b/soft-fp/sysdeps/sparc/sparc64/s_ilogbl.c
new file mode 100644 (file)
index 0000000..d3b1a51
--- /dev/null
@@ -0,0 +1,82 @@
+/* Software floating-point emulation.
+   ilogbl(x, exp)
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* ilogbl(long double x)
+ * return the binary exponent of non-zero x
+ * ilogbl(0) = 0x80000001
+ * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised)
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+#include <math.h>
+
+int __ilogbl(long double x)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(X);
+
+/*
+  FP_UNPACK_Q(X, x);
+  switch (X_c)
+    {
+    case FP_CLS_ZERO:
+      return FP_ILOGB0;
+    case FP_CLS_NAN:
+    case FP_CLS_INF:
+      return FP_ILOGBNAN;
+    default:
+      return X_e;
+    }
+ */
+  FP_UNPACK_RAW_Q(X, x);
+  switch (X_e)
+    {
+    default:
+      return X_e - _FP_EXPBIAS_Q;
+    case 0:
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+      if (_FP_FRAC_ZEROP_4(X))
+       return FP_ILOGB0;
+      else
+       {
+         _FP_I_TYPE shift;
+         _FP_FRAC_CLZ_4(shift, X);
+         shift -= _FP_FRACXBITS_Q;
+         return X_e - _FP_EXPBIAS_Q - 1 + shift;
+       }
+#else
+      if (_FP_FRAC_ZEROP_2(X))
+       return FP_ILOGB0;
+      else
+       {
+         _FP_I_TYPE shift;
+         _FP_FRAC_CLZ_2(shift, X);
+         shift -= _FP_FRACXBITS_Q;
+         return X_e - _FP_EXPBIAS_Q - 1 + shift;
+       }
+#endif
+    case _FP_EXPBIAS_Q:
+      return FP_ILOGBNAN;
+    }
+}
+
+weak_alias (__ilogbl, ilogbl)
diff --git a/soft-fp/sysdeps/sparc/sparc64/s_scalblnl.c b/soft-fp/sysdeps/sparc/sparc64/s_scalblnl.c
new file mode 100644 (file)
index 0000000..5568cfd
--- /dev/null
@@ -0,0 +1,55 @@
+/* Software floating-point emulation.
+   scalblnl(x, exp)
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/*
+ * scalblnl (long double x, long int n)
+ * scalblnl(x,n) returns x* 2**n  computed by  exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __scalblnl(long double arg, int exp)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long double r;
+
+  FP_UNPACK_Q(A, arg);
+  switch (A_c)
+    {
+    case FP_CLS_ZERO:
+      return arg;
+    case FP_CLS_NAN:
+    case FP_CLS_INF:
+      FP_HANDLE_EXCEPTIONS;
+      return arg;
+    }
+  A_e += exp;
+  FP_PACK_Q(r, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+weak_alias (__scalblnl, scalblnl)
diff --git a/soft-fp/sysdeps/sparc/sparc64/s_scalbnl.c b/soft-fp/sysdeps/sparc/sparc64/s_scalbnl.c
new file mode 100644 (file)
index 0000000..fb913fd
--- /dev/null
@@ -0,0 +1,55 @@
+/* Software floating-point emulation.
+   scalbnl(x, exp)
+   Copyright (C) 1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/*
+ * scalbnl (long double x, int n)
+ * scalbnl(x,n) returns x* 2**n  computed by  exponent
+ * manipulation rather than by actually performing an
+ * exponentiation or a multiplication.
+ */
+
+#include "soft-fp.h"
+#include "quad.h"
+
+long double __scalbnl(long double arg, int exp)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long double r;
+
+  FP_UNPACK_Q(A, arg);
+  switch (A_c)
+    {
+    case FP_CLS_ZERO:
+      return arg;
+    case FP_CLS_NAN:
+    case FP_CLS_INF:
+      FP_HANDLE_EXCEPTIONS;
+      return arg;
+    }
+  A_e += exp;
+  FP_PACK_Q(r, A);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
+
+weak_alias (__scalbnl, scalbnl)
diff --git a/soft-fp/sysdeps/sparc/sparc64/sfp-machine.h b/soft-fp/sysdeps/sparc/sparc64/sfp-machine.h
new file mode 100644 (file)
index 0000000..0d82c60
--- /dev/null
@@ -0,0 +1,143 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc64 userland (_Q_* and _Qp_*) version.
+   Copyright (C) 1997,1998,1999 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
+                 David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   
+#include <fpu_control.h>
+#include <fenv.h>
+
+#define _FP_W_TYPE_SIZE                64
+#define _FP_W_TYPE             unsigned long
+#define _FP_WS_TYPE            signed long
+#define _FP_I_TYPE             long
+
+/* Helper macros for _FP_MUL_MEAT_2_120_240_double.  */
+#define _FP_MUL_MEAT_SET_FE_TZ                                 \
+do {                                                           \
+  static fpu_control_t _fetz = _FPU_RC_DOWN;                   \
+  _FPU_SETCW(_fetz);                                           \
+} while (0)
+#ifndef _FP_MUL_MEAT_RESET_FE
+#define _FP_MUL_MEAT_RESET_FE _FPU_SETCW(_fcw)
+#endif
+      
+#define _FP_MUL_MEAT_S(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)                                  \
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)                                  \
+  _FP_MUL_MEAT_2_120_240_double(_FP_WFRACBITS_Q,R,X,Y,         \
+                               _FP_MUL_MEAT_SET_FE_TZ,         \
+                               _FP_MUL_MEAT_RESET_FE)
+
+#define _FP_DIV_MEAT_S(R,X,Y)  _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)  _FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)  _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S          ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D          ((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q          ((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S          0
+#define _FP_NANSIGN_D          0
+#define _FP_NANSIGN_Q          0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose Y.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                     \
+  do {                                                         \
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)         \
+       && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))     \
+      {                                                                \
+       R##_s = X##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,X);                                \
+      }                                                                \
+    else                                                       \
+      {                                                                \
+       R##_s = Y##_s;                                          \
+       _FP_FRAC_COPY_##wc(R,Y);                                \
+      }                                                                \
+    R##_c = FP_CLS_NAN;                                                \
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE   ((_fcw >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID          (1 << 4)
+#define FP_EX_OVERFLOW         (1 << 3)
+#define FP_EX_UNDERFLOW                (1 << 2)
+#define FP_EX_DIVZERO          (1 << 1)
+#define FP_EX_INEXACT          (1 << 0)
+
+#define _FP_DECL_EX    fpu_control_t _fcw
+
+#define FP_INIT_ROUNDMODE                                      \
+do {                                                           \
+  _FPU_GETCW(_fcw);                                            \
+} while (0)
+
+#define FP_INHIBIT_RESULTS ((_fcw >> 23) & _fex)
+
+/* Simulate exceptions using double arithmetics. */
+extern double __Qp_handle_exceptions(int exc);
+
+#define FP_HANDLE_EXCEPTIONS                                   \
+do {                                                           \
+  if (!_fex)                                                   \
+    {                                                          \
+      /* This is the common case, so we do it inline.          \
+       * We need to clear cexc bits if any.                    \
+       */                                                      \
+      __asm__ __volatile__("
+       fzero %%f62
+       faddd %%f62, %%f62, %%f62
+       " : : : "f62");                                         \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      __Qp_handle_exceptions (_fex);                           \
+    }                                                          \
+} while (0)
+
+#define QP_HANDLE_EXCEPTIONS(_a)                               \
+do {                                                           \
+  if ((_fcw >> 23) & _fex)                                     \
+    {                                                          \
+      _a;                                                      \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      _fcw = (_fcw & ~0x1fL) | (_fex << 5) | _fex;             \
+      _FPU_SETCW(_fcw);                                                \
+    }                                                          \
+} while (0)
+
+#define QP_NO_EXCEPTIONS                                       \
+  __asm ("fzero %%f62
+         faddd %%f62, %%f62, %%f62" : : : "f62")
+                              
+#define QP_CLOBBER "memory", "f52", "f54", "f56", "f58", "f60", "f62"
+#define QP_CLOBBER_CC QP_CLOBBER , "cc"
diff --git a/soft-fp/testit.c b/soft-fp/testit.c
new file mode 100644 (file)
index 0000000..46a50c4
--- /dev/null
@@ -0,0 +1,788 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+#include <fpu_control.h>
+
+/*======================================================================*/
+/* declarations for the functions we are testing */
+
+double __adddf3(double, double);
+double __subdf3(double, double);
+double __muldf3(double, double);
+double __divdf3(double, double);
+double __negdf2(double);
+double __sqrtdf2(double);
+double __negdf3(double a, double dummy) { return __negdf2(a); }
+double __sqrtdf3(double a, double dummy) { return __sqrtdf2(a); }
+
+float __addsf3(float, float);
+float __subsf3(float, float);
+float __mulsf3(float, float);
+float __divsf3(float, float);
+float __negsf2(float);
+float __sqrtsf2(float);
+float __negsf3(float a, float dummy) { return __negsf2(a); }
+float __sqrtsf3(float a, float dummy) { return __sqrtsf2(a); }
+
+int __fixdfsi(double);
+int __fixsfsi(float);
+double __floatsidf(int);
+float __floatsisf(int);
+double __extendsfdf2(float);
+float __truncdfsf2(double);
+
+int __eqdf2(double, double);
+int __nedf2(double, double);
+int __gtdf2(double, double);
+int __gedf2(double, double);
+int __ltdf2(double, double);
+int __ledf2(double, double);
+
+int __eqsf2(float, float);
+int __nesf2(float, float);
+int __gtsf2(float, float);
+int __gesf2(float, float);
+int __ltsf2(float, float);
+int __lesf2(float, float);
+
+/*======================================================================*/
+/* definitions for functions we are checking against */
+
+double r_adddf3(double a, double b) { return a + b; }
+double r_subdf3(double a, double b) { return a - b; }
+double r_muldf3(double a, double b) { return a * b; }
+double r_divdf3(double a, double b) { return a / b; }
+double r_negdf3(double a, double b) { return -a; }
+double sqrt(double x);
+double r_sqrtdf3(double a, double b) { return sqrt(a); }
+
+float r_addsf3(float a, float b) { return a + b; }
+float r_subsf3(float a, float b) { return a - b; }
+float r_mulsf3(float a, float b) { return a * b; }
+float r_divsf3(float a, float b) { return a / b; }
+float r_negsf3(float a, float b) { return -a; }
+float sqrtf(float x);
+float r_sqrtsf3(float a, float b) { return sqrtf(a); }
+
+int r_fixdfsi(double a) { return (int)a; }
+int r_fixsfsi(float a) { return (int)a; }
+double r_floatsidf(int a) { return (double)a; }
+float r_floatsisf(int a) { return (float)a; }
+double r_extendsfdf2(float a) { return (double)a; }
+float r_truncdfsf2(double a) { return (float)a; }
+
+int r_eqdf2(double a, double b) { return !(a == b); }
+int r_nedf2(double a, double b) { return a != b; }
+int r_gtdf2(double a, double b) { return a > b; }
+int r_gedf2(double a, double b) { return (a >= b) - 1; }
+int r_ltdf2(double a, double b) { return -(a < b); }
+int r_ledf2(double a, double b) { return 1 - (a <= b); }
+
+int r_eqsf2(float a, float b) { return !(a == b); }
+int r_nesf2(float a, float b) { return a != b; }
+int r_gtsf2(float a, float b) { return a > b; }
+int r_gesf2(float a, float b) { return (a >= b) - 1; }
+int r_ltsf2(float a, float b) { return -(a < b); }
+int r_lesf2(float a, float b) { return 1 - (a <= b); }
+
+/*======================================================================*/
+
+void print_float(float x)
+{
+    union _FP_UNION_S ux;
+    ux.flt = x;
+    printf("%-20.8e %X %02X %06lX",
+          x, ux.bits.sign, ux.bits.exp, (unsigned long)ux.bits.frac);
+}
+
+void print_double(double x)
+{
+    union _FP_UNION_D ux;
+    ux.flt = x;
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+    printf("%-30.18e %X %04X %06lX%08lX",
+          x, ux.bits.sign, ux.bits.exp,
+          (unsigned long)ux.bits.frac1, (unsigned long)ux.bits.frac0);
+#else
+    printf("%-30.18e %X %04X %014lX",
+          x, ux.bits.sign, ux.bits.exp,
+          (unsigned long)ux.bits.frac);
+#endif
+}
+
+float rand_float(void)
+{
+    union {
+       union _FP_UNION_S u;
+       int i;
+    } u;
+
+    u.i = lrand48() << 1;
+
+    if (u.u.bits.exp == _FP_EXPMAX_S)
+       u.u.bits.exp--;
+    else if (u.u.bits.exp == 0 && u.u.bits.frac != 0)
+       u.u.bits.exp++;
+
+    return u.u.flt;
+}
+
+
+double rand_double(void)
+{
+    union {
+       union _FP_UNION_D u;
+       int i[2];
+    } u;
+
+    u.i[0] = lrand48() << 1;
+    u.i[1] = lrand48() << 1;
+
+    if (u.u.bits.exp == _FP_EXPMAX_D)
+       u.u.bits.exp--;
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+    else if (u.u.bits.exp == 0 && !(u.u.bits.frac0 == 0 && u.u.bits.frac1 == 0))
+       u.u.bits.exp++;
+#else
+    else if (u.u.bits.exp == 0 && u.u.bits.frac != 0)
+       u.u.bits.exp++;
+#endif
+
+    return u.u.flt;
+}
+
+#define NSPECIALS  10
+
+float gen_special_float(int i)
+{
+    FP_DECL_EX;
+    FP_DECL_S(X);
+    float x;
+
+    switch (i & ~1)
+    {
+      case 0:
+       X_c = FP_CLS_NAN; X_f = 0x1234;
+       break;
+      case 2:
+       X_c = FP_CLS_NAN; X_f = 0x1;
+       break;
+      case 4:
+       X_c = FP_CLS_INF;
+       break;
+      case 6:
+       X_c = FP_CLS_ZERO;
+       break;
+      case 8:
+       X_c = FP_CLS_NORMAL; X_e = 0;
+       X_f = 0x4321;
+       break;
+    }
+    X_s = (i & 1);
+
+    FP_PACK_S(x, X);
+    return x;
+}
+
+double gen_special_double(int i)
+{
+    FP_DECL_EX;
+    FP_DECL_D(X);
+    double x;
+
+    switch (i & ~1)
+    {
+      case 0:
+       X_c = FP_CLS_NAN;
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+       __FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1234);
+#else
+       _FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1234);
+#endif
+       break;
+      case 2:
+       X_c = FP_CLS_NAN;
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+       __FP_FRAC_SET_2(X, _FP_QNANBIT_D, 0x1);
+#else
+       _FP_FRAC_SET_1(X, _FP_QNANBIT_D | 0x1);
+#endif
+       break;
+      case 4:
+       X_c = FP_CLS_INF;
+       break;
+      case 6:
+       X_c = FP_CLS_ZERO;
+       break;
+      case 8:
+       X_c = FP_CLS_NORMAL; X_e = 0;
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+       __FP_FRAC_SET_2(X, 0, 0x87654321);
+#else
+       _FP_FRAC_SET_1(X, 0x87654321);
+#endif
+       break;
+    }
+    X_s = (i & 1);
+
+    FP_PACK_D(x, X);
+    return x;
+}
+
+float build_float(const char *s, const char *e, const char *f)
+{
+    union _FP_UNION_S u;
+
+    u.bits.sign = strtoul(s, 0, 16);
+    u.bits.exp = strtoul(e, 0, 16);
+    u.bits.frac = strtoul(f, 0, 16);
+
+    return u.flt;
+}
+      
+double build_double(const char *s, const char *e, const char *f)
+{
+    union _FP_UNION_D u;
+
+    u.bits.sign = strtoul(s, 0, 16);
+    u.bits.exp = strtoul(e, 0, 16);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+    {
+       size_t len = strlen(f)+1;
+       char *dup = memcpy(alloca(len), f, len);
+       char *low = dup + len - _FP_W_TYPE_SIZE/4 - 1;
+
+       u.bits.frac0 = strtoul(low, 0, 16);
+       *low = 0;
+       u.bits.frac1 = strtoul(dup, 0, 16);
+    }
+#else
+    u.bits.frac = strtoul(f, 0, 16);
+#endif
+       
+    return u.flt;
+}
+      
+/*======================================================================*/
+
+fpu_control_t fcw0, fcw1;
+
+void test_float_arith(float (*tf)(float, float),
+                     float (*rf)(float, float),
+                     float x, float y)
+{
+    float tr, rr;
+    rr = (*rf)(x, y);
+    tr = (*tf)(x, y);
+    if (memcmp(&tr, &rr, sizeof(float)) != 0)
+    {
+       fputs("error:\n\tx     = ", stdout); print_float(x);
+       fputs("\n\ty     = ", stdout); print_float(y);
+       fputs("\n\ttrue  = ", stdout); print_float(rr);
+       fputs("\n\tfalse = ", stdout); print_float(tr);
+       putchar('\n');
+    }
+}
+
+void test_double_arith(double (*tf)(double, double),
+                      double (*rf)(double, double),
+                      double x, double y)
+{
+    double tr, rr;
+#ifdef __i386__
+    /* Don't worry.  Even this does not make it error free
+       on ia32.  If the result is denormal,  it will not
+       honour the double precision and generate bad results
+       anyway.  On the other side,  who wants to use ia32
+       for IEEE math?  I don't.  */
+    _FPU_GETCW(fcw0);
+    fcw1 = ((fcw0 & ~_FPU_EXTENDED) | _FPU_DOUBLE);
+    _FPU_SETCW(fcw1);
+#endif    
+    rr = (*rf)(x, y);
+#ifdef __i386__
+    _FPU_SETCW(fcw0);
+#endif
+    tr = (*tf)(x, y);
+    if (memcmp(&tr, &rr, sizeof(double)) != 0)
+    {
+       fputs("error:\n\tx     = ", stdout); print_double(x);
+       fputs("\n\ty     = ", stdout); print_double(y);
+       fputs("\n\ttrue  = ", stdout); print_double(rr);
+       fputs("\n\tfalse = ", stdout); print_double(tr);
+       putchar('\n');
+    }
+}
+
+void test_float_double_conv(float x)
+{
+    double tr, rr;
+    rr = r_extendsfdf2(x);
+    tr = __extendsfdf2(x);
+    if (memcmp(&tr, &rr, sizeof(double)) != 0)
+    {
+       fputs("error:\n\tx     = ", stdout); print_float(x);
+       fputs("\n\ttrue  = ", stdout); print_double(rr);
+       fputs("\n\tfalse = ", stdout); print_double(tr);
+       putchar('\n');
+    }
+}
+
+void test_double_float_conv(double x)
+{
+    float tr, rr;
+    rr = r_truncdfsf2(x);
+    tr = __truncdfsf2(x);
+    if (memcmp(&tr, &rr, sizeof(float)) != 0)
+    {
+       fputs("error:\n\tx     = ", stdout); print_double(x);
+       fputs("\n\ttrue  = ", stdout); print_float(rr);
+       fputs("\n\tfalse = ", stdout); print_float(tr);
+       putchar('\n');
+    }
+}
+
+void test_int_float_conv(int x)
+{
+    float tr, rr;
+    rr = r_floatsisf(x);
+    tr = __floatsisf(x);
+    if (memcmp(&tr, &rr, sizeof(float)) != 0)
+    {
+       printf("error\n\tx     = %d", x);
+       fputs("\n\ttrue  = ", stdout); print_float(rr);
+       fputs("\n\tfalse = ", stdout); print_float(tr);
+       putchar('\n');
+    }
+}
+
+void test_int_double_conv(int x)
+{
+    double tr, rr;
+    rr = r_floatsidf(x);
+    tr = __floatsidf(x);
+    if (memcmp(&tr, &rr, sizeof(double)) != 0)
+    {
+       printf("error\n\tx     = %d", x);
+       fputs("\n\ttrue  = ", stdout); print_double(rr);
+       fputs("\n\tfalse = ", stdout); print_double(tr);
+       putchar('\n');
+    }
+}
+
+void test_float_int_conv(float x)
+{
+    int tr, rr;
+    rr = r_fixsfsi(x);
+    tr = __fixsfsi(x);
+    if (rr != tr)
+    {
+       fputs("error:\n\tx     = ", stdout); print_float(x);
+       printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
+    }
+}
+       
+void test_double_int_conv(double x)
+{
+    int tr, rr;
+    rr = r_fixsfsi(x);
+    tr = __fixsfsi(x);
+    if (rr != tr)
+    {
+       fputs("error:\n\tx     = ", stdout); print_double(x);
+       printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
+    }
+}
+
+int eq0(int x) { return x == 0; }
+int ne0(int x) { return x != 0; }
+int le0(int x) { return x <= 0; }
+int lt0(int x) { return x < 0; }
+int ge0(int x) { return x >= 0; }
+int gt0(int x) { return x > 0; }
+
+void test_float_cmp(int (*tf)(float, float),
+                   int (*rf)(float, float),
+                   int (*cmp0)(int),
+                   float x, float y)
+{
+    int tr, rr;
+    rr = (*rf)(x, y);
+    tr = (*tf)(x, y);
+    if (cmp0(rr) != cmp0(tr))
+    {
+       fputs("error:\n\tx     = ", stdout); print_float(x);
+       fputs("\n\ty     = ", stdout); print_float(y);
+       printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
+    }
+}
+
+void test_double_cmp(int (*tf)(double, double),
+                    int (*rf)(double, double),
+                    int (*cmp0)(int),
+                    double x, double y)
+{
+    int tr, rr;
+    rr = (*rf)(x, y);
+    tr = (*tf)(x, y);
+    if (cmp0(rr) != cmp0(tr))
+    {
+       fputs("error:\n\tx     = ", stdout); print_double(x);
+       fputs("\n\ty     = ", stdout); print_double(y);
+       printf("\n\ttrue  = %d\n\tfalse = %d\n", rr, tr);
+    }
+}
+
+
+/*======================================================================*/
+
+
+int main(int ac, char **av)
+{
+#ifdef __alpha__
+    __ieee_set_fp_control(0);
+#endif
+    av++, ac--;
+    switch (*(*av)++)
+    {
+       {
+           float (*r)(float, float);
+           float (*t)(float, float);
+
+           do {
+             case 'a': r = r_addsf3; t = __addsf3; break;
+             case 's': r = r_subsf3; t = __subsf3; break;
+             case 'm': r = r_mulsf3; t = __mulsf3; break;
+             case 'd': r = r_divsf3; t = __divsf3; break;
+             case 'r': r = r_sqrtsf3; t = __sqrtsf3; break;
+             case 'j': r = r_negsf3; t = __negsf3; break;
+           } while (0);
+
+           switch (*(*av)++)
+           {
+             case 'n':
+               {
+                   int count = (ac > 1 ? atoi(av[1]) : 100);
+                   while (count--)
+                       test_float_arith(t, r, rand_float(), rand_float());
+               }
+               break;
+
+             case 's':
+               {
+                   int i, j;
+                   for (i = 0; i < NSPECIALS; i++)
+                       for (j = 0; j < NSPECIALS; j++)
+                           test_float_arith(t, r, gen_special_float(i),
+                                             gen_special_float(j));
+               }
+               break;
+
+             case 0:
+               if (ac < 7) abort();
+               test_float_arith(t, r, build_float(av[1], av[2], av[3]),
+                                build_float(av[4], av[5], av[6]));
+               break;
+           }
+       }
+       break;
+
+       {
+           double (*r)(double, double);
+           double (*t)(double, double);
+
+           do {
+             case 'A': r = r_adddf3; t = __adddf3; break;
+             case 'S': r = r_subdf3; t = __subdf3; break;
+             case 'M': r = r_muldf3; t = __muldf3; break;
+             case 'D': r = r_divdf3; t = __divdf3; break;
+             case 'R': r = r_sqrtdf3; t = __sqrtdf3; break;
+             case 'J': r = r_negdf3; t = __negdf3; break;
+           } while (0);
+
+           switch (*(*av)++)
+           {
+             case 'n':
+               {
+                   int count = (ac > 1 ? atoi(av[1]) : 100);
+                   while (count--)
+                       test_double_arith(t, r, rand_double(), rand_double());
+               }
+               break;
+
+             case 's':
+               {
+                   int i, j;
+                   for (i = 0; i < NSPECIALS; i++)
+                       for (j = 0; j < NSPECIALS; j++)
+                           test_double_arith(t, r, gen_special_double(i),
+                                             gen_special_double(j));
+               }
+               break;
+
+             case 0:
+               if (ac < 7) abort();
+               test_double_arith(t, r, build_double(av[1], av[2], av[3]),
+                                 build_double(av[4], av[5], av[6]));
+               break;
+           }
+       }
+       break;
+
+      case 'c':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_float_double_conv(rand_float());
+           }
+           break;
+
+         case 's':
+           {
+               int i;
+               for (i = 0; i < NSPECIALS; i++)
+                   test_float_double_conv(gen_special_float(i));
+           }
+           break;
+
+         case 0:
+           if (ac < 4) abort();
+           test_float_double_conv(build_float(av[1], av[2], av[3]));
+           break;
+       }
+       break;
+
+      case 'C':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_double_float_conv(rand_double());
+           }
+           break;
+
+         case 's':
+           {
+               int i;
+               for (i = 0; i < NSPECIALS; i++)
+                   test_double_float_conv(gen_special_double(i));
+           }
+           break;
+
+         case 0:
+           if (ac < 4) abort();
+           test_double_float_conv(build_double(av[1], av[2], av[3]));
+           break;
+       }
+       break;
+
+      case 'i':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_int_float_conv(lrand48() << 1);
+           }
+           break;
+
+         case 0:
+           if (ac < 2) abort();
+           test_int_float_conv(strtol(av[1], 0, 0));
+           break;
+       }
+       break;
+
+      case 'I':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_int_double_conv(lrand48() << 1);
+           }
+           break;
+
+         case 0:
+           if (ac < 2) abort();
+           test_int_double_conv(strtol(av[1], 0, 0));
+           break;
+       }
+       break;
+
+      case 'f':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_float_int_conv(rand_float());
+           }
+           break;
+
+         case 's':
+           {
+               int i;
+               for (i = 0; i < NSPECIALS; i++)
+                   test_float_int_conv(gen_special_float(i));
+           }
+           break;
+
+         case 0:
+           if (ac < 4) abort();
+           test_float_int_conv(build_float(av[1], av[2], av[3]));
+           break;
+       }
+       break;
+
+      case 'F':
+       switch (*(*av)++)
+       {
+         case 'n':
+           {
+               int count = (ac > 1 ? atoi(av[1]) : 100);
+               while (count--)
+                   test_double_int_conv(rand_double());
+           }
+           break;
+
+         case 's':
+           {
+               int i;
+               for (i = 0; i < NSPECIALS; i++)
+                   test_double_int_conv(gen_special_double(i));
+           }
+           break;
+
+         case 0:
+           if (ac < 4) abort();
+           test_double_int_conv(build_double(av[1], av[2], av[3]));
+           break;
+       }
+       break;
+
+       {
+           int (*r)(float, float);
+           int (*t)(float, float);
+           int (*c)(int);
+
+           do {
+             case 'e': r = r_eqsf2; t = __eqsf2; c = eq0; break;
+             case 'n': r = r_nesf2; t = __nesf2; c = ne0; break;
+             case 'l':
+               switch (*(*av)++)
+               {
+                 case 'e': r = r_lesf2; t = __lesf2; c = le0; break;
+                 case 't': r = r_ltsf2; t = __ltsf2; c = lt0; break;
+               }
+               break;
+             case 'g':
+               switch (*(*av)++)
+               {
+                 case 'e': r = r_gesf2; t = __gesf2; c = ge0; break;
+                 case 't': r = r_gtsf2; t = __gtsf2; c = gt0; break;
+               }
+               break;
+           } while (0);
+
+           switch (*(*av)++)
+           {
+             case 'n':
+               {
+                   int count = (ac > 1 ? atoi(av[1]) : 100);
+                   while (count--)
+                       test_float_cmp(t, r, c, rand_float(), rand_float());
+               }
+               break;
+
+             case 's':
+               {
+                   int i, j;
+                   for (i = 0; i < NSPECIALS; i++)
+                       for (j = 0; j < NSPECIALS; j++)
+                           test_float_cmp(t, r, c, gen_special_float(i),
+                                          gen_special_float(j));
+               }
+               break;
+
+             case 0:
+               if (ac < 7) abort();
+               test_float_cmp(t, r, c, build_float(av[1], av[2], av[3]),
+                               build_float(av[4], av[5], av[6]));
+               break;
+           }
+       }
+       break;
+
+       {
+           int (*r)(double, double);
+           int (*t)(double, double);
+           int (*c)(int);
+
+           do {
+             case 'E': r = r_eqdf2; t = __eqdf2; c = eq0; break;
+             case 'N': r = r_nedf2; t = __nedf2; c = ne0; break;
+             case 'L':
+               switch (*(*av)++)
+               {
+                 case 'E': r = r_ledf2; t = __ledf2; c = le0; break;
+                 case 'T': r = r_ltdf2; t = __ltdf2; c = lt0; break;
+               }
+               break;
+             case 'G':
+               switch (*(*av)++)
+               {
+                 case 'E': r = r_gedf2; t = __gedf2; c = ge0; break;
+                 case 'T': r = r_gtdf2; t = __gtdf2; c = gt0; break;
+               }
+               break;
+           } while (0);
+
+           switch (*(*av)++)
+           {
+             case 'n':
+               {
+                   int count = (ac > 1 ? atoi(av[1]) : 100);
+                   while (count--)
+                       test_double_cmp(t, r, c, rand_double(), rand_double());
+               }
+               break;
+
+             case 's':
+               {
+                   int i, j;
+                   for (i = 0; i < NSPECIALS; i++)
+                       for (j = 0; j < NSPECIALS; j++)
+                           test_double_cmp(t, r, c, gen_special_double(i),
+                                           gen_special_double(j));
+               }
+               break;
+
+             case 0:
+               if (ac < 7) abort();
+               test_double_cmp(t, r, c, build_double(av[1], av[2], av[3]),
+                               build_double(av[4], av[5], av[6]));
+               break;
+           }
+       }
+       break;
+
+      default:
+       abort();
+    }
+
+    return 0;
+}
diff --git a/soft-fp/truncdfsf2.c b/soft-fp/truncdfsf2.c
new file mode 100644 (file)
index 0000000..a97baca
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Truncate IEEE double into IEEE single
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "double.h"
+
+float __truncdfsf2(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_D(A, a);
+#if _FP_W_TYPE_SIZE < _FP_FRACBITS_D
+  FP_CONV(S,D,1,2,R,A);
+#else
+  FP_CONV(S,D,1,1,R,A);
+#endif
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/trunctfdf2.c b/soft-fp/trunctfdf2.c
new file mode 100644 (file)
index 0000000..85fd241
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Truncate IEEE quad into IEEE double
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "double.h"
+#include "quad.h"
+
+double __trunctfdf2(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_D(R);
+  double r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(D,Q,2,4,R,A);
+#else
+  FP_CONV(D,Q,1,2,R,A);
+#endif
+  FP_PACK_D(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/soft-fp/trunctfsf2.c b/soft-fp/trunctfsf2.c
new file mode 100644 (file)
index 0000000..8a18b85
--- /dev/null
@@ -0,0 +1,45 @@
+/* Software floating-point emulation.
+   Truncate IEEE quad into IEEE single
+   Copyright (C) 1997,1999 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "soft-fp.h"
+#include "single.h"
+#include "quad.h"
+
+float __trunctfsf2(long double a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  FP_DECL_S(R);
+  float r;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+#if (2 * _FP_W_TYPE_SIZE) < _FP_FRACBITS_Q
+  FP_CONV(S,Q,1,4,R,A);
+#else
+  FP_CONV(S,Q,1,2,R,A);
+#endif
+  FP_PACK_S(r, R);
+  FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}