This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! This patch fixes a few sparc32 build things: 1) works around the chicken-and-egg problem where -mlong-double-128 libgcc requires -mlong-double-128 glibc (for _Q_*) and -mlong-double-128 glibc requires -mlong-double-128 libgcc (for __multc3/__divtc3). 2) prepends sparc/sparc32/fpu before ldbl-64-128 and ldbl-opt, so that the generic wrappers don't override e.g. s_fabs{,l} and adjusts them. 2006-01-31 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/sparc/sparc32/Implies: Moved to ... * sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies: ... here. New file. * sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Makefile: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/fpu/divtc3.c: New file. * sysdeps/unix/sysv/linux/sparc/sparc32/fpu/multc3.c: New file. * sysdeps/sparc/sparc32/fpu/s_fabsl.c: Include math.h and math_ldbl_opt.h. (fabsl): Use long_double_symbol instead of weak_alias. * sysdeps/sparc/sparc32/fpu/s_fabs.c: Include math.h and math_ldbl_opt.h. [LONG_DOUBLE_COMPAT] (fabsl): Add compat_symbol. --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies.jj 2006-01-31 16:06:04.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Implies 2006-01-31 16:06:00.000000000 +0100 @@ -0,0 +1,5 @@ +# Override ldbl-opt with sparc specific routines. +sparc/sparc32/fpu +# These supply the ABI compatibility for when long double was double. +ieee754/ldbl-64-128 +ieee754/ldbl-opt --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/divtc3.c.jj 2006-01-31 16:08:19.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/divtc3.c 2006-01-31 16:15:34.000000000 +0100 @@ -0,0 +1,75 @@ +/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@redhat.com>, 2005. + + 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 <stdbool.h> +#include <math.h> +#include <complex.h> + +attribute_hidden +long double _Complex +__divtc3 (long double a, long double b, long double c, long double d) +{ + long double denom, ratio, x, y; + + /* ??? We can get better behavior from logarithmic scaling instead of + the division. But that would mean starting to link libgcc against + libm. We could implement something akin to ldexp/frexp as gcc builtins + fairly easily... */ + if (fabsl (c) < fabsl (d)) + { + ratio = c / d; + denom = (c * ratio) + d; + x = ((a * ratio) + b) / denom; + y = ((b * ratio) - a) / denom; + } + else + { + ratio = d / c; + denom = (d * ratio) + c; + x = ((b * ratio) + a) / denom; + y = (b - (a * ratio)) / denom; + } + + /* Recover infinities and zeros that computed as NaN+iNaN; the only cases + are nonzero/zero, infinite/finite, and finite/infinite. */ + if (isnan (x) && isnan (y)) + { + if (denom == 0.0 && (!isnan (a) || !isnan (b))) + { + x = copysignl (INFINITY, c) * a; + y = copysignl (INFINITY, c) * b; + } + else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) + { + a = copysignl (isinf (a) ? 1 : 0, a); + b = copysignl (isinf (b) ? 1 : 0, b); + x = INFINITY * (a * c + b * d); + y = INFINITY * (b * c - a * d); + } + else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) + { + c = copysignl (isinf (c) ? 1 : 0, c); + d = copysignl (isinf (d) ? 1 : 0, d); + x = 0.0 * (a * c + b * d); + y = 0.0 * (b * c - a * d); + } + } + + return x + I * y; +} --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/multc3.c.jj 2006-01-31 16:08:32.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/multc3.c 2006-01-31 16:15:44.000000000 +0100 @@ -0,0 +1,80 @@ +/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@redhat.com>, 2005. + + 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 <stdbool.h> +#include <math.h> +#include <complex.h> + +attribute_hidden +long double _Complex +__multc3 (long double a, long double b, long double c, long double d) +{ + long double ac, bd, ad, bc, x, y; + + ac = a * c; + bd = b * d; + ad = a * d; + bc = b * c; + + x = ac - bd; + y = ad + bc; + + if (isnan (x) && isnan (y)) + { + /* Recover infinities that computed as NaN + iNaN. */ + bool recalc = 0; + if (isinf (a) || isinf (b)) + { + /* z is infinite. "Box" the infinity and change NaNs in + the other factor to 0. */ + a = copysignl (isinf (a) ? 1 : 0, a); + b = copysignl (isinf (b) ? 1 : 0, b); + if (isnan (c)) c = copysignl (0, c); + if (isnan (d)) d = copysignl (0, d); + recalc = 1; + } + if (isinf (c) || isinf (d)) + { + /* w is infinite. "Box" the infinity and change NaNs in + the other factor to 0. */ + c = copysignl (isinf (c) ? 1 : 0, c); + d = copysignl (isinf (d) ? 1 : 0, d); + if (isnan (a)) a = copysignl (0, a); + if (isnan (b)) b = copysignl (0, b); + recalc = 1; + } + if (!recalc + && (isinf (ac) || isinf (bd) || isinf (ad) || isinf (bc))) + { + /* Recover infinities from overflow by changing NaNs to 0. */ + if (isnan (a)) a = copysignl (0, a); + if (isnan (b)) b = copysignl (0, b); + if (isnan (c)) c = copysignl (0, c); + if (isnan (d)) d = copysignl (0, d); + recalc = 1; + } + if (recalc) + { + x = INFINITY * (a * c - b * d); + y = INFINITY * (a * d + b * c); + } + } + + return x + I * y; +} --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Makefile.jj 2006-01-31 16:09:48.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/fpu/Makefile 2006-01-31 16:12:58.000000000 +0100 @@ -0,0 +1,9 @@ +ifeq ($(subdir),math) +# These 2 routines are normally in libgcc{.a,_s.so.1}. +# However, sparc32 -mlong-double-128 libgcc relies on +# glibc providing _Q_* routines and without these files +# glibc relies on __multc3/__divtc3 only provided +# by libgcc if configured with -mlong-double-128. +# Provide these routines here as well. +libm-routines += multc3 divtc3 +endif # math --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies.jj 2006-01-14 13:09:03.000000000 +0100 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/Implies 2006-01-31 16:06:10.000000000 +0100 @@ -1,3 +0,0 @@ -# These supply the ABI compatibility for when long double was double. -ieee754/ldbl-64-128 -ieee754/ldbl-opt --- libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c.jj 2006-01-14 13:09:02.000000000 +0100 +++ libc/sysdeps/sparc/sparc32/fpu/s_fabsl.c 2006-01-31 17:10:10.000000000 +0100 @@ -1,5 +1,8 @@ +#include <math.h> +#include <math_ldbl_opt.h> + long double __fabsl (long double x) { return __builtin_fabsl (x); } -weak_alias (__fabsl, fabsl) +long_double_symbol (libm, __fabsl, fabsl); --- libc/sysdeps/sparc/sparc32/fpu/s_fabs.c.jj 2006-01-14 13:09:02.000000000 +0100 +++ libc/sysdeps/sparc/sparc32/fpu/s_fabs.c 2006-01-31 17:10:57.000000000 +0100 @@ -1,5 +1,11 @@ +#include <math.h> +#include <math_ldbl_opt.h> + double __fabs (double x) { return __builtin_fabs (x); } weak_alias (__fabs, fabs) +#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0) +compat_symbol (libm, __fabs, fabsl, GLIBC_2_0); +#endif Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |