diff options
author | Richard Henderson <rth@redhat.com> | 2004-03-06 20:46:23 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 2004-03-06 20:46:23 +0000 |
commit | a598e3fc041f38d0c43be55d1664ff7ed0cf405b (patch) | |
tree | da22cbd1cae0cff761823248c1350f7d6ec32177 /sysdeps/alpha | |
parent | 4df8c11d26a29bc3a6116a9125cdfdca3cd517bb (diff) | |
download | glibc-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/Implies | 1 | ||||
-rw-r--r-- | sysdeps/alpha/Subdirs | 1 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/Dist | 13 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/Makefile | 6 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/Versions | 8 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/local-soft-fp.h | 44 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_add.c | 39 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cmp.c | 64 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cmpe.c | 83 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cvtqux.c | 40 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cvtqx.c | 39 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cvttx.c | 48 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cvtxq.c | 43 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_cvtxt.c | 44 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_div.c | 39 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_mul.c | 39 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_nintxq.c | 50 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/ots_sub.c | 39 | ||||
-rw-r--r-- | sysdeps/alpha/soft-fp/sfp-machine.h | 97 |
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) |