summary refs log tree commit diff
path: root/sysdeps/alpha
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-03-06 20:46:23 +0000
committerRichard Henderson <rth@redhat.com>2004-03-06 20:46:23 +0000
commita598e3fc041f38d0c43be55d1664ff7ed0cf405b (patch)
treeda22cbd1cae0cff761823248c1350f7d6ec32177 /sysdeps/alpha
parent4df8c11d26a29bc3a6116a9125cdfdca3cd517bb (diff)
downloadglibc-a598e3fc041f38d0c43be55d1664ff7ed0cf405b.tar.gz
glibc-a598e3fc041f38d0c43be55d1664ff7ed0cf405b.tar.xz
glibc-a598e3fc041f38d0c43be55d1664ff7ed0cf405b.zip
* soft-fp/quad.h (union _FP_UNION_Q): Add longs structure. * sysdeps/alpha/Implies: Add alpha/soft-fp. * sysdeps/alpha/soft-fp/sfp-machine.h: Rewrite for GEM interface. * sysdeps/alpha/Subdirs, sysdeps/alpha/soft-fp/Makefile, sysdeps/alpha/soft-fp/Versions, sysdeps/alpha/soft-fp/local-soft-fp.h, sysdeps/alpha/soft-fp/ots_add.c, sysdeps/alpha/soft-fp/ots_cmp.c, sysdeps/alpha/soft-fp/ots_cmpe.c, sysdeps/alpha/soft-fp/ots_cvtqux.c, sysdeps/alpha/soft-fp/ots_cvtqx.c, sysdeps/alpha/soft-fp/ots_cvttx.c, sysdeps/alpha/soft-fp/ots_cvtxq.c, sysdeps/alpha/soft-fp/ots_cvtxt.c, sysdeps/alpha/soft-fp/ots_div.c, sysdeps/alpha/soft-fp/ots_mul.c, sysdeps/alpha/soft-fp/ots_nintxq.c, sysdeps/alpha/soft-fp/ots_sub.c: New files.
2004-03-06  Richard Henderson  <rth@redhat.com>

	* soft-fp/quad.h (union _FP_UNION_Q): Add longs structure.
	* sysdeps/alpha/Implies: Add alpha/soft-fp.
	* sysdeps/alpha/soft-fp/sfp-machine.h: Rewrite for GEM interface.
	* sysdeps/alpha/Subdirs, sysdeps/alpha/soft-fp/Makefile,
	sysdeps/alpha/soft-fp/Versions, sysdeps/alpha/soft-fp/local-soft-fp.h,
	sysdeps/alpha/soft-fp/ots_add.c, sysdeps/alpha/soft-fp/ots_cmp.c,
	sysdeps/alpha/soft-fp/ots_cmpe.c, sysdeps/alpha/soft-fp/ots_cvtqux.c,
	sysdeps/alpha/soft-fp/ots_cvtqx.c, sysdeps/alpha/soft-fp/ots_cvttx.c,
	sysdeps/alpha/soft-fp/ots_cvtxq.c, sysdeps/alpha/soft-fp/ots_cvtxt.c,
	sysdeps/alpha/soft-fp/ots_div.c, sysdeps/alpha/soft-fp/ots_mul.c,
	sysdeps/alpha/soft-fp/ots_nintxq.c, sysdeps/alpha/soft-fp/ots_sub.c:
	New files.
Diffstat (limited to 'sysdeps/alpha')
-rw-r--r--sysdeps/alpha/Implies1
-rw-r--r--sysdeps/alpha/Subdirs1
-rw-r--r--sysdeps/alpha/soft-fp/Dist13
-rw-r--r--sysdeps/alpha/soft-fp/Makefile6
-rw-r--r--sysdeps/alpha/soft-fp/Versions8
-rw-r--r--sysdeps/alpha/soft-fp/local-soft-fp.h44
-rw-r--r--sysdeps/alpha/soft-fp/ots_add.c39
-rw-r--r--sysdeps/alpha/soft-fp/ots_cmp.c64
-rw-r--r--sysdeps/alpha/soft-fp/ots_cmpe.c83
-rw-r--r--sysdeps/alpha/soft-fp/ots_cvtqux.c40
-rw-r--r--sysdeps/alpha/soft-fp/ots_cvtqx.c39
-rw-r--r--sysdeps/alpha/soft-fp/ots_cvttx.c48
-rw-r--r--sysdeps/alpha/soft-fp/ots_cvtxq.c43
-rw-r--r--sysdeps/alpha/soft-fp/ots_cvtxt.c44
-rw-r--r--sysdeps/alpha/soft-fp/ots_div.c39
-rw-r--r--sysdeps/alpha/soft-fp/ots_mul.c39
-rw-r--r--sysdeps/alpha/soft-fp/ots_nintxq.c50
-rw-r--r--sysdeps/alpha/soft-fp/ots_sub.c39
-rw-r--r--sysdeps/alpha/soft-fp/sfp-machine.h97
19 files changed, 718 insertions, 19 deletions
diff --git a/sysdeps/alpha/Implies b/sysdeps/alpha/Implies
index 2c6af5b7bb..4b354f3e47 100644
--- a/sysdeps/alpha/Implies
+++ b/sysdeps/alpha/Implies
@@ -2,3 +2,4 @@ wordsize-64
 # Alpha uses IEEE 754 single and double precision floating point.
 ieee754/flt-32
 ieee754/dbl-64
+alpha/soft-fp
diff --git a/sysdeps/alpha/Subdirs b/sysdeps/alpha/Subdirs
new file mode 100644
index 0000000000..87eadf3024
--- /dev/null
+++ b/sysdeps/alpha/Subdirs
@@ -0,0 +1 @@
+soft-fp
diff --git a/sysdeps/alpha/soft-fp/Dist b/sysdeps/alpha/soft-fp/Dist
index 7e9914fe58..3d75ee78b5 100644
--- a/sysdeps/alpha/soft-fp/Dist
+++ b/sysdeps/alpha/soft-fp/Dist
@@ -1 +1,14 @@
+local-soft-fp.h
+ots_add.c
+ots_cmp.c
+ots_cmpe.c
+ots_cvtqux.c
+ots_cvtqx.c
+ots_cvttx.c
+ots_cvtxq.c
+ots_cvtxt.c
+ots_div.c
+ots_mul.c
+ots_nintxq.c
+ots_sub.c
 sfp-machine.h
diff --git a/sysdeps/alpha/soft-fp/Makefile b/sysdeps/alpha/soft-fp/Makefile
new file mode 100644
index 0000000000..d7e7e2684a
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/Makefile
@@ -0,0 +1,6 @@
+#  Software floating-point emulation.
+
+ifeq ($(subdir),soft-fp)
+sysdep_routines += ots_add ots_sub ots_mul ots_div ots_cmp ots_cmpe	\
+	ots_cvtxq ots_cvtqx ots_cvtqux ots_cvttx ots_cvtxt ots_nintxq
+endif
diff --git a/sysdeps/alpha/soft-fp/Versions b/sysdeps/alpha/soft-fp/Versions
new file mode 100644
index 0000000000..3901287115
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/Versions
@@ -0,0 +1,8 @@
+libc {
+  GLIBC_2.3.4 {
+    _OtsAddX; _OtsSubX; _OtsMulX; _OtsDivX;
+    _OtsEqlX; _OtsNeqX; _OtsLssX; _OtsLeqX; _OtsGtrX; _OtsGeqX;
+    _OtsCvtQX; _OtsCvtQUX; _OtsCvtXQ; _OtsNintXQ;
+    _OtsConvertFloatTX; _OtsConvertFloatXT;
+  }
+}
diff --git a/sysdeps/alpha/soft-fp/local-soft-fp.h b/sysdeps/alpha/soft-fp/local-soft-fp.h
new file mode 100644
index 0000000000..e93a2ad064
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/local-soft-fp.h
@@ -0,0 +1,44 @@
+#include <stdlib.h>
+#include <soft-fp.h>
+#include <quad.h>
+
+/* Helpers for the Ots functions which receive long double arguments
+   in two integer registers, and return values in $16+$17.  */
+
+#undef _FP_UNPACK_RAW_2
+#define _FP_UNPACK_RAW_2(fs, X, val)                    \
+  do {                                                  \
+    union _FP_UNION_##fs _flo;				\
+    _flo.longs.a = val##l;				\
+    _flo.longs.b = val##h;				\
+    X##_f0 = _flo.bits.frac0;				\
+    X##_f1 = _flo.bits.frac1;				\
+    X##_e  = _flo.bits.exp;				\
+    X##_s  = _flo.bits.sign;				\
+  } while (0)
+
+#undef _FP_PACK_RAW_2
+#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##l = _flo.longs.a;				\
+    val##h = _flo.longs.b;				\
+  } while (0)
+
+#define FP_DECL_RETURN(X) \
+  long X##l, X##h
+
+/* ??? We don't have a real way to tell the compiler that we're wanting
+   to return values in $16+$17.  Instead use a volatile asm to make sure
+   that the values are live, and just hope that nothing kills the values
+   in between here and the end of the function.  */
+#define FP_RETURN(X)				\
+do {						\
+  register long r16 __asm__("16") = X##l;	\
+  register long r17 __asm__("17") = X##h;	\
+  asm volatile ("" : : "r"(r16), "r"(r17));	\
+} while (0)
diff --git a/sysdeps/alpha/soft-fp/ots_add.c b/sysdeps/alpha/soft-fp/ots_add.c
new file mode 100644
index 0000000000..b4f6c28f3d
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_add.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: addition.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+void
+_OtsAddX(long al, long ah, long bl, long bh, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  FP_DECL_RETURN(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;
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cmp.c b/sysdeps/alpha/soft-fp/ots_cmp.c
new file mode 100644
index 0000000000..c356b4848e
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cmp.c
@@ -0,0 +1,64 @@
+/* Software floating-point emulation: comparison.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+static long
+internal_equality (long al, long ah, long bl, long bh, long neq)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  long r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+
+  if ((A_e == _FP_EXPMAX_Q && !_FP_FRAC_ZEROP_2(A))
+       || (B_e == _FP_EXPMAX_Q && !_FP_FRAC_ZEROP_2(B)))
+    {
+      /* EQ and NE signal invalid operation only if either operand is SNaN.  */
+      if (FP_ISSIGNAN_Q(A) || FP_ISSIGNAN_Q(B))
+	{
+	  FP_SET_EXCEPTION(FP_EX_INVALID);
+	  FP_HANDLE_EXCEPTIONS;
+	}
+      return -1;
+    }
+
+  r = (A_e == B_e
+       && _FP_FRAC_EQ_2 (A, B)
+       && (A_s == B_s || (!A_e && _FP_FRAC_ZEROP_2(A))));
+  r ^= neq;
+
+  return r;
+}
+
+long
+_OtsEqlX (long al, long ah, long bl, long bh)
+{
+  return internal_equality (al, ah, bl, bh, 0);
+}
+
+long
+_OtsNeqX (long al, long ah, long bl, long bh)
+{
+  return internal_equality (al, ah, bl, bh, 1);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cmpe.c b/sysdeps/alpha/soft-fp/ots_cmpe.c
new file mode 100644
index 0000000000..001eb75a9b
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cmpe.c
@@ -0,0 +1,83 @@
+/* Software floating-point emulation: comparison.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+static long
+internal_compare (long al, long ah, long bl, long bh)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B);
+  long r;
+
+  FP_UNPACK_RAW_Q(A, a);
+  FP_UNPACK_RAW_Q(B, b);
+  FP_CMP_Q (r, A, B, 2);
+
+  /* Relative comparisons signal invalid operation if either operand is NaN. */
+  if (r == 2)
+    {
+      FP_SET_EXCEPTION(FP_EX_INVALID);
+      FP_HANDLE_EXCEPTIONS;
+    }
+
+  return r;
+}
+
+long
+_OtsLssX (long al, long ah, long bl, long bh)
+{
+  long r = internal_compare (al, ah, bl, bh);
+  if (r == 2)
+    return -1;
+  else
+    return r < 0;
+}
+
+long
+_OtsLeqX (long al, long ah, long bl, long bh)
+{
+  long r = internal_compare (al, ah, bl, bh);
+  if (r == 2)
+    return -1;
+  else
+    return r <= 0;
+}
+
+long
+_OtsGtrX (long al, long ah, long bl, long bh)
+{
+  long r = internal_compare (al, ah, bl, bh);
+  if (r == 2)
+    return -1;
+  else
+    return r > 0;
+}
+
+long
+_OtsGeqX (long al, long ah, long bl, long bh)
+{
+  long r = internal_compare (al, ah, bl, bh);
+  if (r == 2)
+    return -1;
+  else
+    return r >= 0;
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cvtqux.c b/sysdeps/alpha/soft-fp/ots_cvtqux.c
new file mode 100644
index 0000000000..d7ab5bae43
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cvtqux.c
@@ -0,0 +1,40 @@
+/* Software floating-point emulation: unsigned integer to float conversion.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+/* Should never actually be used, since we've more bits of precision
+   than the incomming long, but needed for linkage.  */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE  FP_RND_ZERO
+
+void
+_OtsCvtQUX (unsigned long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  FP_DECL_RETURN(c);
+
+  FP_FROM_INT_Q(C, a, 64, long);
+  FP_PACK_Q(c, C);
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cvtqx.c b/sysdeps/alpha/soft-fp/ots_cvtqx.c
new file mode 100644
index 0000000000..0e1c6bdc41
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cvtqx.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: signed integer to float conversion.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+/* Should never actually be used, since we've more bits of precision
+   than the incomming long, but needed for linkage.  */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE  FP_RND_ZERO
+
+void
+_OtsCvtQX (long a)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(C);
+  FP_DECL_RETURN(c);
+
+  FP_FROM_INT_Q(C, a, 64, long);
+  FP_PACK_Q(c, C);
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cvttx.c b/sysdeps/alpha/soft-fp/ots_cvttx.c
new file mode 100644
index 0000000000..ee5ac324cd
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cvttx.c
@@ -0,0 +1,48 @@
+/* Software floating-point emulation: floating point extension.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+#include "double.h"
+
+/* Should never actually be used, since we're extending, but needed
+   for linkage.  */
+#undef FP_ROUNDMODE
+#define FP_ROUNDMODE  FP_RND_ZERO
+
+void
+_OtsConvertFloatTX(double a)
+{
+  FP_DECL_EX;
+  FP_DECL_D(A);
+  FP_DECL_Q(C);
+  FP_DECL_RETURN(c);
+
+  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;
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cvtxq.c b/sysdeps/alpha/soft-fp/ots_cvtxq.c
new file mode 100644
index 0000000000..1fd47da4f7
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cvtxq.c
@@ -0,0 +1,43 @@
+/* Software floating-point emulation: float to integer conversion.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+long
+_OtsCvtXQ (long al, long ah, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A);
+  long r, s;
+
+  /* If bit 3 is set, then integer overflow detection is requested.  */
+  s = _round & 8 ? 1 : -1;
+  _round = _round & 3;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+  FP_TO_INT_Q(r, A, 64, s);
+
+  if (s > 0 && (_fex &= FP_EX_INVALID))
+    FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/sysdeps/alpha/soft-fp/ots_cvtxt.c b/sysdeps/alpha/soft-fp/ots_cvtxt.c
new file mode 100644
index 0000000000..d1f8d2b945
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_cvtxt.c
@@ -0,0 +1,44 @@
+/* Software floating-point emulation: floating point truncation.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+#include "double.h"
+
+double
+_Ots_ConvertFloatXT (long al, long ah, long _round)
+{
+  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/sysdeps/alpha/soft-fp/ots_div.c b/sysdeps/alpha/soft-fp/ots_div.c
new file mode 100644
index 0000000000..eb07489284
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_div.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: division.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+void
+_OtsDivX(long al, long ah, long bl, long bh, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  FP_DECL_RETURN(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;
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_mul.c b/sysdeps/alpha/soft-fp/ots_mul.c
new file mode 100644
index 0000000000..f88ee33fbc
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_mul.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: multiplication.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+void
+_OtsMulX(long al, long ah, long bl, long bh, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  FP_DECL_RETURN(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;
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/ots_nintxq.c b/sysdeps/alpha/soft-fp/ots_nintxq.c
new file mode 100644
index 0000000000..2cb1ca4c2a
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_nintxq.c
@@ -0,0 +1,50 @@
+/* Software floating-point emulation: convert to fortran nearest.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+long
+_OtsNintXQ (long al, long ah, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  long r, s;
+
+  /* If bit 3 is set, then integer overflow detection is requested.  */
+  s = _round & 8 ? 1 : -1;
+  _round = _round & 3;
+
+  FP_INIT_ROUNDMODE;
+  FP_UNPACK_Q(A, a);
+
+  /* Build 0.5 * sign(A) */
+  B_e = _FP_EXPBIAS_Q;
+  __FP_FRAC_SET_2 (B, _FP_IMPLBIT_Q, 0);
+  B_s = A_s;
+  _FP_UNPACK_CANONICAL(Q,2,B);
+
+  FP_ADD_Q(C, A, B);
+  FP_TO_INT_Q(r, C, 64, s);
+  if (s > 0 && (_fex &= FP_EX_INVALID))
+    FP_HANDLE_EXCEPTIONS;
+
+  return r;
+}
diff --git a/sysdeps/alpha/soft-fp/ots_sub.c b/sysdeps/alpha/soft-fp/ots_sub.c
new file mode 100644
index 0000000000..c10043f071
--- /dev/null
+++ b/sysdeps/alpha/soft-fp/ots_sub.c
@@ -0,0 +1,39 @@
+/* Software floating-point emulation: subtraction.
+   Copyright (C) 1997,1999,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com) and
+		  Jakub Jelinek (jj@ultra.linux.cz).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "local-soft-fp.h"
+
+void
+_OtsSubX(long al, long ah, long bl, long bh, long _round)
+{
+  FP_DECL_EX;
+  FP_DECL_Q(A); FP_DECL_Q(B); FP_DECL_Q(C);
+  FP_DECL_RETURN(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;
+
+  FP_RETURN(c);
+}
diff --git a/sysdeps/alpha/soft-fp/sfp-machine.h b/sysdeps/alpha/soft-fp/sfp-machine.h
index 73b934ddce..2bad4e9dc6 100644
--- a/sysdeps/alpha/soft-fp/sfp-machine.h
+++ b/sysdeps/alpha/soft-fp/sfp-machine.h
@@ -1,35 +1,94 @@
+/* Machine-dependent software floating-point definitions.
+   Alpha userland IEEE 128-bit version.
+   Copyright (C) 2004 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 Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fenv_libc.h>
+
 #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)
+  _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(_FP_WFRACBITS_Q,R,X,Y,_alpha_mul_64_128)
+  _FP_MUL_MEAT_2_wide(_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_D(R,X,Y)	_FP_DIV_MEAT_1_udiv_norm(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_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
-#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;						\
+
+/* Alpha Architecture Handbook, 4.7.10.4 sez that we should prefer any
+   type of NaN in Fb, then Fa.  */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)                      \
+  do {                                                          \
+    R##_s = Y##_s;                                              \
+    _FP_FRAC_COPY_##wc(R,X);                                    \
+    R##_c = FP_CLS_NAN;                                         \
   } while (0)
+
+/* Rounding mode settings.  */
+#define FP_RND_NEAREST		FE_TONEAREST
+#define FP_RND_ZERO		FE_TOWARDZERO
+#define FP_RND_PINF		FE_UPWARD
+#define FP_RND_MINF		FE_DOWNWARD
+
+/* Obtain the current rounding mode.  It's given as an argument to
+   all the Ots functions, with 4 meaning "dynamic".  */
+#define FP_ROUNDMODE		_round
+
+/* Exception flags. */
+#define FP_EX_INVALID		FE_INVALID
+#define FP_EX_OVERFLOW		FE_OVERFLOW
+#define FP_EX_UNDERFLOW		FE_UNDERFLOW
+#define FP_EX_DIVZERO		FE_DIVBYZERO
+#define FP_EX_INEXACT		FE_INEXACT
+
+#define FP_INIT_ROUNDMODE					\
+do {								\
+  if (__builtin_expect (_round == 4, 0))			\
+    {								\
+      unsigned long t;						\
+      __asm__ __volatile__("excb; mf_fpcr %0" : "=f"(t));	\
+      _round = (t >> FPCR_ROUND_SHIFT) & 3;			\
+    }								\
+} while (0)
+
+#define FP_HANDLE_EXCEPTIONS					\
+do {								\
+  if (__builtin_expect (_fex, 0))				\
+    {								\
+      unsigned long t = __ieee_get_fp_control ();		\
+      __ieee_set_fp_control (t | _fex);				\
+    }								\
+} while (0)