* soft-fp/quad.h (union _FP_UNION_Q): Add longs structure.
authorrth <rth>
Sat, 6 Mar 2004 20:46:21 +0000 (20:46 +0000)
committerrth <rth>
Sat, 6 Mar 2004 20:46:21 +0000 (20:46 +0000)
        * 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.

21 files changed:
ChangeLog
soft-fp/quad.h
sysdeps/alpha/Implies
sysdeps/alpha/Subdirs [new file with mode: 0644]
sysdeps/alpha/soft-fp/Dist
sysdeps/alpha/soft-fp/Makefile [new file with mode: 0644]
sysdeps/alpha/soft-fp/Versions [new file with mode: 0644]
sysdeps/alpha/soft-fp/local-soft-fp.h [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_add.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cmp.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cmpe.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cvtqux.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cvtqx.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cvttx.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cvtxq.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_cvtxt.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_div.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_mul.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_nintxq.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/ots_sub.c [new file with mode: 0644]
sysdeps/alpha/soft-fp/sfp-machine.h

index c928251..b88511e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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.
+
 2004-03-06  Ulrich Drepper  <drepper@redhat.com>
 
        * configure.in: Recognize --enable-bind-now.
index 080139e..33ee4d4 100644 (file)
@@ -131,6 +131,9 @@ union _FP_UNION_Q
 {
   long double flt /* __attribute__((mode(TF))) */ ;
   struct {
+    _FP_W_TYPE a, b;
+  } longs;
+  struct {
 #if __BYTE_ORDER == __BIG_ENDIAN
     unsigned sign  : 1;
     unsigned exp   : _FP_EXPBITS_Q;
index 2c6af5b..4b354f3 100644 (file)
@@ -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 (file)
index 0000000..87eadf3
--- /dev/null
@@ -0,0 +1 @@
+soft-fp
index 7e9914f..3d75ee7 100644 (file)
@@ -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 (file)
index 0000000..d7e7e26
--- /dev/null
@@ -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 (file)
index 0000000..3901287
--- /dev/null
@@ -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 (file)
index 0000000..e93a2ad
--- /dev/null
@@ -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 (file)
index 0000000..b4f6c28
--- /dev/null
@@ -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 (file)
index 0000000..c356b48
--- /dev/null
@@ -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 (file)
index 0000000..001eb75
--- /dev/null
@@ -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 (file)
index 0000000..d7ab5ba
--- /dev/null
@@ -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 (file)
index 0000000..0e1c6bd
--- /dev/null
@@ -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 (file)
index 0000000..ee5ac32
--- /dev/null
@@ -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 (file)
index 0000000..1fd47da
--- /dev/null
@@ -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 (file)
index 0000000..d1f8d2b
--- /dev/null
@@ -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 (file)
index 0000000..eb07489
--- /dev/null
@@ -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 (file)
index 0000000..f88ee33
--- /dev/null
@@ -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 (file)
index 0000000..2cb1ca4
--- /dev/null
@@ -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 (file)
index 0000000..c10043f
--- /dev/null
@@ -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);
+}
index 73b934d..2bad4e9 100644 (file)
@@ -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)