aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Jaeger <aj@suse.de>2012-03-20 20:40:16 +0100
committerAndreas Jaeger <aj@suse.de>2012-03-20 20:40:16 +0100
commitd6373f9ce3972a1891e4d09479a98e0dbc7e3d73 (patch)
tree39f9e5c231c70fde2c6326d066a3b9fd892042c2
parent1d6c3d237d10606121c959b9bd2ae722f79ea899 (diff)
parent1897ad44326bb7761dcda46132ae303f7288aba9 (diff)
downloadglibc-d6373f9ce3972a1891e4d09479a98e0dbc7e3d73.tar.xz
glibc-d6373f9ce3972a1891e4d09479a98e0dbc7e3d73.zip
Merge branch 'master' into elf-move
-rw-r--r--ChangeLog81
-rw-r--r--Makerules8
-rw-r--r--NEWS10
-rw-r--r--math/libm-test.inc38
-rw-r--r--math/s_clog.c27
-rw-r--r--math/s_clog10.c28
-rw-r--r--math/s_clog10f.c28
-rw-r--r--math/s_clog10l.c28
-rw-r--r--math/s_clogf.c28
-rw-r--r--math/s_clogl.c27
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps60
-rw-r--r--sysdeps/ieee754/dbl-64/e_atan2.c9
-rw-r--r--sysdeps/unix/Makefile240
-rw-r--r--sysdeps/unix/errnos-tmpl.c98
-rw-r--r--sysdeps/unix/errnos.awk12
-rw-r--r--sysdeps/unix/ioctls-tmpl.c134
-rw-r--r--sysdeps/unix/ioctls.awk10
-rw-r--r--sysdeps/unix/mk-local_lim.c125
-rwxr-xr-xsysdeps/unix/snarf-ioctls48
-rw-r--r--sysdeps/x86_64/fpu/libm-test-ulps67
20 files changed, 404 insertions, 702 deletions
diff --git a/ChangeLog b/ChangeLog
index 88ee5935c2..e806afcbca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,84 @@
+2012-03-19 Joseph Myers <joseph@codesourcery.com>
+
+ [BZ #13629]
+ * math/s_clog.c: Include <float.h>.
+ (__clog): Scale large or subnormal inputs.
+ * math/s_clogf.c: Likewise.
+ * math/s_clogl.c: Likewise.
+ * math/s_clog10.c: Include <float.h>.
+ (M_LOG10_2): Define.
+ (__clog10): Scale large or subnormal inputs.
+ * math/s_clog10f.c: Likewise.
+ * math/s_clog10l.c: Likewise.
+ * math/libm-test.inc (clog_test): Add more tests.
+ (clog10_test): Likewise.
+ * sysdeps/i386/fpu/libm-test-ulps: Update.
+ * sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
+
+ [BZ #11451]
+ * sysdeps/ieee754/dbl-64/e_atan2.c (__ieee754_atan2): Scale large
+ x and y.
+ * math/libm-test.inc (atan2_test): Add another test.
+
+ * Makerules (common-objdir-compile): Remove.
+ * sysdeps/unix/Makefile (config-generated): Do not add
+ $(unix-generated) to variable.
+ [generic bits/local_lim.h] (mk-local_lim-CFLAGS): Remove variable.
+ [generic bits/local_lim.h] ($(common-objpfx)bits/local_lim.h):
+ Remove rule.
+ [generic bits/local_lim.h] ($(common-objpfx)mk-local_lim):
+ Likewise.
+ [generic bits/local_lim.h] (before-compile): Do not append to
+ variable.
+ [generic bits/local_lim.h] (common-generated): Likewise.
+ [generic sys/param.h] (before-compile): Do not append to variable.
+ [generic sys/param.h] ($(common-objpfx)sys/param.h): Remove rule.
+ [generic sys/param.h] ($(common-objpfx)param.h.c): Likewise.
+ [generic sys/param.h] ($(common-objpfx)param.h.dep): Likewise.
+ [generic sys/param.h] ($(common-objpfx)param.h.dep): Do not
+ include.
+ [generic sys/param.h] (sys/param.h-includes): Remove variable.
+ [generic sys/param.h] (sys/param.h-includes): Remove rule.
+ [generic sys/param.h] ($(addprefix
+ $(common-objpfx),$(sys/param.h-includes))): Likewise.
+ [generic sys/param.h] (common-generated): Do not append to
+ variable.
+ [generic sys/param.h] (sysdep_headers): Likewise.
+ [generic bits/errno.h] (before-compile): Do not append to
+ variable.
+ [generic bits/errno.h] ($(common-objpfx)bits/errno.h): Remove
+ rule.
+ [generic bits/errno.h] ($(common-objpfx)make-errnos): Likewise.
+ [generic bits/errno.h] ($(common-objpfx)make-errnos.c): Likewise.
+ [generic bits/errno.h] ($(common-objpfx)errnos): Likewise.
+ [generic bits/errno.h] (common-generated): Do not append to
+ variable.
+ [generic bits/ioctls.h] (before-compile): Do not append to
+ variable.
+ [generic bits/ioctls.h] ($(common-objpfx)bits/ioctls.h): Remove
+ rule.
+ [generic bits/ioctls.h] (ioctl-includes): Remove variable.
+ [generic bits/ioctls.h] (make-ioctls-CFLAGS): Likewise.
+ [generic bits/ioctls.h] ($(common-objpfx)make-ioctls): Remove
+ rule.
+ [generic bits/ioctls.h] ($(common-objpfx)make-ioctls.c): Likewise.
+ [generic bits/ioctls.h] (bits_termios.h): Remove variable.
+ [generic bits/ioctls.h] ($(common-objpfx)ioctls): Remove rule.
+ [generic bits/ioctls.h] (common-generated): Do not append to
+ variable.
+ [generic sys/syscall.h] (syscall.h): Remove variable.
+ [generic sys/syscall.h] ($(common-objpfx)sys/syscall.h): Remove
+ rule.
+ [generic sys/syscall.h] (before-compile): Do not append to
+ variable.
+ [generic sys/syscall.h] (common-generated): Likewise.
+ * sysdeps/unix/errnos-tmpl.c: Remove file.
+ * sysdeps/unix/errnos.awk: Likewise.
+ * sysdeps/unix/ioctls-tmpl.c: Likewise.
+ * sysdeps/unix/ioctls.awk: Likewise.
+ * sysdeps/unix/mk-local_lim.c: Likewise.
+ * sysdeps/unix/snarf-ioctls: Likewise.
+
2012-03-19 Richard Henderson <rth@twiddle.net>
* sysdeps/i386/fpu/fenv_private.h: New file.
diff --git a/Makerules b/Makerules
index f1807c2ee8..d184be6d20 100644
--- a/Makerules
+++ b/Makerules
@@ -1122,14 +1122,6 @@ $(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \
$(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(@F)
endef
-# Command to compile $< in $(common-objdir) using the native libraries.
-# We must cd to $(objdir) anyway so that $(..)config.h is valid.
-define common-objdir-compile
-$(patsubst %/,cd % &&,$(objpfx)) \
-$(BUILD_CC) $($(basename $(<F))-CFLAGS) $(ALL_BUILD_CFLAGS) \
- $(firstword $(filter /%,$< $(shell pwd)/$<)) -o $(..)$(@F)
-endef
-
# We always want to use configuration definitions.
# Note that this is only used for commands running in $(objpfx).
ALL_BUILD_CFLAGS = $(BUILD_CFLAGS) -include $(..)config.h
diff --git a/NEWS b/NEWS
index 5af4f68f06..df8e1f03a6 100644
--- a/NEWS
+++ b/NEWS
@@ -12,11 +12,11 @@ Version 2.16
174, 350, 411, 2541, 2547, 2548, 2551, 2552, 2553, 2554, 2562, 2563, 2565,
2566, 2576, 3335, 3976, 3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805,
5993, 6471, 6884, 6907, 6911, 9739, 9902, 10110, 10135, 10140, 10210,
- 10545, 10716, 11174, 11322, 11365, 11494, 12047, 13058, 13525, 13526,
- 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551, 13552,
- 13553, 13555, 13559, 13566, 13583, 13618, 13637, 13656, 13658, 13673,
- 13695, 13704, 13706, 13726, 13738, 13786, 13792, 13806, 13840, 13841,
- 13844, 13846, 13851, 13852, 13854
+ 10545, 10716, 11174, 11322, 11365, 11451, 11494, 12047, 13058, 13525,
+ 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551,
+ 13552, 13553, 13555, 13559, 13566, 13583, 13618, 13637, 13656, 13658,
+ 13673, 13695, 13704, 13706, 13726, 13738, 13786, 13792, 13806, 13840,
+ 13841, 13844, 13846, 13851, 13852, 13854
* ISO C11 support:
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 5638b76869..8bb435875d 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -949,6 +949,8 @@ atan2_test (void)
TEST_ff_f (atan2, minus_infty, minus_infty, -M_PI_34l);
TEST_ff_f (atan2, nan_value, nan_value, nan_value);
+ TEST_ff_f (atan2, max_value, max_value, M_PI_4l);
+
TEST_ff_f (atan2, 0.75L, 1, 0.643501108793284386802809228717322638L);
TEST_ff_f (atan2, -0.75L, 1.0L, -0.643501108793284386802809228717322638L);
TEST_ff_f (atan2, 0.75L, -1.0L, 2.49809154479650885165983415456218025L);
@@ -1967,6 +1969,24 @@ clog_test (void)
TEST_c_c (clog, 0.75L, 1.25L, 0.376885901188190075998919126749298416L, 1.03037682652431246378774332703115153L);
TEST_c_c (clog, -2, -3, 1.2824746787307683680267437207826593L, -2.1587989303424641704769327722648368L);
+ TEST_c_c (clog, 0x1.fffffep+127L, 0x1.fffffep+127L, 89.06941264234832570836679262104313101776L, M_PI_4l);
+ TEST_c_c (clog, 0x1.fffffep+127L, 1.0L, 88.72283905206835305365817656031404273372L, 2.938736052218037251011746307725933020145e-39L);
+ TEST_c_c (clog, 0x1p-149L, 0x1p-149L, -102.9323563131518784484589700365392203592L, M_PI_4l);
+ TEST_c_c (clog, 0x1p-147L, 0x1p-147L, -101.5460619520319878296245057936228672231L, M_PI_4l);
+
+#ifndef TEST_FLOAT
+ TEST_c_c (clog, 0x1.fffffffffffffp+1023L, 0x1.fffffffffffffp+1023L, 710.1292864836639693869320059713862337880L, M_PI_4l);
+ TEST_c_c (clog, 0x1.fffffffffffffp+1023L, 0x1p+1023L, 709.8942846690411016323109979483151967689L, 0.4636476090008061606231772164674799632783L);
+ TEST_c_c (clog, 0x1p-1074L, 0x1p-1074L, -744.0934983311012896593986823853525458290L, M_PI_4l);
+ TEST_c_c (clog, 0x1p-1073L, 0x1p-1073L, -743.4003511505413443499814502638943692610L, M_PI_4l);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+ TEST_c_c (clog, 0x1.fp+16383L, 0x1.fp+16383L, 11356.83823118610934184548269774874545400L, M_PI_4l);
+ TEST_c_c (clog, 0x1.fp+16383L, 0x1p+16383L, 11356.60974243783798653123798337822335902L, 0.4764674194737066993385333770295162295856L);
+ TEST_c_c (clog, 0x1p-16440L, 0x1p-16441L, -11395.22807662984378194141292922726786191L, 0.4636476090008061162142562314612144020285L);
+#endif
+
END (clog, complex);
}
@@ -2033,6 +2053,24 @@ clog10_test (void)
TEST_c_c (clog10, 0.75L, 1.25L, 0.163679467193165171449476605077428975L, 0.447486970040493067069984724340855636L);
TEST_c_c (clog10, -2, -3, 0.556971676153418384603252578971164214L, -0.937554462986374708541507952140189646L);
+ TEST_c_c (clog10, 0x1.fffffep+127L, 0x1.fffffep+127L, 38.68235441693561449174780668781319348761L, M_PI4_LOG10El);
+ TEST_c_c (clog10, 0x1.fffffep+127L, 1.0L, 38.53183941910362389414093724045094697423L, 1.276276851248440096917018665609900318458e-39L);
+ TEST_c_c (clog10, 0x1p-149L, 0x1p-149L, -44.70295435610120748924022586658721447508L, M_PI4_LOG10El);
+ TEST_c_c (clog10, 0x1p-147L, 0x1p-147L, -44.10089436477324509881274807713822842154L, M_PI4_LOG10El);
+
+#ifndef TEST_FLOAT
+ TEST_c_c (clog10, 0x1.fffffffffffffp+1023L, 0x1.fffffffffffffp+1023L, 308.4052305577487344482591243175787477115L, M_PI4_LOG10El);
+ TEST_c_c (clog10, 0x1.fffffffffffffp+1023L, 0x1p+1023L, 308.3031705664207720674749211936626341569L, 0.2013595981366865903254995612594728746470L);
+ TEST_c_c (clog10, 0x1p-1074L, 0x1p-1074L, -323.1557003452838130619487034867432642357L, M_PI4_LOG10El);
+ TEST_c_c (clog10, 0x1p-1073L, 0x1p-1073L, -322.8546703496198318667349645920187712089L, M_PI4_LOG10El);
+#endif
+
+#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
+ TEST_c_c (clog10, 0x1.fp+16383L, 0x1.fp+16383L, 4932.212175672014259683102930239951947672L, M_PI4_LOG10El);
+ TEST_c_c (clog10, 0x1.fp+16383L, 0x1p+16383L, 4932.112944269463028900262609694408579449L, 0.2069271710841128115912940666587802677383L);
+ TEST_c_c (clog10, 0x1p-16440L, 0x1p-16441L, -4948.884673709346821106688037612752099609L, 0.2013595981366865710389502301937289472543L);
+#endif
+
END (clog10, complex);
}
diff --git a/math/s_clog.c b/math/s_clog.c
index 5bbca00388..15e5e9c678 100644
--- a/math/s_clog.c
+++ b/math/s_clog.c
@@ -1,5 +1,5 @@
/* Compute complex natural logarithm.
- Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,7 +20,7 @@
#include <complex.h>
#include <math.h>
#include <math_private.h>
-
+#include <float.h>
__complex__ double
__clog (__complex__ double x)
@@ -40,8 +40,27 @@ __clog (__complex__ double x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_log (__ieee754_hypot (__real__ x,
- __imag__ x));
+ double d;
+ int scale = 0;
+
+ if (fabs (__real__ x) > DBL_MAX / 2.0
+ || fabs (__imag__ x) > DBL_MAX / 2.0)
+ {
+ scale = -1;
+ __real__ x = __scalbn (__real__ x, scale);
+ __imag__ x = __scalbn (__imag__ x, scale);
+ }
+ else if (fabs (__real__ x) < DBL_MIN
+ && fabs (__imag__ x) < DBL_MIN)
+ {
+ scale = DBL_MANT_DIG;
+ __real__ x = __scalbn (__real__ x, scale);
+ __imag__ x = __scalbn (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypot (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_log (d) - scale * M_LN2;
__imag__ result = __ieee754_atan2 (__imag__ x, __real__ x);
}
else
diff --git a/math/s_clog10.c b/math/s_clog10.c
index 3eb9c518a8..9d366d6f2b 100644
--- a/math/s_clog10.c
+++ b/math/s_clog10.c
@@ -1,5 +1,5 @@
/* Compute complex base 10 logarithm.
- Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,7 +20,10 @@
#include <complex.h>
#include <math.h>
#include <math_private.h>
+#include <float.h>
+/* log_10 (2). */
+#define M_LOG10_2 0.3010299956639811952137388947244930267682
__complex__ double
__clog10 (__complex__ double x)
@@ -40,8 +43,27 @@ __clog10 (__complex__ double x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_log10 (__ieee754_hypot (__real__ x,
- __imag__ x));
+ double d;
+ int scale = 0;
+
+ if (fabs (__real__ x) > DBL_MAX / 2.0
+ || fabs (__imag__ x) > DBL_MAX / 2.0)
+ {
+ scale = -1;
+ __real__ x = __scalbn (__real__ x, scale);
+ __imag__ x = __scalbn (__imag__ x, scale);
+ }
+ else if (fabs (__real__ x) < DBL_MIN
+ && fabs (__imag__ x) < DBL_MIN)
+ {
+ scale = DBL_MANT_DIG;
+ __real__ x = __scalbn (__real__ x, scale);
+ __imag__ x = __scalbn (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypot (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_log10 (d) - scale * M_LOG10_2;
__imag__ result = M_LOG10E * __ieee754_atan2 (__imag__ x, __real__ x);
}
else
diff --git a/math/s_clog10f.c b/math/s_clog10f.c
index e48d928b3c..11bb0bb9ad 100644
--- a/math/s_clog10f.c
+++ b/math/s_clog10f.c
@@ -1,5 +1,5 @@
/* Compute complex base 10 logarithm.
- Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,7 +20,10 @@
#include <complex.h>
#include <math.h>
#include <math_private.h>
+#include <float.h>
+/* log_10 (2). */
+#define M_LOG10_2f 0.3010299956639811952137388947244930267682f
__complex__ float
__clog10f (__complex__ float x)
@@ -40,8 +43,27 @@ __clog10f (__complex__ float x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_log10f (__ieee754_hypotf (__real__ x,
- __imag__ x));
+ float d;
+ int scale = 0;
+
+ if (fabsf (__real__ x) > FLT_MAX / 2.0f
+ || fabsf (__imag__ x) > FLT_MAX / 2.0f)
+ {
+ scale = -1;
+ __real__ x = __scalbnf (__real__ x, scale);
+ __imag__ x = __scalbnf (__imag__ x, scale);
+ }
+ else if (fabsf (__real__ x) < FLT_MIN
+ && fabsf (__imag__ x) < FLT_MIN)
+ {
+ scale = FLT_MANT_DIG;
+ __real__ x = __scalbnf (__real__ x, scale);
+ __imag__ x = __scalbnf (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypotf (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_log10f (d) - scale * M_LOG10_2f;
__imag__ result = M_LOG10E * __ieee754_atan2f (__imag__ x, __real__ x);
}
else
diff --git a/math/s_clog10l.c b/math/s_clog10l.c
index 72b553152e..d1fc872cba 100644
--- a/math/s_clog10l.c
+++ b/math/s_clog10l.c
@@ -1,5 +1,5 @@
/* Compute complex base 10 logarithm.
- Copyright (C) 1997, 1998, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,7 +20,10 @@
#include <complex.h>
#include <math.h>
#include <math_private.h>
+#include <float.h>
+/* log_10 (2). */
+#define M_LOG10_2l 0.3010299956639811952137388947244930267682L
__complex__ long double
__clog10l (__complex__ long double x)
@@ -40,8 +43,27 @@ __clog10l (__complex__ long double x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_log10l (__ieee754_hypotl (__real__ x,
- __imag__ x));
+ long double d;
+ int scale = 0;
+
+ if (fabsl (__real__ x) > LDBL_MAX / 2.0L
+ || fabsl (__imag__ x) > LDBL_MAX / 2.0L)
+ {
+ scale = -1;
+ __real__ x = __scalbnl (__real__ x, scale);
+ __imag__ x = __scalbnl (__imag__ x, scale);
+ }
+ else if (fabsl (__real__ x) < LDBL_MIN
+ && fabsl (__imag__ x) < LDBL_MIN)
+ {
+ scale = LDBL_MANT_DIG;
+ __real__ x = __scalbnl (__real__ x, scale);
+ __imag__ x = __scalbnl (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypotl (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_log10l (d) - scale * M_LOG10_2l;
__imag__ result = M_LOG10El * __ieee754_atan2l (__imag__ x, __real__ x);
}
else
diff --git a/math/s_clogf.c b/math/s_clogf.c
index eb8433a280..0b27506fb4 100644
--- a/math/s_clogf.c
+++ b/math/s_clogf.c
@@ -1,5 +1,5 @@
/* Compute complex natural logarithm.
- Copyright (C) 1997, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -19,9 +19,8 @@
#include <complex.h>
#include <math.h>
-
#include <math_private.h>
-
+#include <float.h>
__complex__ float
__clogf (__complex__ float x)
@@ -41,8 +40,27 @@ __clogf (__complex__ float x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_logf (__ieee754_hypotf (__real__ x,
- __imag__ x));
+ float d;
+ int scale = 0;
+
+ if (fabsf (__real__ x) > FLT_MAX / 2.0f
+ || fabsf (__imag__ x) > FLT_MAX / 2.0f)
+ {
+ scale = -1;
+ __real__ x = __scalbnf (__real__ x, scale);
+ __imag__ x = __scalbnf (__imag__ x, scale);
+ }
+ else if (fabsf (__real__ x) < FLT_MIN
+ && fabsf (__imag__ x) < FLT_MIN)
+ {
+ scale = FLT_MANT_DIG;
+ __real__ x = __scalbnf (__real__ x, scale);
+ __imag__ x = __scalbnf (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypotf (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_logf (d) - scale * (float) M_LN2;
__imag__ result = __ieee754_atan2f (__imag__ x, __real__ x);
}
else
diff --git a/math/s_clogl.c b/math/s_clogl.c
index 11d4878252..8968eefee3 100644
--- a/math/s_clogl.c
+++ b/math/s_clogl.c
@@ -1,5 +1,5 @@
/* Compute complex natural logarithm.
- Copyright (C) 1997, 1998, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,7 +20,7 @@
#include <complex.h>
#include <math.h>
#include <math_private.h>
-
+#include <float.h>
__complex__ long double
__clogl (__complex__ long double x)
@@ -40,8 +40,27 @@ __clogl (__complex__ long double x)
else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
{
/* Neither real nor imaginary part is NaN. */
- __real__ result = __ieee754_logl (__ieee754_hypotl (__real__ x,
- __imag__ x));
+ long double d;
+ int scale = 0;
+
+ if (fabsl (__real__ x) > LDBL_MAX / 2.0L
+ || fabsl (__imag__ x) > LDBL_MAX / 2.0L)
+ {
+ scale = -1;
+ __real__ x = __scalbnl (__real__ x, scale);
+ __imag__ x = __scalbnl (__imag__ x, scale);
+ }
+ else if (fabsl (__real__ x) < LDBL_MIN
+ && fabsl (__imag__ x) < LDBL_MIN)
+ {
+ scale = LDBL_MANT_DIG;
+ __real__ x = __scalbnl (__real__ x, scale);
+ __imag__ x = __scalbnl (__imag__ x, scale);
+ }
+
+ d = __ieee754_hypotl (__real__ x, __imag__ x);
+
+ __real__ result = __ieee754_logl (d) - scale * M_LN2l;
__imag__ result = __ieee754_atan2l (__imag__ x, __real__ x);
}
else
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index