]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/commitdiff
glibc: Update patchset.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 12 Oct 2013 14:03:05 +0000 (16:03 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 12 Oct 2013 14:03:05 +0000 (16:03 +0200)
Import latest patches from RHEL6.

30 files changed:
lfs/glibc
src/patches/glibc/glibc-rh804630.patch [deleted file]
src/patches/glibc/glibc-rh804686.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh806404.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh809726.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh823909.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh826149.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh827362.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh830127.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh832516.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh832694.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh833717.patch [moved from src/patches/glibc/glibc-rh833716.patch with 100% similarity]
src/patches/glibc/glibc-rh837026.patch [deleted file]
src/patches/glibc/glibc-rh837695.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh837918.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh841787.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh843673.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh846342.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh847932.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh848082.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh849203.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh849651.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh852445.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh861167.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh863453.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh864322.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh929388.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh970992.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh989558-2.patch [new file with mode: 0644]
src/patches/glibc/glibc-rh989558.patch [new file with mode: 0644]

index ccbdb315881754bec78b90d4a58eae65b03c2bd0..9acbb111bbfa6c4d58a784e8138a51d318bcbbec 100644 (file)
--- a/lfs/glibc
+++ b/lfs/glibc
@@ -227,13 +227,37 @@ endif
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh795498.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh797094-1.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh797094-2.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804630.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804686.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh804689.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh806404.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808337.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh808545.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh809602.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh833716.patch
-       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837026.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh809726.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh823909.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh826149.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh827362.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh830127.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832516.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh832694.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh833717.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837695.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh837918.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh841787.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh843673.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh846342.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh847932.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh848082.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh849203.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh849651.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh852445.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh861167.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh863453.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh864322.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh929388.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh970992.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh989558.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc/glibc-rh989558-2.patch
 
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-resolv-stack_chk_fail.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/glibc-remove-ctors-dtors-output-sections.patch
diff --git a/src/patches/glibc/glibc-rh804630.patch b/src/patches/glibc/glibc-rh804630.patch
deleted file mode 100644 (file)
index 75dbe94..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-diff -rup c/resolv/res_send.c d/resolv/res_send.c
---- c/resolv/res_send.c        2012-01-01 05:16:32.000000000 -0700
-+++ d/resolv/res_send.c        2012-03-30 12:39:30.862467628 -0600
-@@ -409,6 +409,7 @@ __libc_res_nsend(res_state statp, const
-        */
-       if (EXT(statp).nsinit == 0) {
-               unsigned char map[MAXNS];
-+              unsigned int ext_total_nscount;
-               memset (map, MAXNS, sizeof (map));
-               for (n = 0; n < MAXNS; n++) {
-@@ -422,8 +423,9 @@ __libc_res_nsend(res_state statp, const
-                       }
-               }
-               n = statp->nscount;
--              if (statp->nscount > EXT(statp).nscount)
--                      for (n = EXT(statp).nscount, ns = 0;
-+              ext_total_nscount = EXT(statp).nscount + EXT(statp).nscount6;
-+              if (statp->nscount > ext_total_nscount)
-+                      for (n = ext_total_nscount, ns = 0;
-                            n < statp->nscount; n++) {
-                               while (ns < MAXNS
-                                      && EXT(statp).nsmap[ns] != MAXNS)
diff --git a/src/patches/glibc/glibc-rh804686.patch b/src/patches/glibc/glibc-rh804686.patch
new file mode 100644 (file)
index 0000000..292cd84
--- /dev/null
@@ -0,0 +1,87 @@
+--- a/resolv/res_query.c       2010-05-04 05:27:23.000000000 -0600
++++ a/resolv/res_query.c       2012-08-03 13:43:10.761506047 -0600
+@@ -122,6 +122,7 @@ __libc_res_nquery(res_state statp,
+                 int *resplen2)
+ {
+       HEADER *hp = (HEADER *) answer;
++      HEADER *hp2;
+       int n, use_malloc = 0;
+         u_int oflags = statp->_flags;
+@@ -239,26 +240,25 @@ __libc_res_nquery(res_state statp,
+         /* __libc_res_nsend might have reallocated the buffer.  */
+         hp = (HEADER *) *answerp;
+-      /* We simplify the following tests by assigning HP to HP2.  It
+-         is easy to verify that this is the same as ignoring all
+-         tests of HP2.  */
+-      HEADER *hp2 = answerp2 ? (HEADER *) *answerp2 : hp;
+-
+-      if (n < (int) sizeof (HEADER) && answerp2 != NULL
+-          && *resplen2 > (int) sizeof (HEADER))
++      /* We simplify the following tests by assigning HP to HP2 or
++         vice versa.  It is easy to verify that this is the same as
++         ignoring all tests of HP or HP2.  */
++      if (answerp2 == NULL || *resplen2 < (int) sizeof (HEADER))
+         {
+-          /* Special case of partial answer.  */
+-          assert (hp != hp2);
+-          hp = hp2;
++          hp2 = hp;
+         }
+-      else if (answerp2 != NULL && *resplen2 < (int) sizeof (HEADER)
+-               && n > (int) sizeof (HEADER))
++      else
+         {
+-          /* Special case of partial answer.  */
+-          assert (hp != hp2);
+-          hp2 = hp;
++          hp2 = (HEADER *) *answerp2;
++          if (n < (int) sizeof (HEADER))
++            {
++              hp = hp2;
++            }
+         }
++      /* Make sure both hp and hp2 are defined */
++      assert((hp != NULL) && (hp2 != NULL));
++
+       if ((hp->rcode != NOERROR || ntohs(hp->ancount) == 0)
+           && (hp2->rcode != NOERROR || ntohs(hp2->ancount) == 0)) {
+ #ifdef DEBUG
+--- a/resolv/res_send.c        2012-08-03 13:31:26.622168278 -0600
++++ a/resolv/res_send.c        2012-08-03 13:43:11.881501862 -0600
+@@ -549,7 +549,7 @@ __libc_res_nsend(res_state statp, const
+                                   ns, ansp, ansp2, nansp2, resplen2);
+                       if (n < 0)
+                               return (-1);
+-                      if (n == 0)
++                      if (n == 0 && (buf2 == NULL || *resplen2 == 0))
+                               goto next_ns;
+               } else {
+                       /* Use datagrams. */
+@@ -559,7 +559,7 @@ __libc_res_nsend(res_state statp, const
+                                   ansp2, nansp2, resplen2);
+                       if (n < 0)
+                               return (-1);
+-                      if (n == 0)
++                      if (n == 0 && (buf2 == NULL || *resplen2 == 0))
+                               goto next_ns;
+                       if (v_circuit)
+                         // XXX Check whether both requests failed or
+@@ -1275,10 +1275,14 @@ send_dg(res_state statp,
+                               (*thisresplenp > *thisanssizp)
+                               ? *thisanssizp : *thisresplenp);
+-                      if (recvresp1 || (buf2 != NULL && recvresp2))
++                      if (recvresp1 || (buf2 != NULL && recvresp2)) {
++                        *resplen2 = 0;
+                         return resplen;
++                      }
+                       if (buf2 != NULL)
+                         {
++                          /* No data from the first reply.  */
++                          resplen = 0;
+                           /* We are waiting for a possible second reply.  */
+                           if (hp->id == anhp->id)
+                             recvresp1 = 1;
diff --git a/src/patches/glibc/glibc-rh806404.patch b/src/patches/glibc/glibc-rh806404.patch
new file mode 100644 (file)
index 0000000..b78b903
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rup a/nss/getnssent.c b/nss/getnssent.c
+--- a/nss/getnssent.c  2004-12-13 14:48:34.000000000 -0700
++++ b/nss/getnssent.c  2012-03-23 13:46:54.639095121 -0600
+@@ -33,7 +33,7 @@ __nss_getent (getent_r_function func, vo
+       *buffer = malloc (*buffer_size);
+     }
+-  while (buffer != NULL
++  while (*buffer != NULL
+        && func (resbuf, *buffer, *buffer_size, &result, h_errnop) == ERANGE
+        && (h_errnop == NULL || *h_errnop == NETDB_INTERNAL))
+     {
diff --git a/src/patches/glibc/glibc-rh809726.patch b/src/patches/glibc/glibc-rh809726.patch
new file mode 100644 (file)
index 0000000..0f264c8
--- /dev/null
@@ -0,0 +1,89 @@
+diff -rup a/localedata/locales/fi_FI b/localedata/locales/fi_FI
+--- a/localedata/locales/fi_FI 2012-07-11 14:48:45.994749607 -0600
++++ b/localedata/locales/fi_FI 2012-07-11 14:50:20.003277477 -0600
+@@ -63,60 +63,65 @@ reorder-after <z>
+ <a-diaerisis>
+ <o-diaerisis>
+-reorder-after <U005A>
++reorder-after <U007A>
+ <U00E5> <a-ring>;<BAS>;<MIN>;IGNORE
+-<U00C5> <a-ring>;<BAS>;<CAP>;IGNORE
+ <U01FB> <a-ring>;<ACA>;<MIN>;IGNORE
+-<U01FA> <a-ring>;<ACA>;<CAP>;IGNORE
+ <U00E4> <a-diaerisis>;<BAS>;<MIN>;IGNORE
+-<U00C4> <a-diaerisis>;<BAS>;<CAP>;IGNORE
+ <U00E6> <a-diaerisis>;<REU>;<MIN>;IGNORE
+-<U00C6> <a-diaerisis>;<REU>;<CAP>;IGNORE
+ <U01FD> <a-diaerisis>;<U01FD>;<MIN>;IGNORE
+-<U01FC> <a-diaerisis>;<U01FD>;<CAP>;IGNORE
+ <U01E3> <a-diaerisis>;<MAC>;<MIN>;IGNORE
+-<U01E2> <a-diaerisis>;<MAC>;<CAP>;IGNORE
+ <U00F6> <o-diaerisis>;<BAS>;<MIN>;IGNORE
+-<U00D6> <o-diaerisis>;<BAS>;<CAP>;IGNORE
+ <U00F8> <o-diaerisis>;<U00D8>;<MIN>;IGNORE
+-<U00D8> <o-diaerisis>;<U00D8>;<CAP>;IGNORE
+ <U01FF> <o-diaerisis>;<U01FF>;<MIN>;IGNORE
+-<U01FE> <o-diaerisis>;<U01FF>;<CAP>;IGNORE
+ <U00F5> <o-diaerisis>;<TIL>;<MIN>;IGNORE
++reorder-after <U005A>
++<U00C5> <a-ring>;<BAS>;<CAP>;IGNORE
++<U01FA> <a-ring>;<ACA>;<CAP>;IGNORE
++<U00C4> <a-diaerisis>;<BAS>;<CAP>;IGNORE
++<U00C6> <a-diaerisis>;<REU>;<CAP>;IGNORE
++<U01FC> <a-diaerisis>;<U01FD>;<CAP>;IGNORE
++<U01E2> <a-diaerisis>;<MAC>;<CAP>;IGNORE
++<U00D6> <o-diaerisis>;<BAS>;<CAP>;IGNORE
++<U00D8> <o-diaerisis>;<U00D8>;<CAP>;IGNORE
++<U01FE> <o-diaerisis>;<U01FF>;<CAP>;IGNORE
+ <U00D5> <o-diaerisis>;<TIL>;<CAP>;IGNORE
+-reorder-after <U016A>
++reorder-after <U016B>
+ <U0076> <v>;<U0056>;<BAS>;<MIN>
+-<U0056> <v>;<U0056>;<BAS>;<CAP>
+ <U1E7D> <v>;<U0056>;<TIL>;<MIN>
+-<U1E7C> <v>;<U0056>;<TIL>;<CAP>
+ <U0077> <w>;<U0057>;<BAS>;<MIN>
+-<U0057> <w>;<U0057>;<BAS>;<CAP>
+ <U1E83> <w>;<U0057>;<ACA>;<MIN>
+-<U1E82> <w>;<U0057>;<ACA>;<CAP>
+ <U1E81> <w>;<U0057>;<GRA>;<MIN>
+-<U1E80> <w>;<U0057>;<GRA>;<CAP>
+ <U0175> <w>;<U0057>;<CIR>;<MIN>
+-<U0174> <w>;<U0057>;<CIR>;<CAP>
+ <U1E85> <w>;<U0057>;<REU>;<MIN>
+-<U1E84> <w>;<U0057>;<REU>;<CAP>
+ <U1E87> <w>;<U0057>;<PCT>;<MIN>
++reorder-after <U016A>
++<U0056> <v>;<U0056>;<BAS>;<CAP>
++<U1E7C> <v>;<U0056>;<TIL>;<CAP>
++<U0057> <w>;<U0057>;<BAS>;<CAP>
++<U1E82> <w>;<U0057>;<ACA>;<CAP>
++<U1E80> <w>;<U0057>;<GRA>;<CAP>
++<U0174> <w>;<U0057>;<CIR>;<CAP>
++<U1E84> <w>;<U0057>;<REU>;<CAP>
+ <U1E86> <w>;<U0057>;<PCT>;<CAP>
+ reorder-after <U00FF>
+ <U00FC> <y>;<DTT>;<MIN>;IGNORE
++reorder-after <U0178>
+ <U00DC> <y>;<DTT>;<CAP>;IGNORE
+ %  Present in iso14651_t1, but these definitions seem to have been
+ %  removed from latest iso14651 tables.
+-reorder-after <U0162>
++reorder-after <U0163>
+ <U00FE> "<t><h>";"<LIG><LIG>";"<MIN><MIN>";IGNORE
++reorder-after <U0162>
+ <U00DE> "<t><h>";"<LIG><LIG>";"<CAP><CAP>";IGNORE
+ reorder-after <U0064>
+ <U00F0> <d>;<PCL>;<MIN>;IGNORE
+-<U00D0> <d>;<PCL>;<CAP>;IGNORE
+ <U0111> <d>;<OBL>;<MIN>;IGNORE
++reorder-after <U0044>
++<U00D0> <d>;<PCL>;<CAP>;IGNORE
+ <U0110> <d>;<OBL>;<CAP>;IGNORE
+ reorder-end
diff --git a/src/patches/glibc/glibc-rh823909.patch b/src/patches/glibc/glibc-rh823909.patch
new file mode 100644 (file)
index 0000000..ed9c4c9
--- /dev/null
@@ -0,0 +1,25 @@
+diff --git a/iconvdata/ibm930.c b/iconvdata/ibm930.c
+index 25a9be0..6f758eb 100644
+--- a/iconvdata/ibm930.c
++++ b/iconvdata/ibm930.c
+@@ -162,7 +162,8 @@ enum
+       while (ch > rp2->end)                                                 \
+         ++rp2;                                                              \
+                                                                             \
+-      if (__builtin_expect (ch < rp2->start, 0)                             \
++      if (__builtin_expect (rp2->start == 0xffff, 0)                        \
++          || __builtin_expect (ch < rp2->start, 0)                          \
+           || (res = __ibm930db_to_ucs4[ch + rp2->idx],                      \
+               __builtin_expect (res, L'\1') == L'\0' && ch != '\0'))        \
+         {                                                                   \
+@@ -215,7 +216,8 @@ enum
+       while (ch > rp2->end)                                                 \
+         ++rp2;                                                              \
+                                                                             \
+-      if (__builtin_expect (ch < rp2->start, 0)                             \
++      if (__builtin_expect (rp2->start == 0xffff, 0)                        \
++          || __builtin_expect (ch < rp2->start, 0)                          \
+           || (cp = __ucs4_to_ibm930db[ch + rp2->idx],                       \
+               __builtin_expect (cp[0], L'\1')== L'\0' && ch != '\0'))       \
+         {                                                                   \
+
diff --git a/src/patches/glibc/glibc-rh826149.patch b/src/patches/glibc/glibc-rh826149.patch
new file mode 100644 (file)
index 0000000..805572b
--- /dev/null
@@ -0,0 +1,80 @@
+diff -Nrup a/posix/fnmatch.c b/posix/fnmatch.c
+--- a/posix/fnmatch.c  2012-05-25 12:37:26.566678872 -0400
++++ b/posix/fnmatch.c  2012-05-25 13:08:44.451972286 -0400
+@@ -333,6 +333,7 @@ fnmatch (pattern, string, flags)
+ # if HANDLE_MULTIBYTE
+   if (__builtin_expect (MB_CUR_MAX, 1) != 1)
+     {
++      const char *orig_pattern = pattern;
+       mbstate_t ps;
+       size_t n;
+       const char *p;
+@@ -356,10 +357,9 @@ fnmatch (pattern, string, flags)
+                                                alloca_used);
+         n = mbsrtowcs (wpattern, &p, n + 1, &ps);
+         if (__builtin_expect (n == (size_t) -1, 0))
+-          /* Something wrong.
+-             XXX Do we have to set `errno' to something which mbsrtows hasn't
+-             already done?  */
+-          return -1;
++          /* Something wrong: Fall back to single byte matching. */
++          goto try_singlebyte;
++
+         if (p)
+           {
+             memset (&ps, '\0', sizeof (ps));
+@@ -371,10 +371,8 @@ fnmatch (pattern, string, flags)
+       prepare_wpattern:
+         n = mbsrtowcs (NULL, &pattern, 0, &ps);
+         if (__builtin_expect (n == (size_t) -1, 0))
+-          /* Something wrong.
+-             XXX Do we have to set `errno' to something which mbsrtows hasn't
+-             already done?  */
+-          return -1;
++          /* Something wrong: Fall back to single byte matching. */
++          goto try_singlebyte;
+         if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0))
+           {
+             __set_errno (ENOMEM);
+@@ -401,14 +399,8 @@ fnmatch (pattern, string, flags)
+                                               alloca_used);
+         n = mbsrtowcs (wstring, &p, n + 1, &ps);
+         if (__builtin_expect (n == (size_t) -1, 0))
+-          {
+-            /* Something wrong.
+-               XXX Do we have to set `errno' to something which
+-               mbsrtows hasn't already done?  */
+-          free_return:
+-            free (wpattern_malloc);
+-            return -1;
+-          }
++          /* Something wrong: Fall back to single byte matching. */
++          goto free_and_try_singlebyte;
+         if (p)
+           {
+             memset (&ps, '\0', sizeof (ps));
+@@ -420,10 +412,8 @@ fnmatch (pattern, string, flags)
+       prepare_wstring:
+         n = mbsrtowcs (NULL, &string, 0, &ps);
+         if (__builtin_expect (n == (size_t) -1, 0))
+-          /* Something wrong.
+-             XXX Do we have to set `errno' to something which mbsrtows hasn't
+-             already done?  */
+-          goto free_return;
++          /* Something wrong: Fall back to single byte matching. */
++          goto free_and_try_singlebyte;
+         if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0))
+           {
+             free (wpattern_malloc);
+@@ -450,6 +440,11 @@ fnmatch (pattern, string, flags)
+       free (wpattern_malloc);
+       return res;
++
++      free_and_try_singlebyte:
++      free(wpattern_malloc);
++      try_singlebyte:
++      pattern = orig_pattern;
+     }
+ # endif  /* mbstate_t and mbsrtowcs or _LIBC.  */
diff --git a/src/patches/glibc/glibc-rh827362.patch b/src/patches/glibc/glibc-rh827362.patch
new file mode 100644 (file)
index 0000000..7e6d07e
--- /dev/null
@@ -0,0 +1,250 @@
+diff -pruN glibc-2.12-2-gc4ccff1/libio/Makefile glibc-2.12-2-gc4ccff1.fseek/libio/Makefile
+--- glibc-2.12-2-gc4ccff1/libio/Makefile       2010-05-04 16:57:23.000000000 +0530
++++ glibc-2.12-2-gc4ccff1.fseek/libio/Makefile 2012-09-05 17:28:08.699360413 +0530
+@@ -58,7 +58,7 @@ tests = tst_swprintf tst_wprintf tst_sws
+       tst-memstream1 tst-memstream2 \
+       tst-wmemstream1 tst-wmemstream2 \
+       bug-memstream1 bug-wmemstream1 \
+-      tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos
++      tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek
+ test-srcs = test-freopen
+ all: # Make this the default target; it will be defined in Rules.
+diff -pruN glibc-2.12-2-gc4ccff1/libio/tst-fseek.c glibc-2.12-2-gc4ccff1.fseek/libio/tst-fseek.c
+--- glibc-2.12-2-gc4ccff1/libio/tst-fseek.c    1970-01-01 05:30:00.000000000 +0530
++++ glibc-2.12-2-gc4ccff1.fseek/libio/tst-fseek.c      2012-09-05 17:27:33.606359692 +0530
+@@ -0,0 +1,153 @@
++/* Verify that fseek/ftell combination works for wide chars.
++
++   Copyright (C) 2012 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   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, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <locale.h>
++#include <errno.h>
++#include <wchar.h>
++#include <unistd.h>
++#include <string.h>
++
++/* Defined in test-skeleton.c.  */
++static int create_temp_file (const char *base, char **filename);
++
++
++static int
++do_seek_end (FILE *fp)
++{
++  long save;
++
++  if (fp == NULL)
++    {
++      printf ("do_seek_end: fopen: %s\n", strerror (errno));
++      return 1;
++    }
++
++  if (fputws (L"abc\n", fp) == -1)
++    {
++      printf ("do_seek_end: fputws: %s\n", strerror (errno));
++      return 1;
++    }
++
++  save = ftell (fp);
++  rewind (fp);
++
++  if (fseek (fp, 0, SEEK_END) == -1)
++    {
++      printf ("do_seek_end: fseek: %s\n", strerror (errno));
++      return 1;
++    }
++
++  if (save != ftell (fp))
++    {
++      printf ("save = %ld, ftell = %ld\n", save, ftell (fp));
++      return 1;
++    }
++
++  return 0;
++}
++
++int
++do_seek_set (FILE *fp)
++{
++  long save;
++
++  if (fputws (L"abc\n", fp) == -1)
++    {
++      printf ("seek_set: fputws: %s\n", strerror (errno));
++      return 1;
++    }
++
++  save = ftell (fp);
++
++  if (fputws (L"xyz\n", fp) == -1)
++    {
++      printf ("seek_set: fputws: %s\n", strerror (errno));
++      return 1;
++    }
++
++  if (fseek (fp, save, SEEK_SET) == -1)
++    {
++      printf ("seek_set: fseek: %s\n", strerror (errno));
++      return 1;
++    }
++
++  if (save != ftell (fp))
++    {
++      printf ("save = %ld, ftell = %ld\n", save, ftell (fp));
++      return 1;
++    }
++
++  return 0;
++}
++
++static int
++do_test (void)
++{
++  if (setlocale (LC_ALL, "en_US.utf8") == NULL)
++    {
++      printf ("Cannot set en_US.utf8 locale.\n");
++      exit (1);
++    }
++
++  int ret = 0;
++  char *filename;
++  int fd = create_temp_file ("tst-fseek.out", &filename);
++
++  if (fd == -1)
++    return 1;
++
++  FILE *fp = fdopen (fd, "w+");
++  if (fp == NULL)
++    {
++      printf ("seek_set: fopen: %s\n", strerror (errno));
++      close (fd);
++      return 1;
++    }
++
++  if (do_seek_set (fp))
++    {
++      printf ("SEEK_SET test failed\n");
++      ret = 1;
++    }
++
++  /* Reopen the file.  */
++  fclose (fp);
++  fp = fopen (filename, "w+");
++  if (fp == NULL)
++    {
++      printf ("seek_end: fopen: %s\n", strerror (errno));
++      return 1;
++    }
++
++  if (do_seek_end (fp))
++    {
++      printf ("SEEK_END test failed\n");
++      ret = 1;
++    }
++
++  fclose (fp);
++
++  return ret;
++}
++
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
+diff -pruN glibc-2.12-2-gc4ccff1/libio/wfileops.c glibc-2.12-2-gc4ccff1.fseek/libio/wfileops.c
+--- glibc-2.12-2-gc4ccff1/libio/wfileops.c     2010-05-04 16:57:23.000000000 +0530
++++ glibc-2.12-2-gc4ccff1.fseek/libio/wfileops.c       2012-09-05 17:27:33.608359685 +0530
+@@ -547,6 +547,55 @@ _IO_wfile_sync (fp)
+ }
+ INTDEF(_IO_wfile_sync)
++/* Adjust the internal buffer pointers to reflect the state in the external
++   buffer.  The content between fp->_IO_read_base and fp->_IO_read_ptr is
++   assumed to be converted and available in the range
++   fp->_wide_data->_IO_read_base and fp->_wide_data->_IO_read_end.  */
++static inline int
++adjust_wide_data (_IO_FILE *fp, bool do_convert)
++{
++  struct _IO_codecvt *cv = fp->_codecvt;
++
++  int clen = (*cv->__codecvt_do_encoding) (cv);
++
++  /* Take the easy way out for constant length encodings if we don't need to
++     convert.  */
++  if (!do_convert && clen > 0)
++    {
++      fp->_wide_data->_IO_read_end += ((fp->_IO_read_ptr - fp->_IO_read_base)
++                                     / clen);
++      goto done;
++    }
++
++  enum __codecvt_result status;
++  const char *read_stop = (const char *) fp->_IO_read_base;
++  do
++    {
++
++      fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
++      status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
++                                     fp->_IO_read_base, fp->_IO_read_ptr,
++                                     &read_stop,
++                                     fp->_wide_data->_IO_read_base,
++                                     fp->_wide_data->_IO_buf_end,
++                                     &fp->_wide_data->_IO_read_end);
++
++      /* Should we return EILSEQ?  */
++      if (__builtin_expect (status == __codecvt_error, 0))
++      {
++        fp->_flags |= _IO_ERR_SEEN;
++        return -1;
++      }
++    }
++  while (__builtin_expect (status == __codecvt_partial, 0));
++
++done:
++  /* Now seek to the end of the read buffer.  */
++  fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
++
++  return 0;
++}
++
+ _IO_off64_t
+ _IO_wfile_seekoff (fp, offset, dir, mode)
+      _IO_FILE *fp;
+@@ -695,6 +744,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode
+                    fp->_wide_data->_IO_buf_base);
+         _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
+                    fp->_wide_data->_IO_buf_base);
++
++        if (adjust_wide_data (fp, false))
++          goto dumb;
++
+         _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+         goto resync;
+       }
+@@ -735,6 +788,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode
+   _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
+            fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
+   _IO_wsetp (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
++
++  if (adjust_wide_data (fp, true))
++    goto dumb;
++
+   fp->_offset = result + count;
+   _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+   return offset;
diff --git a/src/patches/glibc/glibc-rh830127.patch b/src/patches/glibc/glibc-rh830127.patch
new file mode 100644 (file)
index 0000000..06dea73
--- /dev/null
@@ -0,0 +1,403 @@
+diff -Nrup a/stdio-common/bug22.c b/stdio-common/bug22.c
+--- a/stdio-common/bug22.c     2010-05-04 05:27:23.000000000 -0600
++++ b/stdio-common/bug22.c     2012-08-03 13:56:40.887829210 -0600
+@@ -1,12 +1,22 @@
+ /* BZ #5424 */
+ #include <stdio.h>
++#include <errno.h>
++/* INT_MAX + 1 */
+ #define N 2147483648
++/* (INT_MAX / 2) + 2 */
++#define N2 1073741825
++
++/* INT_MAX - 3 */
++#define N3 2147483644
++
+ #define STRINGIFY(S) #S
+ #define MAKE_STR(S) STRINGIFY(S)
+ #define SN MAKE_STR(N)
++#define SN2 MAKE_STR(N2)
++#define SN3 MAKE_STR(N3)
+ static int
+ do_test (void)
+@@ -20,13 +30,27 @@ do_test (void)
+       return 1;
+     }
+-  ret = fprintf (fp, "%" SN "d%" SN "d", 1, 1);
++  ret = fprintf (fp, "%" SN "d", 1);
++  printf ("ret = %d\n", ret);
++  if (ret != -1 || errno != EOVERFLOW)
++        return 1;
++
++  ret = fprintf (fp, "%." SN "d", 1);
++  printf ("ret = %d\n", ret);
++  if (ret != -1 || errno != EOVERFLOW)
++        return 1;
++
++  ret = fprintf (fp, "%." SN3 "d", 1);
++  printf ("ret = %d\n", ret);
++  if (ret != -1 || errno != EOVERFLOW)
++        return 1;
++  ret = fprintf (fp, "%" SN2 "d%" SN2 "d", 1, 1);
+   printf ("ret = %d\n", ret);
+-  return ret != -1;
++  return ret != -1 || errno != EOVERFLOW;
+ }
+-#define TIMEOUT 30
++#define TIMEOUT 60
+ #define TEST_FUNCTION do_test ()
+ #include "../test-skeleton.c"
+diff -Nrup a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
+--- a/stdio-common/printf-parse.h      2010-05-04 05:27:23.000000000 -0600
++++ b/stdio-common/printf-parse.h      2012-08-03 13:57:31.932638761 -0600
+@@ -14,9 +14,8 @@
+    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.  */
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
+ #include <printf.h>
+ #include <stdint.h>
+@@ -69,16 +68,27 @@ union printf_arg
+ #ifndef DONT_NEED_READ_INT
+ /* Read a simple integer from a string and update the string pointer.
+    It is assumed that the first character is a digit.  */
+-static unsigned int
++static int
+ read_int (const UCHAR_T * *pstr)
+ {
+-  unsigned int retval = **pstr - L_('0');
++  int retval = **pstr - L_('0');
+   while (ISDIGIT (*++(*pstr)))
+-    {
+-      retval *= 10;
+-      retval += **pstr - L_('0');
+-    }
++    if (retval >= 0)
++      {
++      if (INT_MAX / 10 < retval)
++        retval = -1;
++      else
++        {
++          int digit = **pstr - L_('0');
++
++          retval *= 10;
++          if (INT_MAX - digit < retval)
++            retval = -1;
++          else
++            retval += digit;
++        }
++      }
+   return retval;
+ }
+diff -Nrup a/stdio-common/printf-parsemb.c b/stdio-common/printf-parsemb.c
+--- a/stdio-common/printf-parsemb.c    2010-05-04 05:27:23.000000000 -0600
++++ b/stdio-common/printf-parsemb.c    2012-08-03 13:58:44.683366361 -0600
+@@ -13,9 +13,8 @@
+    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.  */
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
+ #include <ctype.h>
+ #include <limits.h>
+@@ -88,12 +87,15 @@ __parse_one_specmb (const UCHAR_T *forma
+       n = read_int (&format);
+-      if (n > 0 && *format == L_('$'))
++      if (n != 0 && *format == L_('$'))
+       /* Is positional parameter.  */
+       {
+         ++format;             /* Skip the '$'.  */
+-        spec->data_arg = n - 1;
+-        *max_ref_arg = MAX (*max_ref_arg, n);
++        if (n != -1)
++          {
++            spec->data_arg = n - 1;
++            *max_ref_arg = MAX (*max_ref_arg, n);
++          }
+       }
+       else
+       /* Oops; that was actually the width and/or 0 padding flag.
+@@ -161,10 +163,13 @@ __parse_one_specmb (const UCHAR_T *forma
+         /* The width argument might be found in a positional parameter.  */
+         n = read_int (&format);
+-        if (n > 0 && *format == L_('$'))
++        if (n != 0 && *format == L_('$'))
+           {
+-            spec->width_arg = n - 1;
+-            *max_ref_arg = MAX (*max_ref_arg, n);
++            if (n != -1)
++              {
++                spec->width_arg = n - 1;
++                *max_ref_arg = MAX (*max_ref_arg, n);
++              }
+             ++format;         /* Skip '$'.  */
+           }
+       }
+@@ -178,9 +183,13 @@ __parse_one_specmb (const UCHAR_T *forma
+       }
+     }
+   else if (ISDIGIT (*format))
+-    /* Constant width specification.  */
+-    spec->info.width = read_int (&format);
++    {
++      int n = read_int (&format);
++      /* Constant width specification.  */
++      if (n != -1)
++      spec->info.width = n;
++    }
+   /* Get the precision.  */
+   spec->prec_arg = -1;
+   /* -1 means none given; 0 means explicit 0.  */
+@@ -197,10 +206,13 @@ __parse_one_specmb (const UCHAR_T *forma
+           {
+             n = read_int (&format);
+-            if (n > 0 && *format == L_('$'))
++            if (n != 0 && *format == L_('$'))
+               {
+-                spec->prec_arg = n - 1;
+-                *max_ref_arg = MAX (*max_ref_arg, n);
++                if (n != -1)
++                  {
++                    spec->prec_arg = n - 1;
++                    *max_ref_arg = MAX (*max_ref_arg, n);
++                  }
+                 ++format;
+               }
+           }
+@@ -214,7 +226,12 @@ __parse_one_specmb (const UCHAR_T *forma
+           }
+       }
+       else if (ISDIGIT (*format))
+-      spec->info.prec = read_int (&format);
++      {
++        int n = read_int (&format);
++
++        if (n != -1)
++          spec->info.prec = n;
++      }
+       else
+       /* "%.?" is treated like "%.0?".  */
+       spec->info.prec = 0;
+@@ -295,9 +312,9 @@ __parse_one_specmb (const UCHAR_T *forma
+       /* We don't try to get the types for all arguments if the format
+        uses more than one.  The normal case is covered though.  If
+        the call returns -1 we continue with the normal specifiers.  */
+-      || (spec->ndata_args = (*__printf_arginfo_table[spec->info.spec])
+-        (&spec->info, 1, &spec->data_arg_type,
+-         &spec->size)) < 0)
++      || (int) (spec->ndata_args = (*__printf_arginfo_table[spec->info.spec])
++                                 (&spec->info, 1, &spec->data_arg_type,
++                                  &spec->size)) < 0)
+     {
+       /* Find the data argument types of a built-in spec.  */
+       spec->ndata_args = 1;
+diff -Nrup a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
+--- a/stdio-common/vfprintf.c  2012-08-03 13:31:26.605168350 -0600
++++ b/stdio-common/vfprintf.c  2012-08-03 14:09:26.836725512 -0600
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1991-2008, 2009   Free Software Foundation, Inc.
++/* Copyright (C) 1991-2012   Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -12,9 +12,8 @@
+    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.  */
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
+ #include <ctype.h>
+ #include <limits.h>
+@@ -67,10 +66,10 @@
+   do {                                                                              \
+     unsigned int _val = val;                                                \
+     assert ((unsigned int) done < (unsigned int) INT_MAX);                  \
+-    if (__builtin_expect ((unsigned int) INT_MAX - (unsigned int) done              \
+-                        < _val, 0))                                         \
++    if (__builtin_expect (INT_MAX - done < _val, 0))                        \
+       {                                                                             \
+       done = -1;                                                            \
++       __set_errno (EOVERFLOW);                                             \
+       goto all_done;                                                        \
+       }                                                                             \
+     done += _val;                                                           \
+@@ -141,12 +140,17 @@
+   do                                                                        \
+     {                                                                       \
+       assert ((size_t) done <= (size_t) INT_MAX);                           \
+-      if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len)               \
+-        || (size_t) INT_MAX - (size_t) done < (size_t) (Len))               \
++      if ((size_t) PUT (s, (String), (Len)) != (size_t) (Len))                      \
+       {                                                                     \
+         done = -1;                                                          \
+         goto all_done;                                                      \
+       }                                                                     \
++      if (__builtin_expect (INT_MAX - done < (Len), 0))                             \
++      {                                                                             \
++      done = -1;                                                            \
++       __set_errno (EOVERFLOW);                                             \
++      goto all_done;                                                        \
++      }                                                                             \
+       done += (Len);                                                        \
+     }                                                                       \
+   while (0)
+@@ -1435,10 +1439,21 @@ vfprintf (FILE *s, const CHAR_T *format,
+       const UCHAR_T *tmp;     /* Temporary value.  */
+       tmp = ++f;
+-      if (ISDIGIT (*tmp) && read_int (&tmp) && *tmp == L_('$'))
+-        /* The width comes from a positional parameter.  */
+-        goto do_positional;
++      if (ISDIGIT (*tmp))
++        {
++          int pos = read_int (&tmp);
++          if (pos == -1)
++            {
++              __set_errno (EOVERFLOW);
++              done = -1;
++              goto all_done;
++            }
++
++          if (pos && *tmp == L_('$'))
++            /* The width comes from a positional parameter.  */
++            goto do_positional;
++        }
+       width = va_arg (ap, int);
+       /* Negative width means left justified.  */
+@@ -1449,9 +1464,9 @@ vfprintf (FILE *s, const CHAR_T *format,
+           left = 1;
+         }
+-      if (__builtin_expect (width >= (size_t) -1 / sizeof (CHAR_T) - 32, 0))
++      if (__builtin_expect (width >= INT_MAX / sizeof (CHAR_T) - 32, 0))
+         {
+-          __set_errno (ERANGE);
++          __set_errno (EOVERFLOW);
+           done = -1;
+           goto all_done;
+         }
+@@ -1481,9 +1496,10 @@ vfprintf (FILE *s, const CHAR_T *format,
+     LABEL (width):
+       width = read_int (&f);
+-      if (__builtin_expect (width >= (size_t) -1 / sizeof (CHAR_T) - 32, 0))
++      if (__builtin_expect (width == -1
++                          || width >= INT_MAX / sizeof (CHAR_T) - 32, 0))
+       {
+-        __set_errno (ERANGE);
++        __set_errno (EOVERFLOW);
+         done = -1;
+         goto all_done;
+       }
+@@ -1518,10 +1534,21 @@ vfprintf (FILE *s, const CHAR_T *format,
+         const UCHAR_T *tmp;   /* Temporary value.  */
+         tmp = ++f;
+-        if (ISDIGIT (*tmp) && read_int (&tmp) > 0 && *tmp == L_('$'))
+-          /* The precision comes from a positional parameter.  */
+-          goto do_positional;
++        if (ISDIGIT (*tmp))
++          {
++            int pos = read_int (&tmp);
++
++            if (pos == -1)
++              {
++                __set_errno (EOVERFLOW);
++                done = -1;
++                goto all_done;
++              }
++            if (pos && *tmp == L_('$'))
++              /* The precision comes from a positional parameter.  */
++              goto do_positional;
++          }
+         prec = va_arg (ap, int);
+         /* If the precision is negative the precision is omitted.  */
+@@ -1529,15 +1556,26 @@ vfprintf (FILE *s, const CHAR_T *format,
+           prec = -1;
+       }
+       else if (ISDIGIT (*f))
+-      prec = read_int (&f);
++      {
++        prec = read_int (&f);
++
++        /* The precision was specified in this case as an extremely
++           large positive value.  */
++        if (prec == -1)
++          {
++            __set_errno (EOVERFLOW);
++            done = -1;
++            goto all_done;
++          }
++      }
+       else
+       prec = 0;
+       if (prec > width
+         && prec > sizeof (work_buffer) / sizeof (work_buffer[0]) - 32)
+       {
+-        if (__builtin_expect (prec >= (size_t) -1 / sizeof (CHAR_T) - 32, 0))
++        if (__builtin_expect (prec >= INT_MAX / sizeof (CHAR_T) - 32, 0))
+           {
+-            __set_errno (ERANGE);
++            __set_errno (EOVERFLOW);
+             done = -1;
+             goto all_done;
+           }
+@@ -1722,13 +1760,13 @@ do_positional:
+     nargs = MAX (nargs, max_ref_arg);
+     /* Calculate total size needed to represent a single argument across
+        all three argument-related arrays.  */
+-    bytes_per_arg = sizeof (*args_value) + sizeof (*args_size)
+-                    + sizeof (*args_type);
++    bytes_per_arg = (sizeof (*args_value) + sizeof (*args_size)
++                   + sizeof (*args_type));
+     /* Check for potential integer overflow.  */
+-    if (__builtin_expect (nargs > SIZE_MAX / bytes_per_arg, 0))
++    if (__builtin_expect (nargs > INT_MAX / bytes_per_arg, 0))
+       {
+-         __set_errno (ERANGE);
++       __set_errno (EOVERFLOW);
+          done = -1;
+          goto all_done;
+       }
+@@ -1746,6 +1784,8 @@ do_positional:
+           }
+       }
++    /* Set up the remaining two arrays to each point past the end of the
++       prior array, since space for all three has been allocated now.  */
+     args_size = &args_value[nargs].pa_int;
+     args_type = &args_size[nargs];
+     memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0',
diff --git a/src/patches/glibc/glibc-rh832516.patch b/src/patches/glibc/glibc-rh832516.patch
new file mode 100644 (file)
index 0000000..476af4b
--- /dev/null
@@ -0,0 +1,19 @@
+diff -Nrup a/locale/loadlocale.c b/locale/loadlocale.c
+--- a/locale/loadlocale.c      2010-05-04 07:27:23.000000000 -0400
++++ b/locale/loadlocale.c      2012-08-05 17:19:47.761384155 -0400
+@@ -170,7 +170,6 @@ _nl_load_locale (struct loaded_l10nfile 
+   int save_err;
+   int alloc = ld_mapped;
+-  file->decided = 1;
+   file->data = NULL;
+   fd = open_not_cancel_2 (file->filename, O_RDONLY);
+@@ -279,6 +278,7 @@ _nl_load_locale (struct loaded_l10nfile 
+   newdata->alloc = alloc;
+   file->data = newdata;
++  file->decided = 1;
+ }
+ void
diff --git a/src/patches/glibc/glibc-rh832694.patch b/src/patches/glibc/glibc-rh832694.patch
new file mode 100644 (file)
index 0000000..249afb5
--- /dev/null
@@ -0,0 +1,22 @@
+diff --git a/sysdeps/gnu/errlist.c b/sysdeps/gnu/errlist.c
+index e3d2faf..5437ff8 100644
+--- a/sysdeps/gnu/errlist.c
++++ b/sysdeps/gnu/errlist.c
+@@ -780,11 +780,12 @@ TRANS The user's disk quota was exceeded. */
+ #endif
+ #ifdef ESTALE
+ /*
+-TRANS Stale NFS file handle.  This indicates an internal confusion in the NFS
+-TRANS system which is due to file system rearrangements on the server host.
+-TRANS Repairing this condition usually requires unmounting and remounting
+-TRANS the NFS file system on the local host. */
+-    [ERR_REMAP (ESTALE)] = N_("Stale NFS file handle"),
++TRANS Stale file handle.  This indicates an internal confusion in the 
++TRANS file system which is due to file system rearrangements on the server host
++TRANS for NFS filesystems or corruption in other filesystems.
++TRANS Repairing this condition usually requires unmounting, possibly
++TRANS repairing and remounting the file system. */
++    [ERR_REMAP (ESTALE)] = N_("Stale file handle"),
+ # if ESTALE > ERR_MAX
+ # undef ERR_MAX
+ # define ERR_MAX ESTALE
diff --git a/src/patches/glibc/glibc-rh837026.patch b/src/patches/glibc/glibc-rh837026.patch
deleted file mode 100644 (file)
index 558ad4f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-diff -rup a/resolv/res_send.c b/resolv/res_send.c
---- a/resolv/res_send.c        2012-06-28 11:55:38.361886650 -0600
-+++ b/resolv/res_send.c        2012-06-28 11:51:38.253963687 -0600
-@@ -424,17 +424,15 @@ __libc_res_nsend(res_state statp, const
-               }
-               n = statp->nscount;
-               ext_total_nscount = EXT(statp).nscount + EXT(statp).nscount6;
--              if (statp->nscount > ext_total_nscount)
--                      for (n = ext_total_nscount, ns = 0;
--                           n < statp->nscount; n++) {
--                              while (ns < MAXNS
--                                     && EXT(statp).nsmap[ns] != MAXNS)
--                                      ns++;
--                              if (ns == MAXNS)
--                                      break;
--                              EXT(statp).nsmap[ns] = n;
--                              map[n] = ns++;
--                      }
-+              for (n = 0, ns = 0; n < statp->nscount - ext_total_nscount; n++) {
-+                      while (ns < MAXNS
-+                             && EXT(statp).nsmap[ns] != MAXNS)
-+                              ns++;
-+                      if (ns == MAXNS)
-+                              break;
-+                      EXT(statp).nsmap[ns] = n;
-+                      map[n] = ns++;
-+              }
-               EXT(statp).nscount = n;
-               for (ns = 0; ns < EXT(statp).nscount; ns++) {
-                       n = map[ns];
diff --git a/src/patches/glibc/glibc-rh837695.patch b/src/patches/glibc/glibc-rh837695.patch
new file mode 100644 (file)
index 0000000..03e1e02
--- /dev/null
@@ -0,0 +1,54 @@
+diff -rup a/nss/nsswitch.h b/nss/nsswitch.h
+--- a/nss/nsswitch.h   2010-05-04 05:27:23.000000000 -0600
++++ b/nss/nsswitch.h   2012-07-05 11:28:15.316585117 -0600
+@@ -182,4 +182,8 @@ extern int __nss_hostname_digits_dots (c
+                                      int *h_errnop);
+ libc_hidden_proto (__nss_hostname_digits_dots)
++/* Maximum number of aliases we allow.  */
++#define MAX_NR_ALIASES  48
++#define MAX_NR_ADDRS    48
++
+ #endif        /* nsswitch.h */
+Only in b/nss: nsswitch.h.orig
+diff -rup a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
+--- a/resolv/nss_dns/dns-host.c        2012-07-05 11:27:39.298760961 -0600
++++ b/resolv/nss_dns/dns-host.c        2012-07-05 11:28:15.317585112 -0600
+@@ -89,10 +89,6 @@
+ #define RESOLVSORT
+-/* Maximum number of aliases we allow.  */
+-#define MAX_NR_ALIASES        48
+-#define MAX_NR_ADDRS  48
+-
+ #if PACKETSZ > 65536
+ # define MAXPACKET    PACKETSZ
+ #else
+Only in b/resolv/nss_dns: dns-host.c.orig
+diff -rup a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
+--- a/sysdeps/posix/getaddrinfo.c      2012-07-05 11:27:39.284761028 -0600
++++ b/sysdeps/posix/getaddrinfo.c      2012-07-05 14:15:39.785546125 -0600
+@@ -565,7 +565,10 @@ gaih_inet (const char *name, const struc
+            IPv6 scope ids. */
+         if (req->ai_family == AF_INET)
+           {
+-            size_t tmpbuflen = 512;
++              /* Add room for struct host_data in resolv/nss_dns/dns-host.c */
++              size_t tmpbuflen = 512 + (MAX_NR_ALIASES+MAX_NR_ADDRS+1)*sizeof(char*)
++                                  + 16 * sizeof(char);
++
+             assert (tmpbuf == NULL);
+             tmpbuf = alloca_account (tmpbuflen, alloca_used);
+             int rc;
+@@ -807,7 +810,7 @@ gaih_inet (const char *name, const struc
+         old_res_options = _res.options;
+         _res.options &= ~RES_USE_INET6;
+-        size_t tmpbuflen = 1024;
++        size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
+         malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
+         assert (tmpbuf == NULL);
+         if (!malloc_tmpbuf)
+Only in b/sysdeps/posix: getaddrinfo.c.orig
+Only in b/sysdeps/posix: getaddrinfo.c.rej
diff --git a/src/patches/glibc/glibc-rh837918.patch b/src/patches/glibc/glibc-rh837918.patch
new file mode 100644 (file)
index 0000000..924d83d
--- /dev/null
@@ -0,0 +1,7183 @@
+diff -Nrup a/math/libm-test.inc b/math/libm-test.inc
+--- a/math/libm-test.inc       2010-05-04 05:27:23.000000000 -0600
++++ b/math/libm-test.inc       2012-08-06 09:54:00.821929695 -0600
+@@ -2018,6 +2018,142 @@ cos_test (void)
+ static void
++cos_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cos) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cos_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (cos, 1, 0.5403023058681397174009366074429766037323L);
++      TEST_f_f (cos, 2, -0.4161468365471423869975682295007621897660L);
++      TEST_f_f (cos, 3, -0.9899924966004454572715727947312613023937L);
++      TEST_f_f (cos, 4, -0.6536436208636119146391681830977503814241L);
++      TEST_f_f (cos, 5, 0.2836621854632262644666391715135573083344L);
++      TEST_f_f (cos, 6, 0.9601702866503660205456522979229244054519L);
++      TEST_f_f (cos, 7, 0.7539022543433046381411975217191820122183L);
++      TEST_f_f (cos, 8, -0.1455000338086135258688413818311946826093L);
++      TEST_f_f (cos, 9, -0.9111302618846769883682947111811653112463L);
++      TEST_f_f (cos, 10, -0.8390715290764524522588639478240648345199L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cos_tonearest);
++}
++
++
++static void
++cos_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cos) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cos_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (cos, 1, 0.5403023058681397174009366074429766037323L);
++      TEST_f_f (cos, 2, -0.4161468365471423869975682295007621897660L);
++      TEST_f_f (cos, 3, -0.9899924966004454572715727947312613023937L);
++      TEST_f_f (cos, 4, -0.6536436208636119146391681830977503814241L);
++      TEST_f_f (cos, 5, 0.2836621854632262644666391715135573083344L);
++      TEST_f_f (cos, 6, 0.9601702866503660205456522979229244054519L);
++      TEST_f_f (cos, 7, 0.7539022543433046381411975217191820122183L);
++      TEST_f_f (cos, 8, -0.1455000338086135258688413818311946826093L);
++      TEST_f_f (cos, 9, -0.9111302618846769883682947111811653112463L);
++      TEST_f_f (cos, 10, -0.8390715290764524522588639478240648345199L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cos_towardzero);
++}
++
++
++static void
++cos_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cos) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cos_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (cos, 1, 0.5403023058681397174009366074429766037323L);
++      TEST_f_f (cos, 2, -0.4161468365471423869975682295007621897660L);
++      TEST_f_f (cos, 3, -0.9899924966004454572715727947312613023937L);
++      TEST_f_f (cos, 4, -0.6536436208636119146391681830977503814241L);
++      TEST_f_f (cos, 5, 0.2836621854632262644666391715135573083344L);
++      TEST_f_f (cos, 6, 0.9601702866503660205456522979229244054519L);
++      TEST_f_f (cos, 7, 0.7539022543433046381411975217191820122183L);
++      TEST_f_f (cos, 8, -0.1455000338086135258688413818311946826093L);
++      TEST_f_f (cos, 9, -0.9111302618846769883682947111811653112463L);
++      TEST_f_f (cos, 10, -0.8390715290764524522588639478240648345199L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cos_downward);
++}
++
++
++static void
++cos_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cos) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cos_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (cos, 1, 0.5403023058681397174009366074429766037323L);
++      TEST_f_f (cos, 2, -0.4161468365471423869975682295007621897660L);
++      TEST_f_f (cos, 3, -0.9899924966004454572715727947312613023937L);
++      TEST_f_f (cos, 4, -0.6536436208636119146391681830977503814241L);
++      TEST_f_f (cos, 5, 0.2836621854632262644666391715135573083344L);
++      TEST_f_f (cos, 6, 0.9601702866503660205456522979229244054519L);
++      TEST_f_f (cos, 7, 0.7539022543433046381411975217191820122183L);
++      TEST_f_f (cos, 8, -0.1455000338086135258688413818311946826093L);
++      TEST_f_f (cos, 9, -0.9111302618846769883682947111811653112463L);
++      TEST_f_f (cos, 10, -0.8390715290764524522588639478240648345199L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cos_upward);
++}
++
++
++static void
+ cosh_test (void)
+ {
+   errno = 0;
+@@ -2043,6 +2179,114 @@ cosh_test (void)
+ static void
++cosh_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cosh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cosh_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (cosh, 22, 1792456423.065795780980053377632656584997L);
++      TEST_f_f (cosh, 23, 4872401723.124451300068625740569997090344L);
++      TEST_f_f (cosh, 24, 13244561064.92173614708845674912733665919L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cosh_tonearest);
++}
++
++
++static void
++cosh_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cosh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cosh_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (cosh, 22, 1792456423.065795780980053377632656584997L);
++      TEST_f_f (cosh, 23, 4872401723.124451300068625740569997090344L);
++      TEST_f_f (cosh, 24, 13244561064.92173614708845674912733665919L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cosh_towardzero);
++}
++
++
++static void
++cosh_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cosh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cosh_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (cosh, 22, 1792456423.065795780980053377632656584997L);
++      TEST_f_f (cosh, 23, 4872401723.124451300068625740569997090344L);
++      TEST_f_f (cosh, 24, 13244561064.92173614708845674912733665919L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cosh_downward);
++}
++
++
++static void
++cosh_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(cosh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (cosh_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (cosh, 22, 1792456423.065795780980053377632656584997L);
++      TEST_f_f (cosh, 23, 4872401723.124451300068625740569997090344L);
++      TEST_f_f (cosh, 24, 13244561064.92173614708845674912733665919L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (cosh_upward);
++}
++
++
++static void
+ cpow_test (void)
+ {
+   errno = 0;
+@@ -2527,6 +2771,114 @@ exp_test (void)
+ static void
++exp_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(exp) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (exp_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (exp, 1, M_El);
++      TEST_f_f (exp, 2, M_E2l);
++      TEST_f_f (exp, 3, M_E3l);
++    }
++
++  fesetround (save_round_mode);
++
++  END (exp_tonearest);
++}
++
++
++static void
++exp_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(exp) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (exp_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (exp, 1, M_El);
++      TEST_f_f (exp, 2, M_E2l);
++      TEST_f_f (exp, 3, M_E3l);
++    }
++
++  fesetround (save_round_mode);
++
++  END (exp_towardzero);
++}
++
++
++static void
++exp_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(exp) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (exp_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (exp, 1, M_El);
++      TEST_f_f (exp, 2, M_E2l);
++      TEST_f_f (exp, 3, M_E3l);
++    }
++
++  fesetround (save_round_mode);
++
++  END (exp_downward);
++}
++
++
++static void
++exp_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(exp) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (exp_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (exp, 1, M_El);
++      TEST_f_f (exp, 2, M_E2l);
++      TEST_f_f (exp, 3, M_E3l);
++    }
++
++  fesetround (save_round_mode);
++
++  END (exp_upward);
++}
++
++
++static void
+ exp10_test (void)
+ {
+   errno = 0;
+@@ -4848,22 +5200,127 @@ pow_test (void)
+   END (pow);
+ }
++
+ static void
+-remainder_test (void)
++pow_test_tonearest (void)
+ {
++  int save_round_mode;
+   errno = 0;
+-  FUNC(remainder) (1.625, 1.0);
++  FUNC(pow) (0, 0);
+   if (errno == ENOSYS)
+     /* Function not implemented.  */
+     return;
+-  START (remainder);
++  START (pow_tonearest);
+-  TEST_ff_f (remainder, 1, 0, nan_value, INVALID_EXCEPTION);
+-  TEST_ff_f (remainder, 1, minus_zero, nan_value, INVALID_EXCEPTION);
+-  TEST_ff_f (remainder, plus_infty, 1, nan_value, INVALID_EXCEPTION);
+-  TEST_ff_f (remainder, minus_infty, 1, nan_value, INVALID_EXCEPTION);
+-  TEST_ff_f (remainder, nan_value, nan_value, nan_value);
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_ff_f (pow, 1.0625L, 1.125L, 1.070582293028761362162622578677070098674L);
++      TEST_ff_f (pow, 1.5L, 1.03125L, 1.519127098714743184071644334163037684948L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (pow_tonearest);
++}
++
++
++static void
++pow_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(pow) (0, 0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (pow_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_ff_f (pow, 1.0625L, 1.125L, 1.070582293028761362162622578677070098674L);
++      TEST_ff_f (pow, 1.5L, 1.03125L, 1.519127098714743184071644334163037684948L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (pow_towardzero);
++}
++
++
++static void
++pow_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(pow) (0, 0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (pow_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_ff_f (pow, 1.0625L, 1.125L, 1.070582293028761362162622578677070098674L);
++      TEST_ff_f (pow, 1.5L, 1.03125L, 1.519127098714743184071644334163037684948L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (pow_downward);
++}
++
++
++static void
++pow_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(pow) (0, 0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (pow_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_ff_f (pow, 1.0625L, 1.125L, 1.070582293028761362162622578677070098674L);
++      TEST_ff_f (pow, 1.5L, 1.03125L, 1.519127098714743184071644334163037684948L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (pow_upward);
++}
++
++
++static void
++remainder_test (void)
++{
++  errno = 0;
++  FUNC(remainder) (1.625, 1.0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (remainder);
++
++  TEST_ff_f (remainder, 1, 0, nan_value, INVALID_EXCEPTION);
++  TEST_ff_f (remainder, 1, minus_zero, nan_value, INVALID_EXCEPTION);
++  TEST_ff_f (remainder, plus_infty, 1, nan_value, INVALID_EXCEPTION);
++  TEST_ff_f (remainder, minus_infty, 1, nan_value, INVALID_EXCEPTION);
++  TEST_ff_f (remainder, nan_value, nan_value, nan_value);
+   TEST_ff_f (remainder, 1.625, 1.0, -0.375);
+   TEST_ff_f (remainder, -1.625, 1.0, 0.375);
+@@ -5545,6 +6002,7 @@ sin_test (void)
+ #ifdef TEST_DOUBLE
+   TEST_f_f (sin, 0.80190127184058835, 0.71867942238767868);
++  TEST_f_f (sin, 2.522464e-1, 2.4957989804940911e-1);
+ #endif
+   END (sin);
+@@ -5553,6 +6011,142 @@ sin_test (void)
+ static void
++sin_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sin) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sin_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (sin, 1, 0.8414709848078965066525023216302989996226L);
++      TEST_f_f (sin, 2, 0.9092974268256816953960198659117448427023L);
++      TEST_f_f (sin, 3, 0.1411200080598672221007448028081102798469L);
++      TEST_f_f (sin, 4, -0.7568024953079282513726390945118290941359L);
++      TEST_f_f (sin, 5, -0.9589242746631384688931544061559939733525L);
++      TEST_f_f (sin, 6, -0.2794154981989258728115554466118947596280L);
++      TEST_f_f (sin, 7, 0.6569865987187890903969990915936351779369L);
++      TEST_f_f (sin, 8, 0.9893582466233817778081235982452886721164L);
++      TEST_f_f (sin, 9, 0.4121184852417565697562725663524351793439L);
++      TEST_f_f (sin, 10, -0.5440211108893698134047476618513772816836L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sin_tonearest);
++}
++
++
++static void
++sin_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sin) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sin_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (sin, 1, 0.8414709848078965066525023216302989996226L);
++      TEST_f_f (sin, 2, 0.9092974268256816953960198659117448427023L);
++      TEST_f_f (sin, 3, 0.1411200080598672221007448028081102798469L);
++      TEST_f_f (sin, 4, -0.7568024953079282513726390945118290941359L);
++      TEST_f_f (sin, 5, -0.9589242746631384688931544061559939733525L);
++      TEST_f_f (sin, 6, -0.2794154981989258728115554466118947596280L);
++      TEST_f_f (sin, 7, 0.6569865987187890903969990915936351779369L);
++      TEST_f_f (sin, 8, 0.9893582466233817778081235982452886721164L);
++      TEST_f_f (sin, 9, 0.4121184852417565697562725663524351793439L);
++      TEST_f_f (sin, 10, -0.5440211108893698134047476618513772816836L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sin_towardzero);
++}
++
++
++static void
++sin_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sin) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sin_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (sin, 1, 0.8414709848078965066525023216302989996226L);
++      TEST_f_f (sin, 2, 0.9092974268256816953960198659117448427023L);
++      TEST_f_f (sin, 3, 0.1411200080598672221007448028081102798469L);
++      TEST_f_f (sin, 4, -0.7568024953079282513726390945118290941359L);
++      TEST_f_f (sin, 5, -0.9589242746631384688931544061559939733525L);
++      TEST_f_f (sin, 6, -0.2794154981989258728115554466118947596280L);
++      TEST_f_f (sin, 7, 0.6569865987187890903969990915936351779369L);
++      TEST_f_f (sin, 8, 0.9893582466233817778081235982452886721164L);
++      TEST_f_f (sin, 9, 0.4121184852417565697562725663524351793439L);
++      TEST_f_f (sin, 10, -0.5440211108893698134047476618513772816836L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sin_downward);
++}
++
++
++static void
++sin_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sin) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sin_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (sin, 1, 0.8414709848078965066525023216302989996226L);
++      TEST_f_f (sin, 2, 0.9092974268256816953960198659117448427023L);
++      TEST_f_f (sin, 3, 0.1411200080598672221007448028081102798469L);
++      TEST_f_f (sin, 4, -0.7568024953079282513726390945118290941359L);
++      TEST_f_f (sin, 5, -0.9589242746631384688931544061559939733525L);
++      TEST_f_f (sin, 6, -0.2794154981989258728115554466118947596280L);
++      TEST_f_f (sin, 7, 0.6569865987187890903969990915936351779369L);
++      TEST_f_f (sin, 8, 0.9893582466233817778081235982452886721164L);
++      TEST_f_f (sin, 9, 0.4121184852417565697562725663524351793439L);
++      TEST_f_f (sin, 10, -0.5440211108893698134047476618513772816836L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sin_upward);
++}
++
++
++static void
+ sincos_test (void)
+ {
+   FLOAT sin_res, cos_res;
+@@ -5610,6 +6204,115 @@ sinh_test (void)
+   END (sinh);
+ }
++
++static void
++sinh_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sinh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sinh_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (sinh, 22, 1792456423.065795780701106568345764104225L);
++      TEST_f_f (sinh, 23, 4872401723.124451299966006944252978187305L);
++      TEST_f_f (sinh, 24, 13244561064.92173614705070540368454568168L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sinh_tonearest);
++}
++
++
++static void
++sinh_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sinh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sinh_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (sinh, 22, 1792456423.065795780701106568345764104225L);
++      TEST_f_f (sinh, 23, 4872401723.124451299966006944252978187305L);
++      TEST_f_f (sinh, 24, 13244561064.92173614705070540368454568168L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sinh_towardzero);
++}
++
++
++static void
++sinh_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sinh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sinh_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (sinh, 22, 1792456423.065795780701106568345764104225L);
++      TEST_f_f (sinh, 23, 4872401723.124451299966006944252978187305L);
++      TEST_f_f (sinh, 24, 13244561064.92173614705070540368454568168L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sinh_downward);
++}
++
++
++static void
++sinh_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(sinh) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (sinh_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (sinh, 22, 1792456423.065795780701106568345764104225L);
++      TEST_f_f (sinh, 23, 4872401723.124451299966006944252978187305L);
++      TEST_f_f (sinh, 24, 13244561064.92173614705070540368454568168L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (sinh_upward);
++}
++
++
+ static void
+ sqrt_test (void)
+ {
+@@ -5673,6 +6376,143 @@ tan_test (void)
+   END (tan);
+ }
++
++static void
++tan_test_tonearest (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(tan) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (tan_tonearest);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TONEAREST))
++    {
++      TEST_f_f (tan, 1, 1.5574077246549022305069748074583601730873L);
++      TEST_f_f (tan, 2, -2.1850398632615189916433061023136825434320L);
++      TEST_f_f (tan, 3, -0.1425465430742778052956354105339134932261L);
++      TEST_f_f (tan, 4, 1.1578212823495775831373424182673239231198L);
++      TEST_f_f (tan, 5, -3.3805150062465856369827058794473439087096L);
++      TEST_f_f (tan, 6, -0.2910061913847491570536995888681755428312L);
++      TEST_f_f (tan, 7, 0.8714479827243187364564508896003135663222L);
++      TEST_f_f (tan, 8, -6.7997114552203786999252627596086333648814L);
++      TEST_f_f (tan, 9, -0.4523156594418098405903708757987855343087L);
++      TEST_f_f (tan, 10, 0.6483608274590866712591249330098086768169L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (tan_tonearest);
++}
++
++
++static void
++tan_test_towardzero (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(tan) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (tan_towardzero);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_TOWARDZERO))
++    {
++      TEST_f_f (tan, 1, 1.5574077246549022305069748074583601730873L);
++      TEST_f_f (tan, 2, -2.1850398632615189916433061023136825434320L);
++      TEST_f_f (tan, 3, -0.1425465430742778052956354105339134932261L);
++      TEST_f_f (tan, 4, 1.1578212823495775831373424182673239231198L);
++      TEST_f_f (tan, 5, -3.3805150062465856369827058794473439087096L);
++      TEST_f_f (tan, 6, -0.2910061913847491570536995888681755428312L);
++      TEST_f_f (tan, 7, 0.8714479827243187364564508896003135663222L);
++      TEST_f_f (tan, 8, -6.7997114552203786999252627596086333648814L);
++      TEST_f_f (tan, 9, -0.4523156594418098405903708757987855343087L);
++      TEST_f_f (tan, 10, 0.6483608274590866712591249330098086768169L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (tan_towardzero);
++}
++
++
++static void
++tan_test_downward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(tan) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (tan_downward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_DOWNWARD))
++    {
++      TEST_f_f (tan, 1, 1.5574077246549022305069748074583601730873L);
++      TEST_f_f (tan, 2, -2.1850398632615189916433061023136825434320L);
++      TEST_f_f (tan, 3, -0.1425465430742778052956354105339134932261L);
++      TEST_f_f (tan, 4, 1.1578212823495775831373424182673239231198L);
++      TEST_f_f (tan, 5, -3.3805150062465856369827058794473439087096L);
++      TEST_f_f (tan, 6, -0.2910061913847491570536995888681755428312L);
++      TEST_f_f (tan, 7, 0.8714479827243187364564508896003135663222L);
++      TEST_f_f (tan, 8, -6.7997114552203786999252627596086333648814L);
++      TEST_f_f (tan, 9, -0.4523156594418098405903708757987855343087L);
++      TEST_f_f (tan, 10, 0.6483608274590866712591249330098086768169L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (tan_downward);
++}
++
++
++static void
++tan_test_upward (void)
++{
++  int save_round_mode;
++  errno = 0;
++  FUNC(tan) (0);
++  if (errno == ENOSYS)
++    /* Function not implemented.  */
++    return;
++
++  START (tan_upward);
++
++  save_round_mode = fegetround ();
++
++  if (!fesetround (FE_UPWARD))
++    {
++      TEST_f_f (tan, 1, 1.5574077246549022305069748074583601730873L);
++      TEST_f_f (tan, 2, -2.1850398632615189916433061023136825434320L);
++      TEST_f_f (tan, 3, -0.1425465430742778052956354105339134932261L);
++      TEST_f_f (tan, 4, 1.1578212823495775831373424182673239231198L);
++      TEST_f_f (tan, 5, -3.3805150062465856369827058794473439087096L);
++      TEST_f_f (tan, 6, -0.2910061913847491570536995888681755428312L);
++      TEST_f_f (tan, 7, 0.8714479827243187364564508896003135663222L);
++      TEST_f_f (tan, 8, -6.7997114552203786999252627596086333648814L);
++      TEST_f_f (tan, 9, -0.4523156594418098405903708757987855343087L);
++      TEST_f_f (tan, 10, 0.6483608274590866712591249330098086768169L);
++    }
++
++  fesetround (save_round_mode);
++
++  END (tan_upward);
++}
++
++
+ static void
+ tanh_test (void)
+ {
+@@ -6171,20 +7011,44 @@ main (int argc, char **argv)
+   atan_test ();
+   atan2_test ();
+   cos_test ();
++  cos_test_tonearest ();
++  cos_test_towardzero ();
++  cos_test_downward ();
++  cos_test_upward ();
+   sin_test ();
++  sin_test_tonearest ();
++  sin_test_towardzero ();
++  sin_test_downward ();
++  sin_test_upward ();
+   sincos_test ();
+   tan_test ();
++  tan_test_tonearest ();
++  tan_test_towardzero ();
++  tan_test_downward ();
++  tan_test_upward ();
+   /* Hyperbolic functions:  */
+   acosh_test ();
+   asinh_test ();
+   atanh_test ();
+   cosh_test ();
++  cosh_test_tonearest ();
++  cosh_test_towardzero ();
++  cosh_test_downward ();
++  cosh_test_upward ();
+   sinh_test ();
++  sinh_test_tonearest ();
++  sinh_test_towardzero ();
++  sinh_test_downward ();
++  sinh_test_upward ();
+   tanh_test ();
+   /* Exponential and logarithmic functions:  */
+   exp_test ();
++  exp_test_tonearest ();
++  exp_test_towardzero ();
++  exp_test_downward ();
++  exp_test_upward ();
+   exp10_test ();
+   exp2_test ();
+   expm1_test ();
+@@ -6207,6 +7071,10 @@ main (int argc, char **argv)
+   fabs_test ();
+   hypot_test ();
+   pow_test ();
++  pow_test_tonearest ();
++  pow_test_towardzero ();
++  pow_test_downward ();
++  pow_test_upward ();
+   sqrt_test ();
+   /* Error and gamma functions:  */
+diff -Nrup a/math/math_private.h b/math/math_private.h
+--- a/math/math_private.h      2010-05-04 05:27:23.000000000 -0600
++++ b/math/math_private.h      2012-08-06 09:54:00.821929695 -0600
+@@ -357,4 +357,41 @@ extern void __docos (double __x, double
+ #define math_force_eval(x) __asm __volatile ("" : : "m" (x))
+ #endif
++
++/* The standards only specify one variant of the fenv.h interfaces.
++   But at least for some architectures we can be more efficient if we
++   know what operations are going to be performed.  Therefore we
++   define additional interfaces.  By default they refer to the normal
++   interfaces.  */
++#define libc_fegetround() fegetround ()
++#define libc_fegetroundf() fegetround ()
++#define libc_fegetroundl() fegetround ()
++
++#define libc_fesetround(r) (void) fesetround (r)
++#define libc_fesetroundf(r) (void) fesetround (r)
++#define libc_fesetroundl(r) (void) fesetround (r)
++
++#define libc_feholdexcept(e) (void) feholdexcept (e)
++#define libc_feholdexceptf(e) (void) feholdexcept (e)
++#define libc_feholdexceptl(e) (void) feholdexcept (e)
++
++#define libc_feholdexcept_setround(e, r) \
++  do { feholdexcept (e); fesetround (r); } while (0)
++#define libc_feholdexcept_setroundf(e, r) \
++  do { feholdexcept (e); fesetround (r); } while (0)
++#define libc_feholdexcept_setroundl(e, r) \
++  do { feholdexcept (e); fesetround (r); } while (0)
++
++#define libc_fetestexcept(e) fetestexcept (e)
++#define libc_fetestexceptf(e) fetestexcept (e)
++#define libc_fetestexceptl(e) fetestexcept (e)
++
++#define libc_fesetenv(e) (void) fesetenv (e)
++#define libc_fesetenvf(e) (void) fesetenv (e)
++#define libc_fesetenvl(e) (void) fesetenv (e)
++
++#define libc_feupdateenv(e) (void) feupdateenv (e)
++#define libc_feupdateenvf(e) (void) feupdateenv (e)
++#define libc_feupdateenvl(e) (void) feupdateenv (e)
++
+ #endif /* _MATH_PRIVATE_H_ */
+diff -Nrup a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
+--- a/sysdeps/i386/fpu/libm-test-ulps  2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/i386/fpu/libm-test-ulps  2012-08-06 11:29:16.370874961 -0600
+@@ -9,18 +9,12 @@ ldouble: 1
+ Test "asin (-0.5) == -pi/6":
+ ildouble: 1
+ ldouble: 1
+-Test "asin (-1.0) == -pi/2":
+-ildouble: 1
+-ldouble: 1
+ Test "asin (0.5) == pi/6":
+ ildouble: 1
+ ldouble: 1
+ Test "asin (0.75) == 0.848062078981481008052944338998418080":
+ ildouble: 1
+ ldouble: 1
+-Test "asin (1.0) == pi/2":
+-ildouble: 1
+-ldouble: 1
+ # atanh
+ Test "atanh (0.75) == 0.972955074527656652552676371721589865":
+@@ -35,20 +29,6 @@ ildouble: 2
+ ldouble: 2
+ # cacosh
+-Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 9
+-idouble: 1
+-ifloat: 9
+-ildouble: 6
+-ldouble: 6
+-Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 4
+-idouble: 1
+-ifloat: 4
+-ildouble: 1
+-ldouble: 1
+ Test "Real part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i":
+ ildouble: 1
+ ldouble: 1
+@@ -124,8 +104,6 @@ ldouble: 1
+ Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+ float: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+ double: 1
+ idouble: 1
+@@ -149,9 +127,7 @@ float: 1
+ idouble: 1
+ ifloat: 1
+ Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ # cexp
+@@ -186,8 +162,6 @@ ifloat: 1
+ Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ double: 1
+ idouble: 1
+-ildouble: 1
+-ldouble: 1
+ Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+ double: 1
+ float: 1
+@@ -262,27 +236,175 @@ ifloat: 1
+ # cos
+ Test "cos (M_PI_6l * 2.0) == 0.5":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ Test "cos (M_PI_6l * 4.0) == -0.5":
+ double: 2
+ float: 1
+ idouble: 2
+ ifloat: 1
++
++# cos_downward
++Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (10) == -0.8390715290764524522588639478240648345199":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "cos_downward (3) == -0.9899924966004454572715727947312613023937":
++double: 1
++idouble: 1
++Test "cos_downward (4) == -0.6536436208636119146391681830977503814241":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_downward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (8) == -0.1455000338086135258688413818311946826093":
++ildouble: 1
++ldouble: 1
++Test "cos_downward (9) == -0.9111302618846769883682947111811653112463":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# cos_tonearest
++Test "cos_tonearest (8) == -0.1455000338086135258688413818311946826093":
++ildouble: 1
++ldouble: 1
++Test "cos_tonearest (9) == -0.9111302618846769883682947111811653112463":
++ildouble: 1
++ldouble: 1
++
++# cos_towardzero
++Test "cos_towardzero (1) == 0.5403023058681397174009366074429766037323":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (10) == -0.8390715290764524522588639478240648345199":
+ ildouble: 1
+ ldouble: 1
+-Test "cos (pi/2) == 0":
++Test "cos_towardzero (2) == -0.4161468365471423869975682295007621897660":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Test "cos_towardzero (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (4) == -0.6536436208636119146391681830977503814241":
++double: 1
++idouble: 1
++Test "cos_towardzero (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_towardzero (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (8) == -0.1455000338086135258688413818311946826093":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+-# cosh
+-Test "cosh (0.75) == 1.29468328467684468784170818539018176":
++# cos_upward
++Test "cos_upward (1) == 0.5403023058681397174009366074429766037323":
++float: 1
++ifloat: 1
++Test "cos_upward (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (2) == -0.4161468365471423869975682295007621897660":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (4) == -0.6536436208636119146391681830977503814241":
++double: 1
++idouble: 1
++Test "cos_upward (5) == 0.2836621854632262644666391715135573083344":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (6) == 0.9601702866503660205456522979229244054519":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+ ildouble: 1
++ldouble: 1
++Test "cos_upward (7) == 0.7539022543433046381411975217191820122183":
++double: 1
++idouble: 1
++Test "cos_upward (8) == -0.1455000338086135258688413818311946826093":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++
++# cosh_downward
++Test "cosh_downward (22) == 1792456423.065795780980053377632656584997":
++double: 1
++float: 1
++ldouble: 2
++Test "cosh_downward (23) == 4872401723.124451300068625740569997090344":
++double: 1
++float: 1
++ldouble: 1
++Test "cosh_downward (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ldouble: 1
++
++# cosh_tonearest
++Test "cosh_tonearest (22) == 1792456423.065795780980053377632656584997":
++ldouble: 1
++
++# cosh_towardzero
++Test "cosh_towardzero (22) == 1792456423.065795780980053377632656584997":
++double: 1
++float: 1
++ldouble: 2
++Test "cosh_towardzero (23) == 4872401723.124451300068625740569997090344":
++double: 1
++float: 1
++ldouble: 1
++Test "cosh_towardzero (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ldouble: 1
++
++# cosh_upward
++Test "cosh_upward (23) == 4872401723.124451300068625740569997090344":
++ldouble: 1
++Test "cosh_upward (24) == 13244561064.92173614708845674912733665919":
++double: 1
+ # cpow
+ Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+@@ -353,12 +475,8 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+ Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -370,40 +488,36 @@ ifloat: 1
+ Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ double: 1
+ idouble: 1
+-ildouble: 439
+-ldouble: 439
++ildouble: 1
++ldouble: 1
+ Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+ float: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
++ildouble: 1
++ldouble: 1
+ Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 3
+ ldouble: 3
+ # ctanh
+ Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+-ildouble: 5
+-ldouble: 5
++ildouble: 3
++ldouble: 3
+ Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+ float: 1
+ ifloat: 1
+-ildouble: 25
+-ldouble: 25
++ildouble: 1
++ldouble: 1
+ Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+ float: 1
+ ifloat: 1
+ Test "Real part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+ double: 1
+@@ -419,9 +533,6 @@ double: 1
+ idouble: 1
+ # erfc
+-Test "erfc (0.75) == 0.288844366346484868401062165408589223":
+-float: 1
+-ifloat: 1
+ Test "erfc (1.25) == 0.0770998717435417698634765188027188596":
+ ildouble: 1
+ ldouble: 1
+@@ -434,14 +545,6 @@ idouble: 1
+ ildouble: 1
+ ldouble: 1
+-# exp
+-Test "exp (0.75) == 2.11700001661267466854536981983709561":
+-ildouble: 1
+-Test "exp (1000.0) == 0.197007111401704699388887935224332313e435":
+-ildouble: 754
+-Test "exp (50.0) == 5184705528587072464087.45332293348538":
+-ildouble: 16
+-
+ # exp10
+ Test "exp10 (-1) == 0.1":
+ ildouble: 1
+@@ -453,6 +556,51 @@ Test "exp10 (3) == 1000":
+ ildouble: 8
+ ldouble: 8
++# exp_downward
++Test "exp_downward (1) == e":
++ildouble: 1
++ldouble: 1
++Test "exp_downward (2) == e^2":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "exp_downward (3) == e^3":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_towardzero
++Test "exp_towardzero (1) == e":
++ildouble: 1
++ldouble: 1
++Test "exp_towardzero (2) == e^2":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "exp_towardzero (3) == e^3":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_upward
++Test "exp_upward (1) == e":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++
+ # expm1
+ Test "expm1 (1) == M_El - 1.0":
+ ildouble: 1
+@@ -485,26 +633,24 @@ float: 1
+ # j0
+ Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 1
+ float: 1
+-idouble: 3
++idouble: 1
+ ifloat: 1
+ Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+@@ -512,13 +658,8 @@ float: 1
+ ifloat: 1
+ # j1
+-Test "j1 (0.75) == 0.349243602174862192523281016426251335":
+-double: 1
+-idouble: 1
+ Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -526,9 +667,7 @@ Test "j1 (2.0) == 0.57672480775687338720
+ double: 1
+ idouble: 1
+ Test "j1 (8.0) == 0.234636346853914624381276651590454612":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -536,38 +675,31 @@ ldouble: 1
+ # jn
+ Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 1
+ float: 1
+-idouble: 3
++idouble: 1
+ ifloat: 1
+ Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+ float: 1
+ ifloat: 1
+-Test "jn (1, 0.75) == 0.349243602174862192523281016426251335":
+-double: 1
+-idouble: 1
+ Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -575,9 +707,7 @@ Test "jn (1, 2.0) == 0.57672480775687338
+ double: 1
+ idouble: 1
+ Test "jn (1, 8.0) == 0.234636346853914624381276651590454612":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -589,9 +719,7 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10":
+ float: 1
+@@ -606,38 +734,32 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+-double: 5
+-float: 2
+-idouble: 5
+-ifloat: 2
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+-double: 2
+-idouble: 2
+ ildouble: 1
+ ldouble: 1
+ Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+ ildouble: 1
+ ldouble: 1
+ Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+ ildouble: 1
+ ldouble: 1
+ Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+-double: 5
+-float: 2
+-idouble: 5
+-ifloat: 2
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+-double: 1
+-idouble: 1
+ ildouble: 1
+ ldouble: 1
+@@ -648,9 +770,7 @@ idouble: 1
+ ildouble: 1
+ ldouble: 1
+ Test "lgamma (0.7) == 0.260867246531666514385732417016759578":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1":
+ double: 1
+@@ -660,11 +780,6 @@ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+-# log
+-Test "log (e) == 1":
+-float: 1
+-ifloat: 1
+-
+ # log10
+ Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+ ildouble: 1
+@@ -675,20 +790,179 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-# sincos
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
++# pow_downward
++Test "pow_downward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+ double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "pow_downward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# pow_towardzero
++Test "pow_towardzero (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
++double: 1
+ idouble: 1
++ildouble: 1
++ldouble: 1
++Test "pow_towardzero (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
++float: 1
+ ifloat: 1
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
++ildouble: 1
++ldouble: 1
++
++# pow_upward
++Test "pow_upward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "pow_upward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++
++# sin_downward
++Test "sin_downward (1) == 0.8414709848078965066525023216302989996226":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (10) == -0.5440211108893698134047476618513772816836":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (2) == 0.9092974268256816953960198659117448427023":
++double: 1
++idouble: 1
++Test "sin_downward (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (4) == -0.7568024953079282513726390945118290941359":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (5) == -0.9589242746631384688931544061559939733525":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (6) == -0.2794154981989258728115554466118947596280":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
++Test "sin_downward (7) == 0.6569865987187890903969990915936351779369":
+ ildouble: 1
+ ldouble: 1
+-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
++Test "sin_downward (8) == 0.9893582466233817778081235982452886721164":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (9) == 0.4121184852417565697562725663524351793439":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# sin_tonearest
++Test "sin_tonearest (10) == -0.5440211108893698134047476618513772816836":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (4) == -0.7568024953079282513726390945118290941359":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (9) == 0.4121184852417565697562725663524351793439":
++ildouble: 1
++ldouble: 1
++
++# sin_towardzero
++Test "sin_towardzero (1) == 0.8414709848078965066525023216302989996226":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (10) == -0.5440211108893698134047476618513772816836":
++float: 1
++ifloat: 1
++Test "sin_towardzero (2) == 0.9092974268256816953960198659117448427023":
++double: 1
++idouble: 1
++Test "sin_towardzero (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_towardzero (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++Test "sin_towardzero (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (7) == 0.6569865987187890903969990915936351779369":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (8) == 0.9893582466233817778081235982452886721164":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (9) == 0.4121184852417565697562725663524351793439":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# sin_upward
++Test "sin_upward (1) == 0.8414709848078965066525023216302989996226":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "sin_upward (10) == -0.5440211108893698134047476618513772816836":
++float: 1
++ifloat: 1
++Test "sin_upward (2) == 0.9092974268256816953960198659117448427023":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_upward (3) == 0.1411200080598672221007448028081102798469":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_upward (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++Test "sin_upward (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (7) == 0.6569865987187890903969990915936351779369":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "sin_upward (8) == 0.9893582466233817778081235982452886721164":
++float: 1
++ifloat: 1
++
++# sincos
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
++double: 1
++idouble: 1
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+ double: 1
+ float: 1
+ idouble: 1
+@@ -698,66 +972,237 @@ ldouble: 1
+ # sinh
+ Test "sinh (0.75) == 0.822316731935829980703661634446913849":
+-double: 1
+ ildouble: 1
+-# tan
+-Test "tan (pi/4) == 1":
++# sinh_downward
++Test "sinh_downward (22) == 1792456423.065795780701106568345764104225":
+ double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ldouble: 4
++Test "sinh_downward (23) == 4872401723.124451299966006944252978187305":
++double: 1
++float: 1
+ idouble: 1
++ifloat: 1
++Test "sinh_downward (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ldouble: 5
+-# tgamma
+-Test "tgamma (-0.5) == -2 sqrt (pi)":
+-double: 2
++# sinh_tonearest
++Test "sinh_tonearest (22) == 1792456423.065795780701106568345764104225":
++ldouble: 3
++Test "sinh_tonearest (23) == 4872401723.124451299966006944252978187305":
++ldouble: 1
++Test "sinh_tonearest (24) == 13244561064.92173614705070540368454568168":
++ldouble: 6
++
++# sinh_towardzero
++Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ldouble: 4
++Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ldouble: 5
++
++# sinh_upward
++Test "sinh_upward (22) == 1792456423.065795780701106568345764104225":
++ldouble: 16
++Test "sinh_upward (23) == 4872401723.124451299966006944252978187305":
++ldouble: 27
++Test "sinh_upward (24) == 13244561064.92173614705070540368454568168":
++double: 1
++idouble: 1
++ldouble: 7
++
++# tan_downward
++Test "tan_downward (1) == 1.5574077246549022305069748074583601730873":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "tan_downward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_downward (2) == -2.1850398632615189916433061023136825434320":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "tan_downward (3) == -0.1425465430742778052956354105339134932261":
++double: 1
++idouble: 1
++Test "tan_downward (4) == 1.1578212823495775831373424182673239231198":
+ float: 1
+-idouble: 2
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "tgamma (0.5) == sqrt (pi)":
++Test "tan_downward (5) == -3.3805150062465856369827058794473439087096":
++ildouble: 1
++ldouble: 1
++Test "tan_downward (6) == -0.2910061913847491570536995888681755428312":
++double: 1
+ float: 1
++idouble: 1
+ ifloat: 1
+-Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
++Test "tan_downward (7) == 0.8714479827243187364564508896003135663222":
++double: 1
++idouble: 1
++Test "tan_downward (8) == -6.7997114552203786999252627596086333648814":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++
++# tan_tonearest
++Test "tan_tonearest (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (8) == -6.7997114552203786999252627596086333648814":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (9) == -0.4523156594418098405903708757987855343087":
++ildouble: 1
++ldouble: 1
++
++# tan_towardzero
++Test "tan_towardzero (1) == 1.5574077246549022305069748074583601730873":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "tgamma (4) == 6":
++Test "tan_towardzero (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_towardzero (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (4) == 1.1578212823495775831373424182673239231198":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (5) == -3.3805150062465856369827058794473439087096":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "tan_towardzero (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (7) == 0.8714479827243187364564508896003135663222":
++double: 1
++idouble: 1
++Test "tan_towardzero (8) == -6.7997114552203786999252627596086333648814":
++double: 1
++idouble: 1
++ildouble: 2
++ldouble: 2
++Test "tan_towardzero (9) == -0.4523156594418098405903708757987855343087":
++double: 1
++idouble: 1
+ ildouble: 1
+ ldouble: 1
+-# y0
+-Test "y0 (0.125) == -1.38968062514384052915582277745018693":
++# tan_upward
++Test "tan_upward (1) == 1.5574077246549022305069748074583601730873":
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (0.75) == -0.137172769385772397522814379396581855":
++Test "tan_upward (10) == 0.6483608274590866712591249330098086768169":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (4) == 1.1578212823495775831373424182673239231198":
++double: 1
++idouble: 1
++Test "tan_upward (5) == -3.3805150062465856369827058794473439087096":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
++Test "tan_upward (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (7) == 0.8714479827243187364564508896003135663222":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (8) == -6.7997114552203786999252627596086333648814":
++double: 1
++idouble: 1
++ildouble: 2
++ldouble: 2
++Test "tan_upward (9) == -0.4523156594418098405903708757987855343087":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++
++# tgamma
++Test "tgamma (-0.5) == -2 sqrt (pi)":
+ double: 2
+ float: 1
+ idouble: 2
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (1.5) == 0.382448923797758843955068554978089862":
++Test "tgamma (0.5) == sqrt (pi)":
++float: 1
++ifloat: 1
++Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
++
++# y0
++Test "y0 (0.125) == -1.38968062514384052915582277745018693":
++ildouble: 1
++ldouble: 1
++Test "y0 (0.75) == -0.137172769385772397522814379396581855":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
++Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
++ildouble: 1
++ldouble: 1
++Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "y0 (8.0) == 0.223521489387566220527323400498620359":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -766,9 +1211,6 @@ ldouble: 1
+ Test "y1 (0.125) == -5.19993611253477499595928744876579921":
+ ildouble: 1
+ ldouble: 1
+-Test "y1 (1.0) == -0.781212821300288716547150000047964821":
+-double: 1
+-idouble: 1
+ Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+ double: 2
+ float: 2
+@@ -782,9 +1224,7 @@ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+ Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+-double: 1
+ float: 2
+-idouble: 1
+ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+@@ -799,37 +1239,21 @@ float: 1
+ idouble: 1
+ ifloat: 1
+ Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+-double: 2
+-float: 1
+-idouble: 2
+-ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+-double: 1
+-float: 1
+-idouble: 1
+-ifloat: 1
+ Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "yn (0, 8.0) == 0.223521489387566220527323400498620359":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+ ildouble: 1
+ ldouble: 1
+-Test "yn (1, 1.0) == -0.781212821300288716547150000047964821":
+-double: 1
+-idouble: 1
+ Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+ double: 2
+ float: 2
+@@ -843,17 +1267,13 @@ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+ Test "yn (1, 8.0) == -0.158060461731247494255555266187483550":
+-double: 1
+ float: 2
+-idouble: 1
+ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+ Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+@@ -862,28 +1282,22 @@ ifloat: 1
+ ildouble: 4
+ ldouble: 4
+ Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+-double: 1
+ float: 2
+-idouble: 1
+ ifloat: 2
+ Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+ double: 1
+-float: 3
++float: 1
+ idouble: 1
+-ifloat: 3
++ifloat: 1
+ Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+-double: 2
+ float: 3
+-idouble: 2
+ ifloat: 3
+ Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+ ildouble: 1
+ ldouble: 1
+ Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "yn (3, 10.0) == -0.251362657183837329779204747654240998":
+@@ -892,15 +1306,13 @@ float: 1
+ idouble: 1
+ ifloat: 1
+ Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ # Maximal error of functions:
+ Function: "acos":
+-ildouble: 622
+-ldouble: 622
++ildouble: 1
++ldouble: 1
+ Function: "asin":
+ ildouble: 1
+@@ -917,18 +1329,6 @@ ildouble: 2
+ ldouble: 2
+ Function: Real part of "cacosh":
+-double: 1
+-float: 9
+-idouble: 1
+-ifloat: 9
+-ildouble: 6
+-ldouble: 6
+-
+-Function: Imaginary part of "cacosh":
+-double: 1
+-float: 4
+-idouble: 1
+-ifloat: 4
+ ildouble: 1
+ ldouble: 1
+@@ -1033,8 +1433,6 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ Function: "cos":
+ double: 2
+@@ -1044,16 +1442,58 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Function: "cosh":
++Function: "cos_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_tonearest":
+ ildouble: 1
++ldouble: 1
++
++Function: "cos_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_upward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_downward":
++double: 1
++float: 1
++ldouble: 2
++
++Function: "cosh_tonearest":
++ldouble: 1
++
++Function: "cosh_towardzero":
++double: 1
++float: 1
++ldouble: 2
++
++Function: "cosh_upward":
++double: 1
++ldouble: 1
+ Function: Real part of "cpow":
+ double: 1
+ float: 4
+ idouble: 1
+ ifloat: 4
+-ildouble: 763
+-ldouble: 763
++ildouble: 6
++ldouble: 6
+ Function: Imaginary part of "cpow":
+ double: 2
+@@ -1086,38 +1526,32 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+ Function: Real part of "ctan":
+ double: 1
+ idouble: 1
+-ildouble: 439
+-ldouble: 439
++ildouble: 1
++ldouble: 1
+ Function: Imaginary part of "ctan":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 3
+ ldouble: 3
+ Function: Real part of "ctanh":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+-ildouble: 5
+-ldouble: 5
++ildouble: 3
++ldouble: 3
+ Function: Imaginary part of "ctanh":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 25
+-ldouble: 25
++ildouble: 1
++ldouble: 1
+ Function: "erf":
+ double: 1
+@@ -1125,19 +1559,36 @@ idouble: 1
+ Function: "erfc":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Function: "exp":
+-ildouble: 754
+-
+ Function: "exp10":
+ ildouble: 8
+ ldouble: 8
++Function: "exp_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "exp_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "exp_upward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++
+ Function: "expm1":
+ ildouble: 1
+@@ -1151,10 +1602,10 @@ Function: "hypot":
+ float: 1
+ Function: "j0":
+-double: 3
+-float: 2
+-idouble: 3
+-ifloat: 2
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1167,10 +1618,10 @@ ildouble: 1
+ ldouble: 1
+ Function: "jn":
+-double: 5
+-float: 2
+-idouble: 5
+-ifloat: 2
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -1192,6 +1643,58 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "pow_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_upward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "sin_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_upward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ Function: "sincos":
+ double: 1
+ float: 1
+@@ -1201,13 +1704,62 @@ ildouble: 1
+ ldouble: 1
+ Function: "sinh":
+-double: 1
+ ildouble: 1
++Function: "sinh_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ldouble: 5
++
++Function: "sinh_tonearest":
++ldouble: 6
++
++Function: "sinh_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ldouble: 5
++
++Function: "sinh_upward":
++double: 1
++idouble: 1
++ldouble: 27
++
+ Function: "tan":
+ double: 1
+ idouble: 1
++Function: "tan_downward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "tan_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "tan_towardzero":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "tan_upward":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
+ Function: "tgamma":
+ double: 2
+ float: 1
+@@ -1217,9 +1769,9 @@ ildouble: 1
+ ldouble: 1
+ Function: "y0":
+-double: 2
++double: 1
+ float: 1
+-idouble: 2
++idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+diff -Nrup a/sysdeps/ieee754/dbl-64/e_exp.c b/sysdeps/ieee754/dbl-64/e_exp.c
+--- a/sysdeps/ieee754/dbl-64/e_exp.c   2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/e_exp.c   2012-08-06 09:54:00.823929687 -0600
+@@ -1,7 +1,7 @@
+ /*
+  * IBM Accurate Mathematical Library
+  * written by International Business Machines Corp.
+- * Copyright (C) 2001 Free Software Foundation
++ * Copyright (C) 2001-2012 Free Software Foundation
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU Lesser General Public License as published by
+@@ -39,6 +39,7 @@
+ #include "MathLib.h"
+ #include "uexp.tbl"
+ #include "math_private.h"
++#include <fenv.h>
+ double __slowexp(double);
+@@ -53,6 +54,10 @@ double __ieee754_exp(double x) {
+   int4 k;
+ #endif
+   int4 i,j,m,n,ex;
++  fenv_t env;
++  double retval;
++
++  libc_feholdexcept_setround (&env, FE_TONEAREST);
+   junk1.x = x;
+   m = junk1.i[HIGH_HALF];
+@@ -85,18 +90,19 @@ double __ieee754_exp(double x) {
+     rem=(bet + bet*eps)+al*eps;
+     res = al + rem;
+     cor = (al - res) + rem;
+-    if  (res == (res+cor*err_0)) return res*binexp.x;
+-    else return __slowexp(x); /*if error is over bound */
++    if  (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; }
++    else { retval = __slowexp(x); goto ret; } /*if error is over bound */
+   }
+-  if (n <= smallint) return 1.0;
++  if (n <= smallint) { retval = 1.0; goto ret; }
+   if (n >= badint) {
+-    if (n > infint) return(x+x);               /* x is NaN */
+-    if (n < infint) return ( (x>0) ? (hhuge*hhuge) : (tiny*tiny) );
++    if (n > infint) { retval = x+x; goto ret; }               /* x is NaN */
++    if (n < infint) { retval = (x>0) ? (hhuge*hhuge) : (tiny*tiny); goto ret; }
+     /* x is finite,  cause either overflow or underflow  */
+-    if (junk1.i[LOW_HALF] != 0)  return (x+x);                /*  x is NaN  */
+-    return ((x>0)?inf.x:zero );             /* |x| = inf;  return either inf or 0 */
++    if (junk1.i[LOW_HALF] != 0) { retval = x+x; goto ret; } /*  x is NaN  */
++    retval = (x>0)?inf.x:zero;             /* |x| = inf;  return either inf or 0 */
++    goto ret;
+   }
+   y = x*log2e.x + three51.x;
+@@ -121,8 +127,8 @@ double __ieee754_exp(double x) {
+     if (res < 1.0) {res+=res; cor+=cor; ex-=1;}
+     if (ex >=-1022) {
+       binexp.i[HIGH_HALF] = (1023+ex)<<20;
+-      if  (res == (res+cor*err_0)) return res*binexp.x;
+-      else return __slowexp(x); /*if error is over bound */
++      if  (res == (res+cor*err_0)) { retval = res*binexp.x; goto ret; }
++      else { retval = __slowexp(x); goto ret; } /*if error is over bound */
+     }
+     ex = -(1022+ex);
+     binexp.i[HIGH_HALF] = (1023-ex)<<20;
+@@ -135,15 +141,19 @@ double __ieee754_exp(double x) {
+     cor = (t-res)+y;
+     if (res == (res + eps*cor))
+     { binexp.i[HIGH_HALF] = 0x00100000;
+-      return (res-1.0)*binexp.x;
++      retval = (res-1.0)*binexp.x;
++      goto ret;
+     }
+-    else return __slowexp(x); /*   if error is over bound    */
++    else { retval = __slowexp(x); goto ret; } /*   if error is over bound    */
+   }
+   else {
+     binexp.i[HIGH_HALF] =(junk1.i[LOW_HALF]+767)<<20;
+-    if  (res == (res+cor*err_0)) return res*binexp.x*t256.x;
+-    else return __slowexp(x);
++    if (res == (res+cor*err_0)) { retval = res*binexp.x*t256.x; goto ret; }
++    else { retval = __slowexp(x); goto ret; }
+   }
++ ret:
++  libc_feupdateenv (&env);
++  return retval;
+ }
+ /************************************************************************/
+diff -Nrup a/sysdeps/ieee754/dbl-64/e_exp2.c b/sysdeps/ieee754/dbl-64/e_exp2.c
+--- a/sysdeps/ieee754/dbl-64/e_exp2.c  2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/e_exp2.c  2012-08-06 09:54:00.824929683 -0600
+@@ -24,9 +24,6 @@
+    17 (1), March 1991, pp. 26-45.
+    It has been slightly modified to compute 2^x instead of e^x.
+    */
+-#ifndef _GNU_SOURCE
+-#define _GNU_SOURCE
+-#endif
+ #include <stdlib.h>
+ #include <float.h>
+ #include <ieee754.h>
+@@ -37,13 +34,8 @@
+ #include "t_exp2.h"
+-/* XXX I know the assembler generates a warning about incorrect section
+-   attributes. But without the attribute here the compiler places the
+-   constants in the .data section.  Ideally the constant is placed in
+-   .rodata.cst8 so that it can be merged, but gcc sucks, it ICEs when
+-   we try to force this section on it.  --drepper  */
+-static const volatile double TWO1023 = 8.988465674311579539e+307;
+-static const volatile double TWOM1000 = 9.3326361850321887899e-302;
++static const double TWO1023 = 8.988465674311579539e+307;
++static const double TWOM1000 = 9.3326361850321887899e-302;
+ double
+ __ieee754_exp2 (double x)
+@@ -60,11 +52,7 @@ __ieee754_exp2 (double x)
+       union ieee754_double ex2_u, scale_u;
+       fenv_t oldenv;
+-      feholdexcept (&oldenv);
+-#ifdef FE_TONEAREST
+-      /* If we don't have this, it's too bad.  */
+-      fesetround (FE_TONEAREST);
+-#endif
++      libc_feholdexcept_setround (&oldenv, FE_TONEAREST);
+       /* 1. Argument reduction.
+        Choose integers ex, -256 <= t < 256, and some real
+@@ -108,9 +96,10 @@ __ieee754_exp2 (double x)
+              * x + .055504110254308625)
+             * x + .240226506959100583)
+            * x + .69314718055994495) * ex2_u.d;
++      math_opt_barrier (x22);
+       /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
+-      fesetenv (&oldenv);
++      libc_fesetenv (&oldenv);
+       result = x22 * x + ex2_u.d;
+diff -Nrup a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
+--- a/sysdeps/ieee754/dbl-64/e_pow.c   2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/e_pow.c   2012-08-06 09:54:00.824929683 -0600
+@@ -42,6 +42,7 @@
+ #include "MathLib.h"
+ #include "upow.tbl"
+ #include "math_private.h"
++#include <fenv.h>
+ double __exp1(double x, double xx, double error);
+@@ -79,6 +80,11 @@ double __ieee754_pow(double x, double y)
+        (u.i[HIGH_HALF]==0 && u.i[LOW_HALF]!=0))  &&
+                                       /*   2^-1023< x<= 2^-1023 * 0x1.0000ffffffff */
+       (v.i[HIGH_HALF]&0x7fffffff) < 0x4ff00000) {              /* if y<-1 or y>1   */
++    fenv_t env;
++    double retval;
++
++    libc_feholdexcept_setround (&env, FE_TONEAREST);
++
+     z = log1(x,&aa,&error);                                 /* x^y  =e^(y log (X)) */
+     t = y*134217729.0;
+     y1 = t - (t-y);
+@@ -92,7 +98,10 @@ double __ieee754_pow(double x, double y)
+     a2 = (a-a1)+aa;
+     error = error*ABS(y);
+     t = __exp1(a1,a2,1.9e16*error);     /* return -10 or 0 if wasn't computed exactly */
+-    return (t>0)?t:power1(x,y);
++    retval = (t>0)?t:power1(x,y);
++
++    libc_feupdateenv (&env);
++    return retval;
+   }
+   if (x == 0) {
+diff -Nrup a/sysdeps/ieee754/dbl-64/s_sin.c b/sysdeps/ieee754/dbl-64/s_sin.c
+--- a/sysdeps/ieee754/dbl-64/s_sin.c   2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/s_sin.c   2012-08-06 09:54:00.827929671 -0600
+@@ -55,6 +55,7 @@
+ #include "MathLib.h"
+ #include "sincos.tbl"
+ #include "math_private.h"
++#include <fenv.h>
+ static const double
+           sn3 = -1.66666666666664880952546298448555E-01,
+@@ -97,12 +98,16 @@ double __sin(double x){
+ #if 0
+       int4 nn;
+ #endif
++      fenv_t env;
++      double retval = 0;
++
++      libc_feholdexcept_setround (&env, FE_TONEAREST);
+       u.x = x;
+       m = u.i[HIGH_HALF];
+       k = 0x7fffffff&m;              /* no sign           */
+       if (k < 0x3e500000)            /* if x->0 =>sin(x)=x */
+-       return x;
++        { retval = x; goto ret; }
+  /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
+       else  if (k < 0x3fd00000){
+         xx = x*x;
+@@ -110,7 +115,8 @@ double __sin(double x){
+         t = ((((s5.x*xx + s4.x)*xx + s3.x)*xx + s2.x)*xx + s1.x)*(xx*x);
+         res = x+t;
+         cor = (x-res)+t;
+-        return (res == res + 1.07*cor)? res : slow(x);
++        retval = (res == res + 1.07*cor)? res : slow(x);
++        goto ret;
+       }    /*  else  if (k < 0x3fd00000)    */
+ /*---------------------------- 0.25<|x|< 0.855469---------------------- */
+       else if (k < 0x3feb6000)  {
+@@ -127,7 +133,8 @@ double __sin(double x){
+         cor=(ssn+s*ccs-sn*c)+cs*s;
+         res=sn+cor;
+         cor=(sn-res)+cor;
+-        return (res==res+1.025*cor)? res : slow1(x);
++        retval = (res==res+1.096*cor)? res : slow1(x);
++        goto ret;
+       }    /*   else  if (k < 0x3feb6000)    */
+ /*----------------------- 0.855469  <|x|<2.426265  ----------------------*/
+@@ -153,7 +160,8 @@ double __sin(double x){
+         cor=(ccs-s*ssn-cs*c)-sn*s;
+         res=cs+cor;
+         cor=(cs-res)+cor;
+-        return (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
++        retval = (res==res+1.020*cor)? ((m>0)?res:-res) : slow2(x);
++        goto ret;
+       } /*   else  if (k < 0x400368fd)    */
+ /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
+@@ -179,7 +187,8 @@ double __sin(double x){
+             res = a+t;
+             cor = (a-res)+t;
+             cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+-            return (res == res + cor)? res : sloww(a,da,x);
++            retval = (res == res + cor)? res : sloww(a,da,x);
++            goto ret;
+           }
+           else  {
+             if (a>0)
+@@ -200,7 +209,8 @@ double __sin(double x){
+             res=sn+cor;
+             cor=(sn-res)+cor;
+             cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+-            return (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
++            retval = (res==res+cor)? ((m)?res:-res) : sloww1(a,da,x);
++            goto ret;
+           }
+           break;
+@@ -222,7 +232,8 @@ double __sin(double x){
+           res=cs+cor;
+           cor=(cs-res)+cor;
+           cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+-          return (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
++          retval = (res==res+cor)? ((n&2)?-res:res) : sloww2(a,da,x,n);
++          goto ret;
+           break;
+@@ -258,7 +269,8 @@ double __sin(double x){
+             res = a+t;
+             cor = (a-res)+t;
+             cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+-            return (res == res + cor)? res : bsloww(a,da,x,n);
++            retval = (res == res + cor)? res : bsloww(a,da,x,n);
++            goto ret;
+           }
+           else  {
+             if (a>0) {m=1;t=a;db=da;}
+@@ -277,7 +289,8 @@ double __sin(double x){
+             res=sn+cor;
+             cor=(sn-res)+cor;
+             cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+-            return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
++            retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
++            goto ret;
+                  }
+           break;
+@@ -299,7 +312,8 @@ double __sin(double x){
+           res=cs+cor;
+           cor=(cs-res)+cor;
+           cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+-          return (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
++          retval = (res==res+cor)? ((n&2)?-res:res) : bsloww2(a,da,x,n);
++          goto ret;
+           break;
+@@ -313,17 +327,20 @@ double __sin(double x){
+         n = __branred(x,&a,&da);
+         switch (n) {
+         case 0:
+-          if (a*a < 0.01588) return bsloww(a,da,x,n);
+-          else return bsloww1(a,da,x,n);
++          if (a*a < 0.01588) retval = bsloww(a,da,x,n);
++          else retval = bsloww1(a,da,x,n);
++          goto ret;
+           break;
+         case 2:
+-          if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+-          else return bsloww1(-a,-da,x,n);
++          if (a*a < 0.01588) retval = bsloww(-a,-da,x,n);
++          else retval = bsloww1(-a,-da,x,n);
++          goto ret;
+           break;
+         case 1:
+         case 3:
+-          return  bsloww2(a,da,x,n);
++          retval = bsloww2(a,da,x,n);
++          goto ret;
+           break;
+         }
+@@ -333,9 +350,13 @@ double __sin(double x){
+       else {
+         if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
+           __set_errno (EDOM);
+-        return x / x;
++        retval = x / x;
++        goto ret;
+       }
+-      return 0;         /* unreachable */
++
++ ret:
++      libc_feupdateenv (&env);
++      return retval;
+ }
+@@ -350,11 +371,16 @@ double __cos(double x)
+   mynumber u,v;
+   int4 k,m,n;
++  fenv_t env;
++  double retval = 0;
++
++  libc_feholdexcept_setround (&env, FE_TONEAREST);
++
+   u.x = x;
+   m = u.i[HIGH_HALF];
+   k = 0x7fffffff&m;
+-  if (k < 0x3e400000 ) return 1.0; /* |x|<2^-27 => cos(x)=1 */
++  if (k < 0x3e400000 ) { retval = 1.0; goto ret; } /* |x|<2^-27 => cos(x)=1 */
+   else if (k < 0x3feb6000 ) {/* 2^-27 < |x| < 0.855469 */
+     y=ABS(x);
+@@ -371,7 +397,8 @@ double __cos(double x)
+     cor=(ccs-s*ssn-cs*c)-sn*s;
+     res=cs+cor;
+     cor=(cs-res)+cor;
+-    return (res==res+1.020*cor)? res : cslow2(x);
++    retval = (res==res+1.020*cor)? res : cslow2(x);
++    goto ret;
+ }    /*   else  if (k < 0x3feb6000)    */
+@@ -385,7 +412,8 @@ double __cos(double x)
+       res = a+t;
+       cor = (a-res)+t;
+       cor = (cor>0)? 1.02*cor+1.0e-31 : 1.02*cor -1.0e-31;
+-      return (res == res + cor)? res : csloww(a,da,x);
++      retval = (res == res + cor)? res : csloww(a,da,x);
++      goto ret;
+     }
+     else  {
+       if (a>0) {m=1;t=a;db=da;}
+@@ -404,7 +432,8 @@ double __cos(double x)
+       res=sn+cor;
+       cor=(sn-res)+cor;
+       cor = (cor>0)? 1.035*cor+1.0e-31 : 1.035*cor-1.0e-31;
+-      return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
++      retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
++      goto ret;
+ }
+ }    /*   else  if (k < 0x400368fd)    */
+@@ -431,7 +460,8 @@ double __cos(double x)
+       res = a+t;
+       cor = (a-res)+t;
+       cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+-      return (res == res + cor)? res : csloww(a,da,x);
++      retval = (res == res + cor)? res : csloww(a,da,x);
++      goto ret;
+       }
+       else  {
+       if (a>0) {m=1;t=a;db=da;}
+@@ -450,7 +480,8 @@ double __cos(double x)
+       res=sn+cor;
+       cor=(sn-res)+cor;
+       cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+-      return (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
++      retval = (res==res+cor)? ((m)?res:-res) : csloww1(a,da,x);
++      goto ret;
+       }
+       break;
+@@ -471,7 +502,8 @@ double __cos(double x)
+       res=cs+cor;
+       cor=(cs-res)+cor;
+       cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+-      return (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
++      retval = (res==res+cor)? ((n)?-res:res) : csloww2(a,da,x,n);
++      goto ret;
+            break;
+@@ -506,7 +538,8 @@ double __cos(double x)
+       res = a+t;
+       cor = (a-res)+t;
+       cor = (cor>0)? 1.02*cor+eps : 1.02*cor -eps;
+-      return (res == res + cor)? res : bsloww(a,da,x,n);
++      retval = (res == res + cor)? res : bsloww(a,da,x,n);
++      goto ret;
+       }
+       else  {
+       if (a>0) {m=1;t=a;db=da;}
+@@ -525,7 +558,8 @@ double __cos(double x)
+       res=sn+cor;
+       cor=(sn-res)+cor;
+       cor = (cor>0)? 1.035*cor+eps : 1.035*cor-eps;
+-      return (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
++      retval = (res==res+cor)? ((m)?res:-res) : bsloww1(a,da,x,n);
++      goto ret;
+       }
+       break;
+@@ -546,7 +580,8 @@ double __cos(double x)
+       res=cs+cor;
+       cor=(cs-res)+cor;
+       cor = (cor>0)? 1.025*cor+eps : 1.025*cor-eps;
+-      return (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
++      retval = (res==res+cor)? ((n)?-res:res) : bsloww2(a,da,x,n);
++      goto ret;
+       break;
+     }
+@@ -558,17 +593,20 @@ double __cos(double x)
+     n = __branred(x,&a,&da);
+     switch (n) {
+     case 1:
+-      if (a*a < 0.01588) return bsloww(-a,-da,x,n);
+-      else return bsloww1(-a,-da,x,n);
++      if (a*a < 0.01588) retval = bsloww(-a,-da,x,n);
++      else retval = bsloww1(-a,-da,x,n);
++      goto ret;
+       break;
+               case 3:
+-                if (a*a < 0.01588) return bsloww(a,da,x,n);
+-                else return bsloww1(a,da,x,n);
++                if (a*a < 0.01588) retval = bsloww(a,da,x,n);
++                else retval = bsloww1(a,da,x,n);
++                goto ret;
+                 break;
+     case 0:
+     case 2:
+-      return  bsloww2(a,da,x,n);
++      retval = bsloww2(a,da,x,n);
++      goto ret;
+       break;
+     }
+@@ -580,10 +618,13 @@ double __cos(double x)
+   else {
+     if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
+       __set_errno (EDOM);
+-    return x / x; /* |x| > 2^1024 */
++    retval = x / x; /* |x| > 2^1024 */
++    goto ret;
+   }
+-  return 0;
++ ret:
++  libc_feupdateenv (&env);
++  return retval;
+ }
+ /************************************************************************/
+diff -Nrup a/sysdeps/ieee754/dbl-64/s_tan.c b/sysdeps/ieee754/dbl-64/s_tan.c
+--- a/sysdeps/ieee754/dbl-64/s_tan.c   2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/s_tan.c   2012-08-06 09:54:00.828929666 -0600
+@@ -40,6 +40,8 @@
+ #include "mpa.h"
+ #include "MathLib.h"
+ #include "math.h"
++#include "math_private.h"
++#include <fenv.h>
+ static double tanMp(double);
+ void __mptan(double, mp_no *, int);
+@@ -58,21 +60,27 @@ double tan(double x) {
+   mp_no mpy;
+ #endif
++  fenv_t env;
++  double retval;
++
+   int __branred(double, double *, double *);
+   int __mpranred(double, mp_no *, int);
++  libc_feholdexcept_setround (&env, FE_TONEAREST);
++
+   /* x=+-INF, x=NaN */
+   num.d = x;  ux = num.i[HIGH_HALF];
+   if ((ux&0x7ff00000)==0x7ff00000) {
+     if ((ux&0x7fffffff)==0x7ff00000)
+       __set_errno (EDOM);
+-    return x-x;
++    retval = x-x;
++    goto ret;
+   }
+   w=(x<ZERO) ? -x : x;
+   /* (I) The case abs(x) <= 1.259e-8 */
+-  if (w<=g1.d)  return x;
++  if (w<=g1.d) { retval = x; goto ret; }
+   /* (II) The case 1.259e-8 < abs(x) <= 0.0608 */
+   if (w<=g2.d) {
+@@ -80,7 +88,7 @@ double tan(double x) {
+     /* First stage */
+     x2 = x*x;
+     t2 = x*x2*(d3.d+x2*(d5.d+x2*(d7.d+x2*(d9.d+x2*d11.d))));
+-    if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2))  return y;
++    if ((y=x+(t2-u1.d*t2)) == x+(t2+u1.d*t2)) { retval = y; goto ret; }
+     /* Second stage */
+     c1 = x2*(a15.d+x2*(a17.d+x2*(a19.d+x2*(a21.d+x2*(a23.d+x2*(a25.d+
+@@ -100,8 +108,9 @@ double tan(double x) {
+     MUL2(x2,xx2,c2,cc2,c1,cc1,t1,t2,t3,t4,t5,t6,t7,t8)
+     MUL2(x ,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8)
+     ADD2(x    ,zero.d,c2,cc2,c1,cc1,t1,t2)
+-    if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1))  return y;
+-    return tanMp(x);
++    if ((y=c1+(cc1-u2.d*c1)) == c1+(cc1+u2.d*c1)) { retval = y; goto ret; }
++    retval = tanMp(x);
++    goto ret;
+   }
+   /* (III) The case 0.0608 < abs(x) <= 0.787 */
+@@ -112,10 +121,10 @@ double tan(double x) {
+     z = w-xfg[i][0].d;  z2 = z*z;   s = (x<ZERO) ? MONE : ONE;
+     pz = z+z*z2*(e0.d+z2*e1.d);
+     fi = xfg[i][1].d;   gi = xfg[i][2].d;   t2 = pz*(gi+fi)/(gi-pz);
+-    if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d))  return (s*y);
++    if ((y=fi+(t2-fi*u3.d))==fi+(t2+fi*u3.d)) { retval = (s*y); goto ret; }
+     t3 = (t2<ZERO) ? -t2 : t2;
+     t4 = fi*ua3.d+t3*ub3.d;
+-    if ((y=fi+(t2-t4))==fi+(t2+t4))  return (s*y);
++    if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (s*y); goto ret; }
+     /* Second stage */
+     ffi = xfg[i][3].d;
+@@ -133,8 +142,9 @@ double tan(double x) {
+     SUB2(one.d,zero.d,c3,cc3,c1,cc1,t1,t2)
+     DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-    if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3))  return (s*y);
+-    return tanMp(x);
++      if ((y=c3+(cc3-u4.d*c3))==c3+(cc3+u4.d*c3)) { retval = (s*y); goto ret; }
++    retval = tanMp(x);
++    goto ret;
+   }
+   /* (---) The case 0.787 < abs(x) <= 25 */
+@@ -152,7 +162,7 @@ double tan(double x) {
+     else         {ya= a;  yya= da;  sy= ONE;}
+     /* (IV),(V) The case 0.787 < abs(x) <= 25,    abs(y) <= 1e-7 */
+-    if (ya<=gy1.d)  return tanMp(x);
++    if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
+     /* (VI) The case 0.787 < abs(x) <= 25,    1e-7 < abs(y) <= 0.0608 */
+     if (ya<=gy2.d) {
+@@ -162,10 +172,10 @@ double tan(double x) {
+         /* First stage -cot */
+         EADD(a,t2,b,db)
+         DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-        if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c))  return (-y); }
++      if ((y=c+(dc-u6.d*c))==c+(dc+u6.d*c)) { retval = (-y); goto ret; } }
+       else {
+         /* First stage tan */
+-        if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a))  return y; }
++      if ((y=a+(t2-u5.d*a))==a+(t2+u5.d*a)) { retval = y; goto ret; } }
+       /* Second stage */
+       /* Range reduction by algorithm ii */
+       t = (x*hpinv.d + toint.d);
+@@ -203,11 +213,12 @@ double tan(double x) {
+       if (n) {
+         /* Second stage -cot */
+         DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-        if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2))  return (-y); }
++      if ((y=c2+(cc2-u8.d*c2)) == c2+(cc2+u8.d*c2)) { retval = (-y); goto ret; } }
+       else {
+         /* Second stage tan */
+-        if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1))  return y; }
+-      return tanMp(x);
++      if ((y=c1+(cc1-u7.d*c1)) == c1+(cc1+u7.d*c1)) { retval = y; goto ret; } }
++      retval = tanMp(x);
++      goto ret;
+     }
+     /* (VII) The case 0.787 < abs(x) <= 25,    0.0608 < abs(y) <= 0.787 */
+@@ -221,17 +232,17 @@ double tan(double x) {
+     if (n) {
+       /* -cot */
+       t2 = pz*(fi+gi)/(fi+pz);
+-      if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d))  return (-sy*y);
++      if ((y=gi-(t2-gi*u10.d))==gi-(t2+gi*u10.d)) { retval = (-sy*y); goto ret; }
+       t3 = (t2<ZERO) ? -t2 : t2;
+       t4 = gi*ua10.d+t3*ub10.d;
+-      if ((y=gi-(t2-t4))==gi-(t2+t4))  return (-sy*y); }
++      if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
+     else   {
+       /* tan */
+       t2 = pz*(gi+fi)/(gi-pz);
+-      if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d))  return (sy*y);
++      if ((y=fi+(t2-fi*u9.d))==fi+(t2+fi*u9.d)) { retval = (sy*y); goto ret; }
+       t3 = (t2<ZERO) ? -t2 : t2;
+       t4 = fi*ua9.d+t3*ub9.d;
+-      if ((y=fi+(t2-t4))==fi+(t2+t4))  return (sy*y); }
++      if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
+     /* Second stage */
+     ffi = xfg[i][3].d;
+@@ -252,13 +263,14 @@ double tan(double x) {
+     if (n) {
+       /* -cot */
+       DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3))  return (-sy*y); }
++      if ((y=c3+(cc3-u12.d*c3))==c3+(cc3+u12.d*c3)) { retval = (-sy*y); goto ret; } }
+     else {
+       /* tan */
+       DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3))  return (sy*y); }
++      if ((y=c3+(cc3-u11.d*c3))==c3+(cc3+u11.d*c3)) { retval = (sy*y); goto ret; } }
+-    return tanMp(x);
++    retval = tanMp(x);
++    goto ret;
+   }
+   /* (---) The case 25 < abs(x) <= 1e8 */
+@@ -280,7 +292,7 @@ double tan(double x) {
+     else         {ya= a;  yya= da;  sy= ONE;}
+     /* (+++) The case 25 < abs(x) <= 1e8,    abs(y) <= 1e-7 */
+-    if (ya<=gy1.d)  return tanMp(x);
++    if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
+     /* (VIII) The case 25 < abs(x) <= 1e8,    1e-7 < abs(y) <= 0.0608 */
+     if (ya<=gy2.d) {
+@@ -290,10 +302,10 @@ double tan(double x) {
+         /* First stage -cot */
+         EADD(a,t2,b,db)
+         DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-        if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c))  return (-y); }
++      if ((y=c+(dc-u14.d*c))==c+(dc+u14.d*c)) { retval = (-y); goto ret; } }
+       else {
+         /* First stage tan */
+-        if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a))  return y; }
++      if ((y=a+(t2-u13.d*a))==a+(t2+u13.d*a)) { retval = y; goto ret; } }
+       /* Second stage */
+       MUL2(a,da,a,da,x2,xx2,t1,t2,t3,t4,t5,t6,t7,t8)
+@@ -317,11 +329,12 @@ double tan(double x) {
+       if (n) {
+         /* Second stage -cot */
+         DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-        if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2))  return (-y); }
++      if ((y=c2+(cc2-u16.d*c2)) == c2+(cc2+u16.d*c2)) { retval = (-y); goto ret; } }
+       else {
+         /* Second stage tan */
+-        if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1))  return (y); }
+-      return tanMp(x);
++      if ((y=c1+(cc1-u15.d*c1)) == c1+(cc1+u15.d*c1)) { retval = (y); goto ret; } }
++      retval = tanMp(x);
++      goto ret;
+     }
+     /* (IX) The case 25 < abs(x) <= 1e8,    0.0608 < abs(y) <= 0.787 */
+@@ -334,17 +347,17 @@ double tan(double x) {
+     if (n) {
+       /* -cot */
+       t2 = pz*(fi+gi)/(fi+pz);
+-      if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d))  return (-sy*y);
++      if ((y=gi-(t2-gi*u18.d))==gi-(t2+gi*u18.d)) { retval = (-sy*y); goto ret; }
+       t3 = (t2<ZERO) ? -t2 : t2;
+       t4 = gi*ua18.d+t3*ub18.d;
+-      if ((y=gi-(t2-t4))==gi-(t2+t4))  return (-sy*y); }
++      if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
+     else   {
+       /* tan */
+       t2 = pz*(gi+fi)/(gi-pz);
+-      if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d))  return (sy*y);
++      if ((y=fi+(t2-fi*u17.d))==fi+(t2+fi*u17.d)) { retval = (sy*y); goto ret; }
+       t3 = (t2<ZERO) ? -t2 : t2;
+       t4 = fi*ua17.d+t3*ub17.d;
+-      if ((y=fi+(t2-t4))==fi+(t2+t4))  return (sy*y); }
++      if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
+     /* Second stage */
+     ffi = xfg[i][3].d;
+@@ -365,12 +378,13 @@ double tan(double x) {
+     if (n) {
+       /* -cot */
+       DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3))  return (-sy*y); }
++      if ((y=c3+(cc3-u20.d*c3))==c3+(cc3+u20.d*c3)) { retval = (-sy*y); goto ret; } }
+     else {
+       /* tan */
+       DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3))  return (sy*y); }
+-    return tanMp(x);
++      if ((y=c3+(cc3-u19.d*c3))==c3+(cc3+u19.d*c3)) { retval = (sy*y); goto ret; } }
++    retval = tanMp(x);
++    goto ret;
+   }
+   /* (---) The case 1e8 < abs(x) < 2**1024 */
+@@ -381,7 +395,7 @@ double tan(double x) {
+   else         {ya= a;  yya= da;  sy= ONE;}
+   /* (+++) The case 1e8 < abs(x) < 2**1024,    abs(y) <= 1e-7 */
+-  if (ya<=gy1.d)  return tanMp(x);
++  if (ya<=gy1.d) { retval = tanMp(x); goto ret; }
+   /* (X) The case 1e8 < abs(x) < 2**1024,    1e-7 < abs(y) <= 0.0608 */
+   if (ya<=gy2.d) {
+@@ -391,10 +405,10 @@ double tan(double x) {
+       /* First stage -cot */
+       EADD(a,t2,b,db)
+       DIV2(one.d,zero.d,b,db,c,dc,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c))  return (-y); }
++      if ((y=c+(dc-u22.d*c))==c+(dc+u22.d*c)) { retval = (-y); goto ret; } }
+     else {
+       /* First stage tan */
+-      if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a))  return y; }
++      if ((y=a+(t2-u21.d*a))==a+(t2+u21.d*a)) { retval = y; goto ret; } }
+     /* Second stage */
+     /* Reduction by algorithm iv */
+@@ -423,11 +437,12 @@ double tan(double x) {
+     if (n) {
+       /* Second stage -cot */
+       DIV2(one.d,zero.d,c1,cc1,c2,cc2,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-      if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2))  return (-y); }
++      if ((y=c2+(cc2-u24.d*c2)) == c2+(cc2+u24.d*c2)) { retval = (-y); goto ret; } }
+     else {
+       /* Second stage tan */
+-      if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1))  return y; }
+-    return tanMp(x);
++      if ((y=c1+(cc1-u23.d*c1)) == c1+(cc1+u23.d*c1)) { retval = y; goto ret; } }
++    retval = tanMp(x);
++    goto ret;
+   }
+   /* (XI) The case 1e8 < abs(x) < 2**1024,    0.0608 < abs(y) <= 0.787 */
+@@ -440,17 +455,17 @@ double tan(double x) {
+   if (n) {
+     /* -cot */
+     t2 = pz*(fi+gi)/(fi+pz);
+-    if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d))  return (-sy*y);
++    if ((y=gi-(t2-gi*u26.d))==gi-(t2+gi*u26.d)) { retval = (-sy*y); goto ret; }
+     t3 = (t2<ZERO) ? -t2 : t2;
+     t4 = gi*ua26.d+t3*ub26.d;
+-    if ((y=gi-(t2-t4))==gi-(t2+t4))  return (-sy*y); }
++    if ((y=gi-(t2-t4))==gi-(t2+t4)) { retval = (-sy*y); goto ret; } }
+   else   {
+     /* tan */
+     t2 = pz*(gi+fi)/(gi-pz);
+-    if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d))  return (sy*y);
++    if ((y=fi+(t2-fi*u25.d))==fi+(t2+fi*u25.d)) { retval = (sy*y); goto ret; }
+     t3 = (t2<ZERO) ? -t2 : t2;
+     t4 = fi*ua25.d+t3*ub25.d;
+-    if ((y=fi+(t2-t4))==fi+(t2+t4))  return (sy*y); }
++    if ((y=fi+(t2-t4))==fi+(t2+t4)) { retval = (sy*y); goto ret; } }
+   /* Second stage */
+   ffi = xfg[i][3].d;
+@@ -471,15 +486,19 @@ double tan(double x) {
+   if (n) {
+     /* -cot */
+     DIV2(c1,cc1,c2,cc2,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-    if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3))  return (-sy*y); }
++    if ((y=c3+(cc3-u28.d*c3))==c3+(cc3+u28.d*c3)) { retval = (-sy*y); goto ret; } }
+   else {
+     /* tan */
+     DIV2(c2,cc2,c1,cc1,c3,cc3,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10)
+-    if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3))  return (sy*y); }
+-  return tanMp(x);
++    if ((y=c3+(cc3-u27.d*c3))==c3+(cc3+u27.d*c3)) { retval = (sy*y); goto ret; } }
++  retval = tanMp(x);
++  goto ret;
++
++ ret:
++  libc_feupdateenv (&env);
++  return retval;
+ }
+-
+ /* multiple precision stage                                              */
+ /* Convert x to multi precision number,compute tan(x) by mptan() routine */
+ /* and converts result back to double                                    */
+diff -Nrup a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c
+--- a/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c 2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/dbl-64/wordsize-64/s_nearbyint.c 2012-08-06 09:54:00.828929666 -0600
+@@ -24,22 +24,14 @@
+ #include "math.h"
+ #include "math_private.h"
+-#ifdef __STDC__
+ static const double
+-#else
+-static double
+-#endif
+ TWO52[2]={
+   4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
+  -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
+ };
+-#ifdef __STDC__
+-      double __nearbyint(double x)
+-#else
+-      double __nearbyint(x)
+-      double x;
+-#endif
++double
++__nearbyint(double x)
+ {
+       fenv_t env;
+       int64_t i0,sx;
+@@ -47,20 +39,19 @@ TWO52[2]={
+       EXTRACT_WORDS64(i0,x);
+       sx = (i0>>63)&1;
+       j0 = ((i0>>52)&0x7ff)-0x3ff;
+-      if(j0<52) {
++      if(__builtin_expect(j0<52, 1)) {
+           if(j0<0) {
+             if((i0&UINT64_C(0x7fffffffffffffff))==0) return x;
+               uint64_t i = i0 & UINT64_C(0xfffffffffffff);
+               i0 &= UINT64_C(0xfffe000000000000);
+               i0 |= (((i|-i) >> 12) & UINT64_C(0x8000000000000));
+               INSERT_WORDS64(x,i0);
+-              feholdexcept (&env);
++              libc_feholdexcept (&env);
+               double w = TWO52[sx]+x;
+               double t =  w-TWO52[sx];
+-              fesetenv (&env);
+-              EXTRACT_WORDS64(i0,t);
+-              INSERT_WORDS64(t,(i0&UINT64_C(0x7fffffffffffffff))|(sx<<63));
+-              return t;
++              math_opt_barrier(t);
++              libc_fesetenv (&env);
++              return copysign(t, x);
+           } else {
+               uint64_t i = UINT64_C(0x000fffffffffffff)>>j0;
+               if((i0&i)==0) return x; /* x is integral */
+@@ -73,10 +64,11 @@ TWO52[2]={
+           else return x;              /* x is integral */
+       }
+       INSERT_WORDS64(x,i0);
+-      feholdexcept (&env);
++      libc_feholdexcept (&env);
+       double w = TWO52[sx]+x;
+       double t = w-TWO52[sx];
+-      fesetenv (&env);
++      math_opt_barrier (t);
++      libc_fesetenv (&env);
+       return t;
+ }
+ weak_alias (__nearbyint, nearbyint)
+diff -Nrup a/sysdeps/ieee754/flt-32/e_exp2f.c b/sysdeps/ieee754/flt-32/e_exp2f.c
+--- a/sysdeps/ieee754/flt-32/e_exp2f.c 2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/flt-32/e_exp2f.c 2012-08-06 09:54:00.829929661 -0600
+@@ -56,11 +56,7 @@ __ieee754_exp2f (float x)
+       union ieee754_float ex2_u, scale_u;
+       fenv_t oldenv;
+-      feholdexcept (&oldenv);
+-#ifdef FE_TONEAREST
+-      /* If we don't have this, it's too bad.  */
+-      fesetround (FE_TONEAREST);
+-#endif
++      libc_feholdexcept_setroundf (&oldenv, FE_TONEAREST);
+       /* 1. Argument reduction.
+        Choose integers ex, -128 <= t < 128, and some real
+@@ -103,7 +99,7 @@ __ieee754_exp2f (float x)
+       x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
+       /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex).  */
+-      fesetenv (&oldenv);
++      libc_fesetenv (&oldenv);
+       result = x22 * x + ex2_u.f;
+diff -Nrup a/sysdeps/ieee754/flt-32/e_expf.c b/sysdeps/ieee754/flt-32/e_expf.c
+--- a/sysdeps/ieee754/flt-32/e_expf.c  2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/flt-32/e_expf.c  2012-08-06 09:54:00.829929661 -0600
+@@ -47,9 +47,6 @@
+    to perform an 'accurate table method' expf, because of the range reduction
+    overhead (compare exp2f).
+    */
+-#ifndef _GNU_SOURCE
+-#define _GNU_SOURCE
+-#endif
+ #include <float.h>
+ #include <ieee754.h>
+ #include <math.h>
+@@ -60,8 +57,8 @@
+ extern const float __exp_deltatable[178];
+ extern const double __exp_atable[355] /* __attribute__((mode(DF))) */;
+-static const volatile float TWOM100 = 7.88860905e-31;
+-static const volatile float TWO127 = 1.7014118346e+38;
++static const float TWOM100 = 7.88860905e-31;
++static const float TWO127 = 1.7014118346e+38;
+ float
+ __ieee754_expf (float x)
+@@ -86,10 +83,7 @@ __ieee754_expf (float x)
+       union ieee754_double ex2_u;
+       fenv_t oldenv;
+-      feholdexcept (&oldenv);
+-#ifdef FE_TONEAREST
+-      fesetround (FE_TONEAREST);
+-#endif
++      libc_feholdexcept_setroundf (&oldenv, FE_TONEAREST);
+       /* Calculate n.  */
+       n = x * M_1_LN2 + THREEp22;
+@@ -119,7 +113,7 @@ __ieee754_expf (float x)
+       x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta;
+       /* Return result.  */
+-      fesetenv (&oldenv);
++      libc_fesetenvf (&oldenv);
+       result = x22 * ex2_u.d + ex2_u.d;
+       return (float) result;
+diff -Nrup a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
+--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c    2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c    2012-08-06 09:54:00.891929402 -0600
+@@ -19,22 +19,14 @@
+ #include "math.h"
+ #include "math_private.h"
+-#ifdef __STDC__
+ static const float
+-#else
+-static float
+-#endif
+ TWO23[2]={
+   8.3886080000e+06, /* 0x4b000000 */
+  -8.3886080000e+06, /* 0xcb000000 */
+ };
+-#ifdef __STDC__
+-      float __nearbyintf(float x)
+-#else
+-      float __nearbyintf(x)
+-      float x;
+-#endif
++float
++__nearbyintf(float x)
+ {
+       fenv_t env;
+       int32_t i0,j0,sx;
+@@ -50,13 +42,13 @@ TWO23[2]={
+               i0 &= 0xfff00000;
+               i0 |= ((i1|-i1)>>9)&0x400000;
+               SET_FLOAT_WORD(x,i0);
+-              feholdexcept (&env);
+-              w = TWO23[sx]+x;
+-              t =  w-TWO23[sx];
+-              fesetenv (&env);
++              libc_feholdexceptf (&env);
++              w = TWO23[sx]+x;
++              t =  w-TWO23[sx];
++              libc_fesetenvf (&env);
+               GET_FLOAT_WORD(i0,t);
+               SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
+-              return t;
++              return t;
+           } else {
+               i = (0x007fffff)>>j0;
+               if((i0&i)==0) return x; /* x is integral */
+@@ -64,14 +56,14 @@ TWO23[2]={
+               if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
+           }
+       } else {
+-          if(j0==0x80) return x+x;    /* inf or NaN */
++          if(__builtin_expect(j0==0x80, 0)) return x+x;       /* inf or NaN */
+           else return x;              /* x is integral */
+       }
+       SET_FLOAT_WORD(x,i0);
+-      feholdexcept (&env);
++      libc_feholdexceptf (&env);
+       w = TWO23[sx]+x;
+       t = w-TWO23[sx];
+-      fesetenv (&env);
++      libc_fesetenvf (&env);
+       return t;
+ }
+ weak_alias (__nearbyintf, nearbyintf)
+diff -Nrup a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps
+--- a/sysdeps/powerpc/fpu/libm-test-ulps       2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/powerpc/fpu/libm-test-ulps       2012-08-06 10:03:24.424569052 -0600
+@@ -37,16 +37,9 @@ ildouble: 1
+ ldouble: 1
+ # cacosh
+-Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+ Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
++float: 1
++ifloat: 1
+ # casin
+ Test "Real part of: casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i":
+@@ -84,8 +77,6 @@ ifloat: 1
+ # catan
+ Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+-float: 3
+-ifloat: 3
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+@@ -93,23 +84,14 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+-float: 4
+-ifloat: 4
+ # catanh
+ Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+ double: 4
+ idouble: 4
+-Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+-float: 4
+-ifloat: 4
+ Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+ double: 1
+ idouble: 1
+-Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+-float: 6
+-ifloat: 6
+ # cbrt
+ Test "cbrt (-27.0) == -3.0":
+@@ -167,8 +149,6 @@ ldouble: 1
+ # clog
+ Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+-float: 3
+-ifloat: 3
+ ildouble: 1
+ ldouble: 1
+ Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+@@ -197,9 +177,7 @@ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ double: 1
+-float: 5
+ idouble: 1
+-ifloat: 5
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+@@ -298,23 +276,165 @@ ldouble: 1
+ # cos
+ Test "cos (M_PI_6l * 2.0) == 0.5":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ Test "cos (M_PI_6l * 4.0) == -0.5":
+ double: 2
+ float: 1
+ idouble: 2
+ ifloat: 1
+-Test "cos (pi/2) == 0":
+-double: 1
++
++# cos_downward
++Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
++float: 1
++ifloat: 1
++ildouble: 4
++ldouble: 4
++Test "cos_downward (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_downward (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++Test "cos_downward (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++Test "cos_downward (4) == -0.6536436208636119146391681830977503814241":
++float: 1
++ifloat: 1
++Test "cos_downward (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_downward (6) == 0.9601702866503660205456522979229244054519":
++ildouble: 1
++ldouble: 1
++Test "cos_downward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++Test "cos_downward (8) == -0.1455000338086135258688413818311946826093":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "cos_downward (9) == -0.9111302618846769883682947111811653112463":
++ildouble: 1
++ldouble: 1
++
++# cos_tonearest
++Test "cos_tonearest (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++
++# cos_towardzero
++Test "cos_towardzero (1) == 0.5403023058681397174009366074429766037323":
++ildouble: 2
++ldouble: 2
++Test "cos_towardzero (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++Test "cos_towardzero (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++Test "cos_towardzero (4) == -0.6536436208636119146391681830977503814241":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_towardzero (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++Test "cos_towardzero (8) == -0.1455000338086135258688413818311946826093":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "cos (16.0) == -0.9576594803233846418996372326511034717803"
+ ildouble: 2
+ ldouble: 2
++# cos_upward
++Test "cos_upward (1) == 0.5403023058681397174009366074429766037323":
++ildouble: 2
++ldouble: 2
++Test "cos_upward (10) == -0.8390715290764524522588639478240648345199":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (4) == -0.6536436208636119146391681830977503814241":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (5) == 0.2836621854632262644666391715135573083344":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (6) == 0.9601702866503660205456522979229244054519":
++float: 1
++ifloat: 1
++Test "cos_upward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (9) == -0.9111302618846769883682947111811653112463":
++float: 2
++ifloat: 2
++
++# cosh_downward
++Test "cosh_downward (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 5269156250720
++ldouble: 5269156250720
++Test "cosh_downward (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 484603564240
++ldouble: 484603564240
++Test "cosh_downward (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ifloat: 1
++ildouble: 89137844202
++ldouble: 89137844202
++
++# cosh_tonearest
++Test "cosh_tonearest (22) == 1792456423.065795780980053377632656584997":
++ildouble: 5269156250719
++ldouble: 5269156250719
++Test "cosh_tonearest (23) == 4872401723.124451300068625740569997090344":
++ildouble: 484603564240
++ldouble: 484603564240
++Test "cosh_tonearest (24) == 13244561064.92173614708845674912733665919":
++ildouble: 89137844202
++ldouble: 89137844202
++
++# cosh_towardzero
++Test "cosh_towardzero (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 5269156250720
++ldouble: 5269156250720
++Test "cosh_towardzero (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 484603564240
++ldouble: 484603564240
++Test "cosh_towardzero (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ifloat: 1
++ildouble: 89137844202
++ldouble: 89137844202
++
++# cosh_upward
++Test "cosh_upward (22) == 1792456423.065795780980053377632656584997":
++ildouble: 5269156250719
++ldouble: 5269156250719
++Test "cosh_upward (23) == 4872401723.124451300068625740569997090344":
++ildouble: 484603564240
++ldouble: 484603564240
++Test "cosh_upward (24) == 13244561064.92173614708845674912733665919":
++ildouble: 89137844200
++ldouble: 89137844200
++
+ # cpow
+ Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+ float: 1
+@@ -386,12 +506,6 @@ float: 1
+ ifloat: 1
+ # ctan
+-Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+-double: 1
+-idouble: 1
+-Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+-ildouble: 1
+-ldouble: 1
+ Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ double: 1
+ idouble: 1
+@@ -463,6 +577,33 @@ Test "exp2 (10) == 1024":
+ ildouble: 2
+ ldouble: 2
++# exp_downward
++Test "exp_downward (2) == e^2":
++float: 1
++ifloat: 1
++Test "exp_downward (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_towardzero
++Test "exp_towardzero (2) == e^2":
++float: 1
++ifloat: 1
++Test "exp_towardzero (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_upward
++Test "exp_upward (1) == e":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ # expm1
+ Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+ double: 1
+@@ -505,40 +646,27 @@ ifloat: 1
+ # j0
+ Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
+-ildouble: 1
+-ldouble: 1
++ifloat: 1
+ Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 2
+ float: 1
+-idouble: 3
++idouble: 2
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+-Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+-float: 2
+-ifloat: 2
+ Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
+-ildouble: 1
+-ldouble: 1
++ifloat: 1
+ Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+ float: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ # j1
+ Test "j1 (10.0) == 0.0434727461688614366697487680258592883":
+ float: 2
+ ifloat: 2
+-ildouble: 1
+-ldouble: 1
+ Test "j1 (2.0) == 0.576724807756873387202448242269137087":
+ double: 1
+ idouble: 1
+@@ -551,38 +679,25 @@ ldouble: 1
+ # jn
+ Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
+-ildouble: 1
+-ldouble: 1
++ifloat: 1
+ Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 2
+ float: 1
+-idouble: 3
++idouble: 2
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+-Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+-float: 2
+-ifloat: 2
+ Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
+-ildouble: 1
+-ldouble: 1
++ifloat: 1
+ Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+ float: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+ float: 2
+ ifloat: 2
+-ildouble: 1
+-ldouble: 1
+ Test "jn (1, 2.0) == 0.576724807756873387202448242269137087":
+ double: 1
+ idouble: 1
+@@ -615,11 +730,8 @@ ifloat: 1
+ ildouble: 4
+ ldouble: 4
+ Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+-float: 4
+-ifloat: 4
+-Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083":
+-ildouble: 1
+-ldouble: 1
++float: 3
++ifloat: 3
+ Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+ double: 1
+ float: 1
+@@ -628,21 +740,18 @@ ifloat: 1
+ Test "jn (3, 0.75) == 0.848438342327410884392755236884386804e-2":
+ double: 1
+ idouble: 1
+-Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083":
+-ildouble: 1
+-ldouble: 1
+ Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+ double: 3
+-float: 2
++float: 1
+ idouble: 3
+-ifloat: 2
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -675,115 +784,350 @@ Test "log1p (-0.25) == -0.28768207245178
+ float: 1
+ ifloat: 1
+-# log2
+-Test "log2 (e) == M_LOG2El":
++# pow_downward
++Test "pow_downward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+ ildouble: 1
+ ldouble: 1
+-
+-# sin
+-Test "sin (16.0) == -0.2879033166650652947844562482186175296207"
+-ildouble: 2
+-ldouble: 2
+-
+-# sincos
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+-double: 1
+-float: 1
+-idouble: 1
+-ifloat: 1
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+-double: 1
++Test "pow_downward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+-double: 1
++
++# pow_towardzero
++Test "pow_towardzero (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
++ildouble: 1
++ldouble: 1
++Test "pow_towardzero (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++
++# pow_upward
++Test "pow_upward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+ float: 1
+ ifloat: 1
+-
+-# sinh
+-Test "sinh (0.75) == 0.822316731935829980703661634446913849":
++Test "pow_upward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ ildouble: 1
+ ldouble: 1
+-# tan
+-Test "tan (pi/4) == 1":
+-double: 1
+-idouble: 1
++# sin_downward
++Test "sin_downward (1) == 0.8414709848078965066525023216302989996226":
++ildouble: 4
++ldouble: 4
++Test "sin_downward (10) == -0.5440211108893698134047476618513772816836":
++float: 1
++ifloat: 1
++Test "sin_downward (2) == 0.9092974268256816953960198659117448427023":
+ ildouble: 1
+ ldouble: 1
+-
+-# tanh
+-Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
++Test "sin_downward (3) == 0.1411200080598672221007448028081102798469":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "sin_downward (4) == -0.7568024953079282513726390945118290941359":
+ ildouble: 1
+ ldouble: 1
+-Test "tanh (0.75) == 0.635148952387287319214434357312496495":
++Test "sin_downward (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++Test "sin_downward (6) == -0.2794154981989258728115554466118947596280":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "sin_downward (8) == 0.9893582466233817778081235982452886721164":
+ ildouble: 1
+ ldouble: 1
+-# tgamma
+-Test "tgamma (-0.5) == -2 sqrt (pi)":
+-double: 1
++# sin_tonearest
++Test "sin_tonearest (1) == 0.8414709848078965066525023216302989996226":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "tgamma (0.5) == sqrt (pi)":
++
++# sin_towardzero
++Test "sin_towardzero (1) == 0.8414709848078965066525023216302989996226":
+ float: 1
+ ifloat: 1
+-Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+-double: 1
++ildouble: 2
++ldouble: 2
++Test "sin_towardzero (10) == -0.5440211108893698134047476618513772816836":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-
+-# y0
+-Test "y0 (0.125) == -1.38968062514384052915582277745018693":
++Test "sin_towardzero (2) == 0.9092974268256816953960198659117448427023":
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (0.75) == -0.137172769385772397522814379396581855":
++Test "sin_towardzero (3) == 0.1411200080598672221007448028081102798469":
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
+-double: 2
++Test "sin_towardzero (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_towardzero (5) == -0.9589242746631384688931544061559939733525":
+ float: 1
+-idouble: 2
+ ifloat: 1
++Test "sin_towardzero (8) == 0.9893582466233817778081235982452886721164":
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (1.5) == 0.382448923797758843955068554978089862":
+-double: 2
++Test "sin_towardzero (9) == 0.4121184852417565697562725663524351793439":
+ float: 1
+-idouble: 2
+ ifloat: 1
+-Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
++ildouble: 1
++ldouble: 1
++
++# sin_upward
++Test "sin_upward (1) == 0.8414709848078965066525023216302989996226":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "sin_upward (2) == 0.9092974268256816953960198659117448427023":
++float: 2
++ifloat: 2
++Test "sin_upward (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_upward (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (9) == 0.4121184852417565697562725663524351793439":
++float: 1
++ifloat: 1
++
++# sincos
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
++double: 1
++idouble: 1
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
++Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++float: 1
++ifloat: 1
++
++# sinh
++Test "sinh (0.75) == 0.822316731935829980703661634446913849":
+ ildouble: 1
+ ldouble: 1
+-Test "y0 (2.0) == 0.510375672649745119596606592727157873":
++
++# sinh_downward
++Test "sinh_downward (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 5269156250718
++ldouble: 5269156250718
++Test "sinh_downward (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++ildouble: 484603564240
++ldouble: 484603564240
++Test "sinh_downward (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ildouble: 89137844201
++ldouble: 89137844201
++
++# sinh_tonearest
++Test "sinh_tonearest (22) == 1792456423.065795780701106568345764104225":
++ildouble: 5269156250719
++ldouble: 5269156250719
++Test "sinh_tonearest (23) == 4872401723.124451299966006944252978187305":
++ildouble: 484603564241
++ldouble: 484603564241
++Test "sinh_tonearest (24) == 13244561064.92173614705070540368454568168":
++ildouble: 89137844201
++ldouble: 89137844201
++
++# sinh_towardzero
++Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 5269156250718
++ldouble: 5269156250718
++Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++ildouble: 484603564240
++ldouble: 484603564240
++Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ildouble: 89137844201
++ldouble: 89137844201
++
++# sinh_upward
++Test "sinh_upward (22) == 1792456423.065795780701106568345764104225":
++ildouble: 5269156250719
++ldouble: 5269156250719
++Test "sinh_upward (23) == 4872401723.124451299966006944252978187305":
++ildouble: 484603564241
++ldouble: 484603564241
++Test "sinh_upward (24) == 13244561064.92173614705070540368454568168":
++ildouble: 89137844202
++ldouble: 89137844202
++
++# tan
++Test "tan (pi/4) == 1":
++ildouble: 1
++ldouble: 1
++
++# tan_downward
++Test "tan_downward (1) == 1.5574077246549022305069748074583601730873":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "tan_downward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "tan_downward (2) == -2.1850398632615189916433061023136825434320":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (6) == -0.2910061913847491570536995888681755428312":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (8) == -6.7997114552203786999252627596086333648814":
++float: 1
++ifloat: 1
++Test "tan_downward (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# tan_tonearest
++Test "tan_tonearest (10) == 0.6483608274590866712591249330098086768169":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (4) == 1.1578212823495775831373424182673239231198":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (7) == 0.8714479827243187364564508896003135663222":
++ildouble: 1
++ldouble: 1
++
++# tan_towardzero
++Test "tan_towardzero (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 3
++ldouble: 3
++Test "tan_towardzero (4) == 1.1578212823495775831373424182673239231198":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++Test "tan_towardzero (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (7) == 0.8714479827243187364564508896003135663222":
++ildouble: 2
++ldouble: 2
++Test "tan_towardzero (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# tan_upward
++Test "tan_upward (10) == 0.6483608274590866712591249330098086768169":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 3
++ldouble: 3
++Test "tan_upward (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (7) == 0.8714479827243187364564508896003135663222":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (9) == -0.4523156594418098405903708757987855343087":
++ildouble: 1
++ldouble: 1
++
++# tanh
++Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
++ildouble: 1
++ldouble: 1
++Test "tanh (0.75) == 0.635148952387287319214434357312496495":
++ildouble: 1
++ldouble: 1
++
++# tgamma
++Test "tgamma (-0.5) == -2 sqrt (pi)":
+ double: 1
++float: 1
+ idouble: 1
+-Test "y0 (8.0) == 0.223521489387566220527323400498620359":
++ifloat: 1
++Test "tgamma (0.5) == sqrt (pi)":
++float: 1
++ifloat: 1
++Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
++
++# y0
++Test "y0 (0.125) == -1.38968062514384052915582277745018693":
+ ildouble: 1
+ ldouble: 1
+-
+-# y1
+-Test "y1 (0.125) == -5.19993611253477499595928744876579921":
++Test "y0 (1.0) == 0.0882569642156769579829267660235151628":
++double: 2
++float: 1
++idouble: 2
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "y0 (1.5) == 0.382448923797758843955068554978089862":
++double: 2
++float: 1
++idouble: 2
++ifloat: 1
++Test "y0 (10.0) == 0.0556711672835993914244598774101900481":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "y0 (2.0) == 0.510375672649745119596606592727157873":
+ double: 1
+ idouble: 1
+-Test "y1 (1.5) == -0.412308626973911295952829820633445323":
++Test "y0 (8.0) == 0.223521489387566220527323400498620359":
++double: 1
+ float: 1
++idouble: 1
+ ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# y1
+ Test "y1 (10.0) == 0.249015424206953883923283474663222803":
+ double: 3
+ float: 1
+@@ -794,30 +1138,27 @@ ldouble: 2
+ Test "y1 (2.0) == -0.107032431540937546888370772277476637":
+ double: 1
+ float: 1
+-idouble: 2
+-ifloat: 2
++idouble: 1
++ifloat: 1
+ Test "y1 (8.0) == -0.158060461731247494255555266187483550":
+ double: 1
+ float: 2
+ idouble: 1
+ ifloat: 2
+-ildouble: 2
+-ldouble: 2
++ildouble: 1
++ldouble: 1
+ # yn
+ Test "yn (0, 0.125) == -1.38968062514384052915582277745018693":
+ ildouble: 1
+ ldouble: 1
+-Test "yn (0, 0.75) == -0.137172769385772397522814379396581855":
+-ildouble: 1
+-ldouble: 1
+ Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628":
+ double: 2
+ float: 1
+ idouble: 2
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
++ildouble: 1
++ldouble: 1
+ Test "yn (0, 1.5) == 0.382448923797758843955068554978089862":
+ double: 2
+ float: 1
+@@ -828,8 +1169,6 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+ Test "yn (0, 2.0) == 0.510375672649745119596606592727157873":
+ double: 1
+ idouble: 1
+@@ -838,14 +1177,8 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+-Test "yn (1, 0.125) == -5.19993611253477499595928744876579921":
+-double: 1
+-idouble: 1
+-Test "yn (1, 1.5) == -0.412308626973911295952829820633445323":
+-float: 2
+-ifloat: 2
++ildouble: 1
++ldouble: 1
+ Test "yn (1, 10.0) == 0.249015424206953883923283474663222803":
+ double: 3
+ float: 1
+@@ -863,14 +1196,8 @@ double: 1
+ float: 2
+ idouble: 1
+ ifloat: 2
+-ildouble: 2
+-ldouble: 2
+-Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+-double: 1
+-idouble: 1
+-Test "yn (10, 0.125) == -127057845771019398.252538486899753195":
+-double: 1
+-idouble: 1
++ildouble: 1
++ldouble: 1
+ Test "yn (10, 0.75) == -2133501638.90573424452445412893839236":
+ double: 1
+ float: 2
+@@ -881,21 +1208,14 @@ float: 2
+ ifloat: 2
+ Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+ double: 2
+-float: 2
+ idouble: 2
+-ifloat: 2
+-ildouble: 2
+-ldouble: 2
+ Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+ double: 3
+ float: 1
+ idouble: 3
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+-Test "yn (3, 0.125) == -2612.69757350066712600220955744091741":
+-double: 1
+-idouble: 1
++ildouble: 1
++ldouble: 1
+ Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+ float: 1
+ ifloat: 1
+@@ -904,8 +1224,8 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
++ildouble: 1
++ldouble: 1
+ Test "yn (3, 2.0) == -1.12778377684042778608158395773179238":
+ double: 1
+ idouble: 1
+@@ -950,18 +1270,12 @@ ildouble: 1
+ ldouble: 1
+ Function: Real part of "cacosh":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+ ildouble: 1
+ ldouble: 1
+ Function: Imaginary part of "cacosh":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
++float: 1
++ifloat: 1
+ Function: Real part of "casin":
+ double: 1
+@@ -992,8 +1306,6 @@ ildouble: 1
+ ldouble: 1
+ Function: Real part of "catan":
+-float: 4
+-ifloat: 4
+ ildouble: 1
+ ldouble: 1
+@@ -1009,10 +1321,6 @@ Function: Real part of "catanh":
+ double: 4
+ idouble: 4
+-Function: Imaginary part of "catanh":
+-float: 6
+-ifloat: 6
+-
+ Function: "cbrt":
+ double: 1
+ idouble: 1
+@@ -1066,8 +1374,6 @@ ildouble: 2
+ ldouble: 2
+ Function: Imaginary part of "clog":
+-float: 3
+-ifloat: 3
+ ildouble: 1
+ ldouble: 1
+@@ -1079,9 +1385,9 @@ ldouble: 3
+ Function: Imaginary part of "clog10":
+ double: 1
+-float: 5
++float: 1
+ idouble: 1
+-ifloat: 5
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1093,10 +1399,54 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "cos_downward":
++float: 1
++ifloat: 1
++ildouble: 4
++ldouble: 4
++
++Function: "cos_tonearest":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "cos_upward":
++float: 2
++ifloat: 2
++ildouble: 2
++ldouble: 2
++
+ Function: "cosh":
+ ildouble: 1
+ ldouble: 1
++Function: "cosh_downward":
++float: 1
++ifloat: 1
++ildouble: 5269156250720
++ldouble: 5269156250720
++
++Function: "cosh_tonearest":
++ildouble: 5269156250719
++ldouble: 5269156250719
++
++Function: "cosh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 5269156250720
++ldouble: 5269156250720
++
++Function: "cosh_upward":
++ildouble: 5269156250719
++ldouble: 5269156250719
++
+ Function: Real part of "cpow":
+ double: 2
+ float: 5
+@@ -1113,10 +1463,6 @@ ifloat: 2
+ ildouble: 2
+ ldouble: 2
+-Function: Imaginary part of "cproj":
+-ildouble: 1
+-ldouble: 1
+-
+ Function: Real part of "csin":
+ ildouble: 1
+ ldouble: 1
+@@ -1146,8 +1492,6 @@ ildouble: 1
+ ldouble: 1
+ Function: Real part of "ctan":
+-double: 1
+-idouble: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1201,6 +1545,28 @@ Function: "exp2":
+ ildouble: 2
+ ldouble: 2
++Function: "exp_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "exp_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "exp_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "exp_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ Function: "expm1":
+ double: 1
+ float: 1
+@@ -1218,10 +1584,10 @@ ildouble: 1
+ ldouble: 1
+ Function: "j0":
+-double: 3
+-float: 2
+-idouble: 3
+-ifloat: 2
++double: 2
++float: 1
++idouble: 2
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1235,9 +1601,9 @@ ldouble: 1
+ Function: "jn":
+ double: 3
+-float: 4
++float: 3
+ idouble: 3
+-ifloat: 4
++ifloat: 3
+ ildouble: 4
+ ldouble: 4
+@@ -1264,8 +1630,6 @@ ldouble: 1
+ Function: "log1p":
+ float: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ Function: "log2":
+ ildouble: 1
+@@ -1275,10 +1639,52 @@ Function: "pow":
+ ildouble: 1
+ ldouble: 1
++Function: "pow_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ Function: "sin":
+ ildouble: 1
+ ldouble: 1
++Function: "sin_downward":
++float: 1
++ifloat: 1
++ildouble: 4
++ldouble: 4
++
++Function: "sin_tonearest":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "sin_upward":
++float: 2
++ifloat: 2
++ildouble: 2
++ldouble: 2
++
+ Function: "sincos":
+ double: 1
+ float: 1
+@@ -1291,12 +1697,54 @@ Function: "sinh":
+ ildouble: 1
+ ldouble: 1
++Function: "sinh_downward":
++float: 1
++ifloat: 1
++ildouble: 5269156250718
++ldouble: 5269156250718
++
++Function: "sinh_tonearest":
++ildouble: 5269156250719
++ldouble: 5269156250719
++
++Function: "sinh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 5269156250718
++ldouble: 5269156250718
++
++Function: "sinh_upward":
++ildouble: 5269156250719
++ldouble: 5269156250719
++
+ Function: "tan":
+ double: 1
+ idouble: 1
+ ildouble: 1
+ ldouble: 1
++Function: "tan_downward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "tan_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "tan_towardzero":
++float: 1
++ifloat: 1
++ildouble: 3
++ldouble: 3
++
++Function: "tan_upward":
++float: 1
++ifloat: 1
++ildouble: 3
++ldouble: 3
++
+ Function: "tanh":
+ ildouble: 1
+ ldouble: 1
+diff -Nrup a/sysdeps/s390/fpu/libm-test-ulps b/sysdeps/s390/fpu/libm-test-ulps
+--- a/sysdeps/s390/fpu/libm-test-ulps  2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/s390/fpu/libm-test-ulps  2012-08-06 09:54:38.324772546 -0600
+@@ -31,16 +31,9 @@ ildouble: 1
+ ldouble: 1
+ # cacosh
+-Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+ Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -83,17 +76,11 @@ ildouble: 1
+ ldouble: 1
+ # catan
+-Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+-float: 3
+-ifloat: 3
+ Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+-float: 4
+-ifloat: 4
+ Test "Imaginary part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+ ildouble: 1
+ ldouble: 1
+@@ -102,17 +89,12 @@ ldouble: 1
+ Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+ double: 4
+ idouble: 4
+-Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+-float: 4
+-ifloat: 4
+ Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+ double: 1
+ idouble: 1
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+-float: 6
+-ifloat: 6
+ ildouble: 1
+ ldouble: 1
+@@ -185,9 +167,6 @@ ildouble: 1
+ ldouble: 1
+ # clog
+-Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+-float: 3
+-ifloat: 3
+ Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+ float: 1
+ ifloat: 1
+@@ -210,9 +189,7 @@ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ double: 1
+-float: 5
+ idouble: 1
+-ifloat: 5
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+@@ -288,9 +265,7 @@ ifloat: 1
+ # cos
+ Test "cos (M_PI_6l * 2.0) == 0.5":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "cos (M_PI_6l * 4.0) == -0.5":
+@@ -300,11 +275,159 @@ idouble: 2
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "cos (pi/2) == 0":
+-double: 1
++
++# cos_downward
++Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_downward (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (4) == -0.6536436208636119146391681830977503814241":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (6) == 0.9601702866503660205456522979229244054519":
++ildouble: 1
++ldouble: 1
++Test "cos_downward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (8) == -0.1455000338086135258688413818311946826093":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++# cos_tonearest
++Test "cos_tonearest (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++
++# cos_towardzero
++Test "cos_towardzero (1) == 0.5403023058681397174009366074429766037323":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (4) == -0.6536436208636119146391681830977503814241":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (6) == 0.9601702866503660205456522979229244054519":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (8) == -0.1455000338086135258688413818311946826093":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++# cos_upward
++Test "cos_upward (10) == -0.8390715290764524522588639478240648345199":
++float: 1
++ifloat: 1
++Test "cos_upward (6) == 0.9601702866503660205456522979229244054519":
++float: 1
++ifloat: 1
++Test "cos_upward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++Test "cos_upward (9) == -0.9111302618846769883682947111811653112463":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++
++# cosh_downward
++Test "cosh_downward (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_downward (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_downward (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# cosh_tonearest
++Test "cosh_tonearest (22) == 1792456423.065795780980053377632656584997":
++ildouble: 1
++ldouble: 1
++
++# cosh_towardzero
++Test "cosh_towardzero (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_towardzero (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_towardzero (24) == 13244561064.92173614708845674912733665919":
+ float: 1
+-idouble: 1
+ ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# cosh_upward
++Test "cosh_upward (22) == 1792456423.065795780980053377632656584997":
++ildouble: 1
++ldouble: 1
++Test "cosh_upward (23) == 4872401723.124451300068625740569997090344":
++ildouble: 1
++ldouble: 1
++Test "cosh_upward (24) == 13244561064.92173614708845674912733665919":
++ildouble: 1
++ldouble: 1
+ # cpow
+ Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+@@ -393,8 +516,6 @@ ldouble: 1
+ # ctan
+ Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+-double: 1
+-idouble: 1
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+@@ -467,6 +588,37 @@ Test "exp2 (10) == 1024":
+ ildouble: 2
+ ldouble: 2
++# exp_downward
++Test "exp_downward (2) == e^2":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "exp_downward (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_towardzero
++Test "exp_towardzero (2) == e^2":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "exp_towardzero (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_upward
++Test "exp_upward (1) == e":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ # expm1
+ Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+ double: 1
+@@ -513,29 +665,27 @@ ifloat: 1
+ # j0
+ Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ Test "j0 (0.75) == 0.864242275166648623555731103820923211":
+ float: 1
+ ifloat: 1
+ Test "j0 (10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 2
+ float: 1
+-idouble: 3
++idouble: 2
+ ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "j0 (2.0) == 0.223890779141235668051827454649948626":
+-float: 2
+-ifloat: 2
+ ildouble: 2
+ ldouble: 2
+ Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+ float: 1
+ ifloat: 1
+@@ -569,29 +719,27 @@ ldouble: 4
+ # jn
+ Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ Test "jn (0, 0.75) == 0.864242275166648623555731103820923211":
+ float: 1
+ ifloat: 1
+ Test "jn (0, 10.0) == -0.245935764451348335197760862485328754":
+-double: 3
++double: 2
+ float: 1
+-idouble: 3
++idouble: 2
+ ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "jn (0, 2.0) == 0.223890779141235668051827454649948626":
+-float: 2
+-ifloat: 2
+ ildouble: 2
+ ldouble: 2
+ Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+ float: 1
+ ifloat: 1
+@@ -640,15 +788,13 @@ Test "jn (10, 1.0) == 0.2630615123687453
+ ildouble: 1
+ ldouble: 1
+ Test "jn (10, 10.0) == 0.207486106633358857697278723518753428":
+-double: 4
+-float: 3
+-idouble: 4
+-ifloat: 3
++float: 1
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6":
+-float: 4
+-ifloat: 4
++float: 3
++ifloat: 3
+ Test "jn (3, 0.125) == 0.406503832554912875023029337653442868e-4":
+ double: 1
+ float: 1
+@@ -661,16 +807,16 @@ idouble: 1
+ ifloat: 1
+ Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563":
+ double: 3
+-float: 2
++float: 1
+ idouble: 3
+-ifloat: 2
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "jn (3, 2.0) == 0.128943249474402051098793332969239835":
+ double: 1
+-float: 2
++float: 1
+ idouble: 1
+-ifloat: 2
++ifloat: 1
+ # lgamma
+ Test "lgamma (-0.5) == log(2*sqrt(pi))":
+@@ -713,71 +859,315 @@ Test "log2 (0.75) == -.41503749927884381
+ ildouble: 1
+ ldouble: 1
+-# sincos
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+-double: 1
++# pow_downward
++Test "pow_downward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+-double: 1
++
++# pow_towardzero
++Test "pow_towardzero (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
++float: 1
++ifloat: 1
++
++# pow_upward
++Test "pow_upward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+-double: 1
++
++# sin_downward
++Test "sin_downward (1) == 0.8414709848078965066525023216302989996226":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (10) == -0.5440211108893698134047476618513772816836":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++Test "sin_downward (2) == 0.9092974268256816953960198659117448427023":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (3) == 0.1411200080598672221007448028081102798469":
+ float: 1
+ ifloat: 1
+-
+-# sqrt
+-Test "sqrt (2) == M_SQRT2l":
+ ildouble: 1
+ ldouble: 1
+-
+-# tan
+-Test "tan (pi/4) == 1":
+-double: 1
+-idouble: 1
+-
+-# tanh
+-Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
++Test "sin_downward (4) == -0.7568024953079282513726390945118290941359":
+ ildouble: 1
+ ldouble: 1
+-Test "tanh (-1.0) == -0.7615941559557648881194582826047935904":
++Test "sin_downward (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "tanh (0.75) == 0.635148952387287319214434357312496495":
++Test "sin_downward (6) == -0.2794154981989258728115554466118947596280":
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "tanh (1.0) == 0.7615941559557648881194582826047935904":
++Test "sin_downward (8) == 0.9893582466233817778081235982452886721164":
+ ildouble: 1
+ ldouble: 1
+-# tgamma
+-Test "tgamma (-0.5) == -2 sqrt (pi)":
+-double: 1
++# sin_tonearest
++Test "sin_tonearest (1) == 0.8414709848078965066525023216302989996226":
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "tgamma (0.5) == sqrt (pi)":
++Test "sin_tonearest (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (9) == 0.4121184852417565697562725663524351793439":
++ildouble: 1
++ldouble: 1
++
++# sin_towardzero
++Test "sin_towardzero (1) == 0.8414709848078965066525023216302989996226":
+ float: 1
+ ifloat: 1
+-Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
+-double: 1
++Test "sin_towardzero (10) == -0.5440211108893698134047476618513772816836":
+ float: 1
+-idouble: 1
+ ifloat: 1
+-Test "tgamma (4) == 6":
++Test "sin_towardzero (2) == 0.9092974268256816953960198659117448427023":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_towardzero (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (8) == 0.9893582466233817778081235982452886721164":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (9) == 0.4121184852417565697562725663524351793439":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++# sin_upward
++Test "sin_upward (1) == 0.8414709848078965066525023216302989996226":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_upward (10) == -0.5440211108893698134047476618513772816836":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (2) == 0.9092974268256816953960198659117448427023":
++float: 2
++ifloat: 2
++Test "sin_upward (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_upward (7) == 0.6569865987187890903969990915936351779369":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (9) == 0.4121184852417565697562725663524351793439":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# sincos
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
++double: 1
++idouble: 1
++ildouble: 1
++ldouble: 1
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++float: 1
++ifloat: 1
++
++# sinh_downward
++Test "sinh_downward (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sinh_downward (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "sinh_downward (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# sinh_towardzero
++Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++
++# sinh_upward
++Test "sinh_upward (22) == 1792456423.065795780701106568345764104225":
++ildouble: 1
++ldouble: 1
++Test "sinh_upward (23) == 4872401723.124451299966006944252978187305":
++ildouble: 1
++ldouble: 1
++Test "sinh_upward (24) == 13244561064.92173614705070540368454568168":
++ildouble: 1
++ldouble: 1
++
++# sqrt
++Test "sqrt (2) == M_SQRT2l":
++ildouble: 1
++ldouble: 1
++
++# tan_downward
++Test "tan_downward (1) == 1.5574077246549022305069748074583601730873":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_downward (2) == -2.1850398632615189916433061023136825434320":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (6) == -0.2910061913847491570536995888681755428312":
++float: 1
++ifloat: 1
++Test "tan_downward (8) == -6.7997114552203786999252627596086333648814":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++
++# tan_towardzero
++Test "tan_towardzero (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (4) == 1.1578212823495775831373424182673239231198":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# tan_upward
++Test "tan_upward (1) == 1.5574077246549022305069748074583601730873":
++float: 1
++ifloat: 1
++Test "tan_upward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (4) == 1.1578212823495775831373424182673239231198":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (9) == -0.4523156594418098405903708757987855343087":
++ildouble: 1
++ldouble: 1
++
++# tanh
++Test "tanh (-0.75) == -0.635148952387287319214434357312496495":
++ildouble: 1
++ldouble: 1
++Test "tanh (-1.0) == -0.7615941559557648881194582826047935904":
++ildouble: 1
++ldouble: 1
++Test "tanh (0.75) == 0.635148952387287319214434357312496495":
++ildouble: 1
++ldouble: 1
++Test "tanh (1.0) == 0.7615941559557648881194582826047935904":
++ildouble: 1
++ldouble: 1
++
++# tgamma
++Test "tgamma (-0.5) == -2 sqrt (pi)":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tgamma (0.5) == sqrt (pi)":
++float: 1
++ifloat: 1
++Test "tgamma (0.7) == 1.29805533264755778568117117915281162":
++double: 1
++float: 1
++idouble: 1
++ifloat: 1
++Test "tgamma (4) == 6":
+ ildouble: 1
+ ldouble: 1
+@@ -917,17 +1307,13 @@ ifloat: 2
+ ildouble: 5
+ ldouble: 5
+ Test "yn (10, 1.0) == -121618014.278689189288130426667971145":
+-double: 1
+ float: 2
+-idouble: 1
+ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+ Test "yn (10, 10.0) == -0.359814152183402722051986577343560609":
+ double: 2
+-float: 2
+ idouble: 2
+-ifloat: 2
+ ildouble: 2
+ ldouble: 2
+ Test "yn (10, 2.0) == -129184.542208039282635913145923304214":
+@@ -941,9 +1327,7 @@ Test "yn (3, 0.125) == -2612.69757350066
+ double: 1
+ idouble: 1
+ Test "yn (3, 0.75) == -12.9877176234475433186319774484809207":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -973,17 +1357,9 @@ Function: Imaginary part of "cacos":
+ ildouble: 1
+ ldouble: 1
+-Function: Real part of "cacosh":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+-
+ Function: Imaginary part of "cacosh":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1013,10 +1389,6 @@ ifloat: 6
+ ildouble: 2
+ ldouble: 2
+-Function: Real part of "catan":
+-float: 4
+-ifloat: 4
+-
+ Function: Imaginary part of "catan":
+ double: 1
+ float: 1
+@@ -1032,8 +1404,6 @@ ildouble: 1
+ ldouble: 1
+ Function: Imaginary part of "catanh":
+-float: 6
+-ifloat: 6
+ ildouble: 1
+ ldouble: 1
+@@ -1089,10 +1459,6 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Function: Imaginary part of "clog":
+-float: 3
+-ifloat: 3
+-
+ Function: Real part of "clog10":
+ float: 1
+ ifloat: 1
+@@ -1101,9 +1467,9 @@ ldouble: 1
+ Function: Imaginary part of "clog10":
+ double: 1
+-float: 5
++float: 1
+ idouble: 1
+-ifloat: 5
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1115,6 +1481,48 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "cos_downward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "cos_tonearest":
++float: 1
++ifloat: 1
++
++Function: "cos_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "cos_upward":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_upward":
++ildouble: 1
++ldouble: 1
++
+ Function: Real part of "cpow":
+ double: 2
+ float: 4
+@@ -1162,8 +1570,6 @@ ildouble: 1
+ ldouble: 1
+ Function: Real part of "ctan":
+-double: 1
+-idouble: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1211,6 +1617,24 @@ Function: "exp2":
+ ildouble: 2
+ ldouble: 2
++Function: "exp_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "exp_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "exp_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ Function: "expm1":
+ double: 1
+ float: 1
+@@ -1228,10 +1652,10 @@ float: 1
+ ifloat: 1
+ Function: "j0":
+-double: 3
+-float: 2
+-idouble: 3
+-ifloat: 2
++double: 2
++float: 1
++idouble: 2
++ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -1244,10 +1668,10 @@ ildouble: 4
+ ldouble: 4
+ Function: "jn":
+-double: 4
+-float: 4
+-idouble: 4
+-ifloat: 4
++double: 3
++float: 3
++idouble: 3
++ifloat: 3
+ ildouble: 4
+ ldouble: 4
+@@ -1277,6 +1701,44 @@ Function: "log2":
+ ildouble: 1
+ ldouble: 1
++Function: "pow_downward":
++float: 1
++ifloat: 1
++
++Function: "pow_towardzero":
++float: 1
++ifloat: 1
++
++Function: "pow_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_tonearest":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "sin_upward":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++
+ Function: "sincos":
+ double: 1
+ float: 1
+@@ -1285,6 +1747,22 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "sinh_downward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "sinh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "sinh_upward":
++ildouble: 1
++ldouble: 1
++
+ Function: "sqrt":
+ ildouble: 1
+ ldouble: 1
+@@ -1293,6 +1771,24 @@ Function: "tan":
+ double: 1
+ idouble: 1
++Function: "tan_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "tan_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "tan_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
+ Function: "tanh":
+ ildouble: 1
+ ldouble: 1
+diff -Nrup a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
+--- a/sysdeps/x86_64/fpu/libm-test-ulps        2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/x86_64/fpu/libm-test-ulps        2012-08-06 11:02:14.602759422 -0600
+@@ -42,26 +42,13 @@ ldouble: 1
+ # cacos
+ Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i":
+-float: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ # cacosh
+-Test "Real part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+-ildouble: 6
+-ldouble: 6
+ Test "Imaginary part of: cacosh (-2 - 3 i) == 1.9833870299165354323470769028940395 - 2.1414491111159960199416055713254211 i":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
+-ildouble: 1
+-ldouble: 1
++float: 1
++ifloat: 1
+ Test "Real part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i":
+ ildouble: 1
+ ldouble: 1
+@@ -75,8 +62,6 @@ ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i":
+-float: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -103,21 +88,15 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ldouble: 1
+ ildouble: 1
++ldouble: 1
+ # catan
+-Test "Real part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+-float: 3
+-ifloat: 3
+ Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i":
+ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i":
+-float: 4
+-ifloat: 4
+ # catanh
+ Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+@@ -125,15 +104,9 @@ double: 4
+ idouble: 4
+ ildouble: 1
+ ldouble: 1
+-Test "Imaginary part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i":
+-float: 4
+-ifloat: 4
+ Test "Real part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+ double: 1
+ idouble: 1
+-Test "Imaginary part of: catanh (0.75 + 1.25 i) == 0.261492138795671927078652057366532140 + 0.996825126463918666098902241310446708 i":
+-float: 6
+-ifloat: 6
+ # cbrt
+ Test "cbrt (-0.001) == -0.1":
+@@ -152,14 +125,9 @@ ildouble: 1
+ ldouble: 1
+ # ccos
+-Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+-double: 1
+-idouble: 1
+ Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i":
+ float: 1
+ ifloat: 1
+-ildouble: 1
+-ldouble: 1
+ Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+ double: 1
+ float: 1
+@@ -168,19 +136,17 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i":
+-ildouble: 1
+-ldouble: 1
+ float: 1
+ ifloat: 1
++ildouble: 1
++ldouble: 1
+ # ccosh
+ Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+ float: 1
+ ifloat: 1
+ Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -205,9 +171,6 @@ ildouble: 1
+ ldouble: 1
+ # clog
+-Test "Imaginary part of: clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i":
+-float: 3
+-ifloat: 3
+ Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i":
+ float: 1
+ ifloat: 1
+@@ -227,11 +190,7 @@ idouble: 1
+ ifloat: 1
+ Test "Imaginary part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i":
+ double: 1
+-float: 5
+ idouble: 1
+-ifloat: 5
+-ildouble: 1
+-ldouble: 1
+ Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i":
+ double: 1
+ float: 1
+@@ -276,9 +235,7 @@ float: 1
+ idouble: 1
+ ifloat: 1
+ Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -306,33 +263,164 @@ ifloat: 1
+ # cos
+ Test "cos (M_PI_6l * 2.0) == 0.5":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ Test "cos (M_PI_6l * 4.0) == -0.5":
+ double: 2
+ float: 1
+ idouble: 2
+ ifloat: 1
++
++# cos_downward
++Test "cos_downward (1) == 0.5403023058681397174009366074429766037323":
++float: 1
++ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "cos (pi/2) == 0":
+-double: 1
++Test "cos_downward (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++Test "cos_downward (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++Test "cos_downward (4) == -0.6536436208636119146391681830977503814241":
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "cos (0.80190127184058835) == 0.69534156199418473":
+-double: 1
+-idouble: 1
++Test "cos_downward (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_downward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (8) == -0.1455000338086135258688413818311946826093":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_downward (9) == -0.9111302618846769883682947111811653112463":
++ildouble: 1
++ldouble: 1
++
++# cos_tonearest
++Test "cos_tonearest (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++Test "cos_tonearest (8) == -0.1455000338086135258688413818311946826093":
++ildouble: 1
++ldouble: 1
++Test "cos_tonearest (9) == -0.9111302618846769883682947111811653112463":
++ildouble: 1
++ldouble: 1
++
++# cos_towardzero
++Test "cos_towardzero (1) == 0.5403023058681397174009366074429766037323":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (10) == -0.8390715290764524522588639478240648345199":
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (2) == -0.4161468365471423869975682295007621897660":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (3) == -0.9899924966004454572715727947312613023937":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (5) == 0.2836621854632262644666391715135573083344":
++float: 1
++ifloat: 1
++Test "cos_towardzero (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_towardzero (8) == -0.1455000338086135258688413818311946826093":
++float: 1
++ifloat: 1
++
++# cos_upward
++Test "cos_upward (10) == -0.8390715290764524522588639478240648345199":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (2) == -0.4161468365471423869975682295007621897660":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (3) == -0.9899924966004454572715727947312613023937":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (5) == 0.2836621854632262644666391715135573083344":
++ildouble: 1
++ldouble: 1
++Test "cos_upward (6) == 0.9601702866503660205456522979229244054519":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cos_upward (7) == 0.7539022543433046381411975217191820122183":
++float: 1
++ifloat: 1
++Test "cos_upward (9) == -0.9111302618846769883682947111811653112463":
++float: 2
++ifloat: 2
++
++# cosh_downward
++Test "cosh_downward (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "cosh_downward (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_downward (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# cosh_tonearest
++Test "cosh_tonearest (22) == 1792456423.065795780980053377632656584997":
++ildouble: 1
++ldouble: 1
++
++# cosh_towardzero
++Test "cosh_towardzero (22) == 1792456423.065795780980053377632656584997":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "cosh_towardzero (23) == 4872401723.124451300068625740569997090344":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "cosh_towardzero (24) == 13244561064.92173614708845674912733665919":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# cosh_upward
++Test "cosh_upward (23) == 4872401723.124451300068625740569997090344":
++ildouble: 1
++ldouble: 1
+ # cpow
+ Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+ float: 1
+ ifloat: 1
+-ldouble: 1
+ ildouble: 1
++ldouble: 1
+ Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i":
+ float: 1
+ ifloat: 1
+@@ -363,9 +451,9 @@ ildouble: 1
+ ldouble: 1
+ Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+ double: 1
+-float: 5
++float: 4
+ idouble: 1
+-ifloat: 5
++ifloat: 4
+ Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i":
+ float: 2
+ ifloat: 2
+@@ -383,22 +471,11 @@ ldouble: 1
+ Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+ ildouble: 1
+ ldouble: 1
+-Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i":
+-float: 1
+-ifloat: 1
+-Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i":
+-double: 1
+-idouble: 1
+ # csinh
+-Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+-double: 1
+-idouble: 1
+ Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i":
+ double: 1
+ idouble: 1
+-ildouble: 2
+-ldouble: 2
+ Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i":
+ float: 1
+ ifloat: 1
+@@ -418,37 +495,31 @@ ifloat: 1
+ # ctan
+ Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+-double: 1
+-idouble: 1
+-ildouble: 439
+-ldouble: 439
++ildouble: 1
++ldouble: 1
+ Test "Imaginary part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i":
+-float: 1
+-ifloat: 1
+-ildouble: 2
+-ldouble: 2
++ildouble: 1
++ldouble: 1
+ Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ ildouble: 1
+ ldouble: 1
+ Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 3
+ ldouble: 3
+ # ctanh
+ Test "Real part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+-float: 2
+-ifloat: 2
+-ildouble: 5
+-ldouble: 5
+ double: 1
++float: 2
+ idouble: 1
++ifloat: 2
++ildouble: 3
++ldouble: 3
+ Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i":
+-ildouble: 25
+-ldouble: 25
++ildouble: 1
++ldouble: 1
+ Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+ float: 1
+ ifloat: 1
+@@ -456,10 +527,10 @@ Test "Real part of: ctanh (0.75 + 1.25 i
+ double: 1
+ idouble: 1
+ Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i":
+-ildouble: 1
+-ldouble: 1
+ double: 1
+ idouble: 1
++ildouble: 1
++ldouble: 1
+ # erf
+ Test "erf (1.25) == 0.922900128256458230136523481197281140":
+@@ -481,26 +552,61 @@ ldouble: 1
+ # exp10
+ Test "exp10 (-1) == 0.1":
+-ildouble: 1
+-ldouble: 1
+-float: 1
+-ifloat: 1
+ double: 2
+-idouble: 2
+-Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+-ildouble: 2
+-ldouble: 2
+ float: 1
++idouble: 2
+ ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "exp10 (0.75) == 5.62341325190349080394951039776481231":
+ double: 1
++float: 1
+ idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
+ Test "exp10 (3) == 1000":
+-ildouble: 8
+-ldouble: 8
+-float: 2
+-ifloat: 2
+ double: 6
++float: 2
+ idouble: 6
++ifloat: 2
++ildouble: 3
++ldouble: 3
++
++# exp_downward
++Test "exp_downward (1) == e":
++ildouble: 1
++ldouble: 1
++Test "exp_downward (2) == e^2":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "exp_downward (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_towardzero
++Test "exp_towardzero (1) == e":
++ildouble: 1
++ldouble: 1
++Test "exp_towardzero (2) == e^2":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++Test "exp_towardzero (3) == e^3":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# exp_upward
++Test "exp_upward (1) == e":
++float: 1
++ifloat: 1
+ # expm1
+ Test "expm1 (0.75) == 1.11700001661267466854536981983709561":
+@@ -570,9 +676,7 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "j0 (8.0) == 0.171650807137553906090869407851972001":
+-double: 2
+ float: 1
+-idouble: 2
+ ifloat: 1
+ # j1
+@@ -617,9 +721,7 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Test "jn (0, 8.0) == 0.171650807137553906090869407851972001":
+-double: 2
+ float: 1
+-idouble: 2
+ ifloat: 1
+ Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883":
+ float: 2
+@@ -714,12 +816,12 @@ ldouble: 1
+ # log10
+ Test "log10 (0.75) == -0.124938736608299953132449886193870744":
+-ildouble: 1
+-ldouble: 1
+-float: 2
+-ifloat: 2
+ double: 1
++float: 2
+ idouble: 1
++ifloat: 2
++ildouble: 1
++ldouble: 1
+ Test "log10 (e) == log10(e)":
+ float: 1
+ ifloat: 1
+@@ -731,37 +833,309 @@ Test "log1p (-0.25) == -0.28768207245178
+ float: 1
+ ifloat: 1
+-# sincos
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+-double: 1
+-float: 1
+-idouble: 1
+-ifloat: 1
+-Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+-double: 1
+-float: 1
+-idouble: 1
+-ifloat: 1
++# pow_downward
++Test "pow_downward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
+ ildouble: 1
+ ldouble: 1
+-Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res":
+-double: 1
++Test "pow_downward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++
++# pow_towardzero
++Test "pow_towardzero (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
++ildouble: 1
++ldouble: 1
++Test "pow_towardzero (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# pow_upward
++Test "pow_upward (1.0625, 1.125) == 1.070582293028761362162622578677070098674":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "pow_upward (1.5, 1.03125) == 1.519127098714743184071644334163037684948":
++ildouble: 1
++ldouble: 1
++
++# sin_downward
++Test "sin_downward (1) == 0.8414709848078965066525023216302989996226":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (10) == -0.5440211108893698134047476618513772816836":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (3) == 0.1411200080598672221007448028081102798469":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (4) == -0.7568024953079282513726390945118290941359":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sin_downward (6) == -0.2794154981989258728115554466118947596280":
++float: 1
++ifloat: 1
++Test "sin_downward (7) == 0.6569865987187890903969990915936351779369":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (8) == 0.9893582466233817778081235982452886721164":
++ildouble: 1
++ldouble: 1
++Test "sin_downward (9) == 0.4121184852417565697562725663524351793439":
++ildouble: 1
++ldouble: 1
++
++# sin_tonearest
++Test "sin_tonearest (1) == 0.8414709848078965066525023216302989996226":
++float: 1
++ifloat: 1
++Test "sin_tonearest (10) == -0.5440211108893698134047476618513772816836":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (4) == -0.7568024953079282513726390945118290941359":
++ildouble: 1
++ldouble: 1
++Test "sin_tonearest (9) == 0.4121184852417565697562725663524351793439":
++ildouble: 1
++ldouble: 1
++
++# sin_towardzero
++Test "sin_towardzero (1) == 0.8414709848078965066525023216302989996226":
+ float: 1
+ ifloat: 1
+-Test "sincos (0.80190127184058835, &sin_res, &cos_res) puts 0.69534156199418473 in cos_res":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (10) == -0.5440211108893698134047476618513772816836":
++float: 1
++ifloat: 1
++Test "sin_towardzero (3) == 0.1411200080598672221007448028081102798469":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_towardzero (5) == -0.9589242746631384688931544061559939733525":
++float: 1
++ifloat: 1
++Test "sin_towardzero (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (7) == 0.6569865987187890903969990915936351779369":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (8) == 0.9893582466233817778081235982452886721164":
++ildouble: 1
++ldouble: 1
++Test "sin_towardzero (9) == 0.4121184852417565697562725663524351793439":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# sin_upward
++Test "sin_upward (1) == 0.8414709848078965066525023216302989996226":
++float: 1
++ifloat: 1
++Test "sin_upward (2) == 0.9092974268256816953960198659117448427023":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++Test "sin_upward (4) == -0.7568024953079282513726390945118290941359":
++float: 1
++ifloat: 1
++Test "sin_upward (6) == -0.2794154981989258728115554466118947596280":
++ildouble: 1
++ldouble: 1
++Test "sin_upward (9) == 0.4121184852417565697562725663524351793439":
++float: 1
++ifloat: 1
++
++# sincos
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res":
+ double: 1
+ idouble: 1
+-
+-# tan
+-Test "tan (pi/4) == 1":
++Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res":
+ double: 1
++float: 1
+ idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res":
++float: 1
++ifloat: 1
++
++# sinh_downward
++Test "sinh_downward (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 4
++ldouble: 4
++Test "sinh_downward (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++Test "sinh_downward (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ildouble: 5
++ldouble: 5
++
++# sinh_tonearest
++Test "sinh_tonearest (22) == 1792456423.065795780701106568345764104225":
++ildouble: 3
++ldouble: 3
++Test "sinh_tonearest (23) == 4872401723.124451299966006944252978187305":
++ildouble: 1
++ldouble: 1
++Test "sinh_tonearest (24) == 13244561064.92173614705070540368454568168":
++ildouble: 6
++ldouble: 6
++
++# sinh_towardzero
++Test "sinh_towardzero (22) == 1792456423.065795780701106568345764104225":
++float: 1
++ifloat: 1
++ildouble: 4
++ldouble: 4
++Test "sinh_towardzero (23) == 4872401723.124451299966006944252978187305":
++float: 1
++ifloat: 1
++Test "sinh_towardzero (24) == 13244561064.92173614705070540368454568168":
++float: 1
++ifloat: 1
++ildouble: 5
++ldouble: 5
++
++# sinh_upward
++Test "sinh_upward (22) == 1792456423.065795780701106568345764104225":
++ildouble: 16
++ldouble: 16
++Test "sinh_upward (23) == 4872401723.124451299966006944252978187305":
++ildouble: 27
++ldouble: 27
++Test "sinh_upward (24) == 13244561064.92173614705070540368454568168":
++ildouble: 7
++ldouble: 7
++
++# tan_downward
++Test "tan_downward (1) == 1.5574077246549022305069748074583601730873":
++float: 1
++ifloat: 1
++Test "tan_downward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_downward (2) == -2.1850398632615189916433061023136825434320":
++float: 1
++ifloat: 1
++Test "tan_downward (4) == 1.1578212823495775831373424182673239231198":
++ildouble: 1
++ldouble: 1
++Test "tan_downward (5) == -3.3805150062465856369827058794473439087096":
++ildouble: 1
++ldouble: 1
++Test "tan_downward (6) == -0.2910061913847491570536995888681755428312":
++float: 1
++ifloat: 1
++Test "tan_downward (8) == -6.7997114552203786999252627596086333648814":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_downward (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++
++# tan_tonearest
++Test "tan_tonearest (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (8) == -6.7997114552203786999252627596086333648814":
++ildouble: 1
++ldouble: 1
++Test "tan_tonearest (9) == -0.4523156594418098405903708757987855343087":
++ildouble: 1
++ldouble: 1
++
++# tan_towardzero
++Test "tan_towardzero (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++Test "tan_towardzero (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (4) == 1.1578212823495775831373424182673239231198":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++Test "tan_towardzero (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_towardzero (8) == -6.7997114552203786999252627596086333648814":
++ildouble: 2
++ldouble: 2
++Test "tan_towardzero (9) == -0.4523156594418098405903708757987855343087":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++# tan_upward
++Test "tan_upward (1) == 1.5574077246549022305069748074583601730873":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (10) == 0.6483608274590866712591249330098086768169":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (2) == -2.1850398632615189916433061023136825434320":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (3) == -0.1425465430742778052956354105339134932261":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++Test "tan_upward (5) == -3.3805150062465856369827058794473439087096":
++float: 1
++ifloat: 1
++Test "tan_upward (6) == -0.2910061913847491570536995888681755428312":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (7) == 0.8714479827243187364564508896003135663222":
++ildouble: 1
++ldouble: 1
++Test "tan_upward (8) == -6.7997114552203786999252627596086333648814":
++ildouble: 2
++ldouble: 2
++Test "tan_upward (9) == -0.4523156594418098405903708757987855343087":
++ildouble: 1
++ldouble: 1
+ # tgamma
+ Test "tgamma (-0.5) == -2 sqrt (pi)":
+@@ -779,9 +1153,6 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-Test "tgamma (4) == 6":
+-ildouble: 1
+-ldouble: 1
+ # y0
+ Test "y0 (0.125) == -1.38968062514384052915582277745018693":
+@@ -960,27 +1331,17 @@ ildouble: 1
+ ldouble: 1
+ Function: Imaginary part of "cacos":
+-float: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+ Function: Real part of "cacosh":
+-double: 1
+-float: 7
+-idouble: 1
+-ifloat: 7
+-ildouble: 6
+-ldouble: 6
+-
+-Function: Imaginary part of "cacosh":
+-double: 1
+-float: 3
+-idouble: 1
+-ifloat: 3
+ ildouble: 1
+ ldouble: 1
++Function: Imaginary part of "cacosh":
++float: 1
++ifloat: 1
++
+ Function: Real part of "casin":
+ double: 1
+ float: 1
+@@ -990,8 +1351,6 @@ ildouble: 2
+ ldouble: 2
+ Function: Imaginary part of "casin":
+-float: 1
+-ifloat: 1
+ ildouble: 2
+ ldouble: 2
+@@ -1011,10 +1370,6 @@ ifloat: 6
+ ildouble: 5
+ ldouble: 5
+-Function: Real part of "catan":
+-float: 4
+-ifloat: 4
+-
+ Function: Imaginary part of "catan":
+ double: 1
+ float: 1
+@@ -1027,10 +1382,6 @@ idouble: 4
+ ildouble: 1
+ ldouble: 1
+-Function: Imaginary part of "catanh":
+-float: 6
+-ifloat: 6
+-
+ Function: "cbrt":
+ double: 1
+ idouble: 1
+@@ -1058,9 +1409,7 @@ idouble: 1
+ ifloat: 1
+ Function: Imaginary part of "ccosh":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1081,25 +1430,17 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+-Function: Imaginary part of "clog":
+-float: 3
+-ifloat: 3
+-
+ Function: Real part of "clog10":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+ Function: Imaginary part of "clog10":
+ double: 1
+-float: 5
++float: 1
+ idouble: 1
+-ifloat: 5
+-ildouble: 1
+-ldouble: 1
++ifloat: 1
+ Function: "cos":
+ double: 2
+@@ -1109,11 +1450,55 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "cos_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_tonearest":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "cos_upward":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_downward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "cosh_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "cosh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "cosh_upward":
++ildouble: 1
++ldouble: 1
++
+ Function: Real part of "cpow":
+ double: 2
+-float: 5
++float: 4
+ idouble: 2
+-ifloat: 5
++ifloat: 4
+ ildouble: 5
+ ldouble: 5
+@@ -1129,16 +1514,8 @@ Function: Real part of "csin":
+ ildouble: 1
+ ldouble: 1
+-Function: Imaginary part of "csin":
+-double: 1
+-float: 1
+-idouble: 1
+-ifloat: 1
+-
+ Function: Real part of "csinh":
+-double: 1
+ float: 1
+-idouble: 1
+ ifloat: 1
+ ildouble: 1
+ ldouble: 1
+@@ -1148,24 +1525,18 @@ double: 1
+ float: 1
+ idouble: 1
+ ifloat: 1
+-ildouble: 2
+-ldouble: 2
+ Function: Real part of "csqrt":
+ float: 1
+ ifloat: 1
+ Function: Real part of "ctan":
+-double: 1
+-idouble: 1
+-ildouble: 439
+-ldouble: 439
++ildouble: 1
++ldouble: 1
+ Function: Imaginary part of "ctan":
+ double: 1
+-float: 1
+ idouble: 1
+-ifloat: 1
+ ildouble: 3
+ ldouble: 3
+@@ -1174,16 +1545,16 @@ double: 1
+ float: 2
+ idouble: 1
+ ifloat: 2
+-ildouble: 5
+-ldouble: 5
++ildouble: 3
++ldouble: 3
+ Function: Imaginary part of "ctanh":
+-float: 1
+-ifloat: 1
+-ildouble: 25
+-ldouble: 25
+ double: 1
++float: 1
+ idouble: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
+ Function: "erf":
+ double: 1
+@@ -1196,12 +1567,28 @@ ildouble: 1
+ ldouble: 1
+ Function: "exp10":
+-ildouble: 8
+-ldouble: 8
+-float: 2
+-ifloat: 2
+ double: 6
++float: 2
+ idouble: 6
++ifloat: 2
++ildouble: 3
++ldouble: 3
++
++Function: "exp_downward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "exp_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "exp_upward":
++float: 1
++ifloat: 1
+ Function: "expm1":
+ double: 1
+@@ -1250,17 +1637,59 @@ ildouble: 1
+ ldouble: 1
+ Function: "log10":
++double: 1
+ float: 2
++idouble: 1
+ ifloat: 2
+ ildouble: 1
+ ldouble: 1
+-double: 1
+-idouble: 1
+ Function: "log1p":
+ float: 1
+ ifloat: 1
++Function: "pow_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "pow_upward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_tonearest":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_towardzero":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "sin_upward":
++float: 2
++ifloat: 2
++ildouble: 1
++ldouble: 1
++
+ Function: "sincos":
+ double: 1
+ float: 1
+@@ -1269,10 +1698,52 @@ ifloat: 1
+ ildouble: 1
+ ldouble: 1
++Function: "sinh_downward":
++float: 1
++ifloat: 1
++ildouble: 5
++ldouble: 5
++
++Function: "sinh_tonearest":
++ildouble: 6
++ldouble: 6
++
++Function: "sinh_towardzero":
++float: 1
++ifloat: 1
++ildouble: 5
++ldouble: 5
++
++Function: "sinh_upward":
++ildouble: 27
++ldouble: 27
++
+ Function: "tan":
+ double: 1
+ idouble: 1
++Function: "tan_downward":
++float: 1
++ifloat: 1
++ildouble: 1
++ldouble: 1
++
++Function: "tan_tonearest":
++ildouble: 1
++ldouble: 1
++
++Function: "tan_towardzero":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
++Function: "tan_upward":
++float: 1
++ifloat: 1
++ildouble: 2
++ldouble: 2
++
+ Function: "tgamma":
+ double: 1
+ float: 1
+diff -Nrup a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h
+--- a/sysdeps/x86_64/fpu/math_private.h        2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/x86_64/fpu/math_private.h        2012-08-06 09:54:00.893929393 -0600
+@@ -56,3 +56,82 @@ do {                                                                \
+ } while (0)
+ #endif
++
++
++/* Specialized variants of the <fenv.h> interfaces which only handle
++   either the FPU or the SSE unit.  */
++#undef libc_fegetround
++#define libc_fegetround() \
++  ({                                                                        \
++     unsigned int mxcsr;                                                    \
++     asm volatile ("stmxcsr %0" : "=m" (*&mxcsr));                          \
++     (mxcsr & 0x6000) >> 3;                                                 \
++  })
++#undef libc_fegetroundf
++#define libc_fegetroundf() libc_fegetround ()
++// #define libc_fegetroundl() fegetround ()
++
++#undef libc_fesetround
++#define libc_fesetround(r) \
++  do {                                                                              \
++     unsigned int mxcsr;                                                    \
++     asm ("stmxcsr %0" : "=m" (*&mxcsr));                                   \
++     mxcsr = (mxcsr & ~0x6000) | ((r) << 3);                                \
++     asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr));                         \
++  } while (0)
++#undef libc_fesetroundf
++#define libc_fesetroundf(r) libc_fesetround (r)
++// #define libc_fesetroundl(r) (void) fesetround (r)
++
++#undef libc_feholdexcept
++#define libc_feholdexcept(e) \
++  do {                                                                              \
++     unsigned int mxcsr;                                                    \
++     asm ("stmxcsr %0" : "=m" (*&mxcsr));                                   \
++     (e)->__mxcsr = mxcsr;                                                  \
++     mxcsr = (mxcsr | 0x1f80) & ~0x3f;                                              \
++     asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr));                         \
++  } while (0)
++#undef libc_feholdexceptf
++#define libc_feholdexceptf(e) libc_feholdexcept (e)
++// #define libc_feholdexceptl(e) (void) feholdexcept (e)
++
++#undef libc_feholdexcept_setround
++#define libc_feholdexcept_setround(e, r) \
++  do {                                                                              \
++     unsigned int mxcsr;                                                    \
++     asm ("stmxcsr %0" : "=m" (*&mxcsr));                                   \
++     (e)->__mxcsr = mxcsr;                                                  \
++     mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3);                             \
++     asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr));                         \
++  } while (0)
++#undef libc_feholdexcept_setroundf
++#define libc_feholdexcept_setroundf(e, r) libc_feholdexcept_setround (e, r)
++// #define libc_feholdexcept_setroundl(e, r) ...
++
++#undef libc_fetestexcept
++#define libc_fetestexcept(e) \
++  ({ unsigned int mxcsr; asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
++     mxcsr & (e) & FE_ALL_EXCEPT; })
++#undef libc_fetestexceptf
++#define libc_fetestexceptf(e) libc_fetestexcept (e)
++// #define libc_fetestexceptl(e) fetestexcept (e)
++
++#undef libc_fesetenv
++#define libc_fesetenv(e) \
++  asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr))
++#undef libc_fesetenvf
++#define libc_fesetenvf(e) libc_fesetenv (e)
++// #define libc_fesetenvl(e) (void) fesetenv (e)
++
++#undef libc_feupdateenv
++#define libc_feupdateenv(e) \
++  do {                                                                              \
++    unsigned int mxcsr;                                                             \
++    asm volatile ("stmxcsr %0" : "=m" (*&mxcsr));                           \
++    asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr));                             \
++    feraiseexcept (mxcsr & FE_ALL_EXCEPT);                                  \
++  } while (0)
++#undef libc_feupdateenvf
++#define libc_feupdateenvf(e) libc_feupdateenv (e)
++// #define libc_feupdateenvl(e) (void) feupdateenv (e)
diff --git a/src/patches/glibc/glibc-rh841787.patch b/src/patches/glibc/glibc-rh841787.patch
new file mode 100644 (file)
index 0000000..3cec783
--- /dev/null
@@ -0,0 +1,42 @@
+diff -rup a/resolv/res_init.c b/resolv/res_init.c
+--- a/resolv/res_init.c        2012-07-26 15:10:45.655638776 -0600
++++ b/resolv/res_init.c        2012-07-26 15:11:27.731423002 -0600
+@@ -314,9 +314,9 @@ __res_vinit(res_state statp, int preinit
+                       cp++;
+                   if ((*cp != '\0') && (*cp != '\n')
+                       && __inet_aton(cp, &a)) {
+-                      statp->nsaddr_list[nservall].sin_addr = a;
+-                      statp->nsaddr_list[nservall].sin_family = AF_INET;
+-                      statp->nsaddr_list[nservall].sin_port =
++                      statp->nsaddr_list[nserv].sin_addr = a;
++                      statp->nsaddr_list[nserv].sin_family = AF_INET;
++                      statp->nsaddr_list[nserv].sin_port =
+                               htons(NAMESERVER_PORT);
+                       nserv++;
+ #ifdef _LIBC
+diff -rup a/resolv/res_send.c b/resolv/res_send.c
+--- a/resolv/res_send.c        2010-05-04 05:27:23.000000000 -0600
++++ b/resolv/res_send.c        2012-07-26 15:34:58.398261659 -0600
+@@ -421,10 +421,10 @@ __libc_res_nsend(res_state statp, const
+                               EXT(statp).nsmap[n] = MAXNS;
+                       }
+               }
+-              n = statp->nscount;
+-              if (statp->nscount > EXT(statp).nscount)
++              n = statp->nscount - EXT(statp).nscount6;
++              if (n > EXT(statp).nscount)
+                       for (n = EXT(statp).nscount, ns = 0;
+-                           n < statp->nscount; n++) {
++                           n < statp->nscount - EXT(statp).nscount6; n++) {
+                               while (ns < MAXNS
+                                      && EXT(statp).nsmap[ns] != MAXNS)
+                                       ns++;
+@@ -441,7 +441,7 @@ __libc_res_nsend(res_state statp, const
+                                   malloc(sizeof (struct sockaddr_in6));
+                       if (EXT(statp).nsaddrs[n] != NULL) {
+                               memset (mempcpy(EXT(statp).nsaddrs[n],
+-                                              &statp->nsaddr_list[n],
++                                              &statp->nsaddr_list[ns],
+                                               sizeof (struct sockaddr_in)),
+                                       '\0',
+                                       sizeof (struct sockaddr_in6)
diff --git a/src/patches/glibc/glibc-rh843673.patch b/src/patches/glibc/glibc-rh843673.patch
new file mode 100644 (file)
index 0000000..a2ff262
--- /dev/null
@@ -0,0 +1,31 @@
+diff -Brup a/stdlib/msort.c b/stdlib/msort.c
+--- a/stdlib/msort.c   2010-05-04 07:27:23.000000000 -0400
++++ b/stdlib/msort.c   2012-08-07 13:30:14.131765346 -0400
+@@ -25,6 +25,8 @@
+ #include <unistd.h>
+ #include <memcopy.h>
+ #include <errno.h>
++#include <atomic.h>
++
+ struct msort_param
+ {
+@@ -182,7 +184,7 @@ qsort_r (void *b, size_t n, size_t s, __
+       static long int phys_pages;
+       static int pagesize;
+-      if (phys_pages == 0)
++      if (pagesize == 0)
+       {
+         phys_pages = __sysconf (_SC_PHYS_PAGES);
+@@ -197,6 +199,9 @@ qsort_r (void *b, size_t n, size_t s, __
+            a quarter of the physical memory.  */
+         phys_pages /= 4;
++          /* Make sure phys_pages is written to memory.  */
++          atomic_write_barrier ();
++
+         pagesize = __sysconf (_SC_PAGESIZE);
+       }
diff --git a/src/patches/glibc/glibc-rh846342.patch b/src/patches/glibc/glibc-rh846342.patch
new file mode 100644 (file)
index 0000000..8cfca05
--- /dev/null
@@ -0,0 +1,48 @@
+This is a workaround for broken code which issues memcpy requests with
+overlapping arguments.  With this patch installed, if the file
+/etc/sysconfig/32bit_ssse3_memcpy_via_32bit_ssse3_memmove exists then a
+32bit memcpy call which normally would be handled by the SSSE3 memcpy
+implementation would instead be handled by the 32bit SSSE3 memmove
+implementation which is more tolerant of overlaps.
+
+diff -Nrup a/sysdeps/i386/i686/multiarch/memcpy.S b/sysdeps/i386/i686/multiarch/memcpy.S
+--- a/sysdeps/i386/i686/multiarch/memcpy.S     2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/i386/i686/multiarch/memcpy.S     2012-11-20 14:19:52.890780415 -0700
+@@ -21,6 +21,10 @@
+ #include <sysdep.h>
+ #include <init-arch.h>
++        .section .rodata
++L(magicfile):
++      .ascii "/etc/sysconfig/32bit_ssse3_memcpy_via_32bit_ssse3_memmove"
++
+ /* Define multiple versions only for the definition in lib and for
+    DSO.  In static binaries we need memcpy before the initialization
+    happened.  */
+@@ -48,6 +52,26 @@ ENTRY(memcpy)
+ 1:    leal    __memcpy_ia32@GOTOFF(%ebx), %eax
+       testl   $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
+       jz      2f
++
++      /* This is an inlined access (magicfile, 0) syscall.  
++
++         Note that it clobbers %ebx, so we have to save/restore
++         it around the syscall.  */
++      mov     %ebx, %edx
++      leal    L(magicfile)@GOTOFF(%ebx), %ebx
++      xor     %ecx, %ecx
++      movl    $33, %eax
++      int     $0x80
++      mov     %edx, %ebx
++
++      /* If the file did not exist, then %eax will be -1..-4095 and we
++         do nothing special.  */
++      cmpl    $-4095, %eax
++      jae     4f
++
++      leal    __memmove_ssse3@GOTOFF(%ebx), %eax
++      jmp     2f
++4:
+       leal    __memcpy_ssse3@GOTOFF(%ebx), %eax
+       testl   $bit_Fast_Rep_String, FEATURE_OFFSET+index_Fast_Rep_String+__cpu_features@GOTOFF(%ebx)
+       jz      2f
diff --git a/src/patches/glibc/glibc-rh847932.patch b/src/patches/glibc/glibc-rh847932.patch
new file mode 100644 (file)
index 0000000..33ea851
--- /dev/null
@@ -0,0 +1,364 @@
+diff -Nrup a/stdlib/Makefile b/stdlib/Makefile
+--- a/stdlib/Makefile  2010-05-04 05:27:23.000000000 -0600
++++ b/stdlib/Makefile  2012-08-15 09:25:37.812443006 -0600
+@@ -71,7 +71,7 @@ tests                := tst-strtol tst-strtod testmb t
+                  tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
+                  tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2       \
+                  tst-makecontext2 tst-strtod6 tst-unsetenv1               \
+-                 tst-makecontext3
++                 tst-makecontext3 tst-strtod-overflow
+ include ../Makeconfig
+diff -Nrup a/stdlib/strtod_l.c b/stdlib/strtod_l.c
+--- a/stdlib/strtod_l.c        2010-05-04 05:27:23.000000000 -0600
++++ b/stdlib/strtod_l.c        2012-08-15 09:34:29.550281346 -0600
+@@ -62,6 +62,7 @@ extern unsigned long long int ____strtou
+ #include <math.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <stdint.h>
+ /* The gmp headers need some configuration frobs.  */
+ #define HAVE_ALLOCA 1
+@@ -176,19 +177,19 @@ extern const mp_limb_t _tens_in_limb[MAX
+ /* Return a floating point number of the needed type according to the given
+    multi-precision number after possible rounding.  */
+ static FLOAT
+-round_and_return (mp_limb_t *retval, int exponent, int negative,
++round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
+                 mp_limb_t round_limb, mp_size_t round_bit, int more_bits)
+ {
+   if (exponent < MIN_EXP - 1)
+     {
+-      mp_size_t shift = MIN_EXP - 1 - exponent;
+-
+-      if (shift > MANT_DIG)
++      if (exponent < MIN_EXP - 1 - MANT_DIG)
+       {
+         __set_errno (EDOM);
+         return 0.0;
+       }
++      mp_size_t shift = MIN_EXP - 1 - exponent;
++
+       more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
+       if (shift == MANT_DIG)
+       /* This is a special case to handle the very seldom case where
+@@ -235,6 +236,9 @@ round_and_return (mp_limb_t *retval, int
+       __set_errno (ERANGE);
+     }
++  if (exponent > MAX_EXP)
++    goto overflow;
++
+   if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
+       && (more_bits || (retval[0] & 1) != 0
+         || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
+@@ -260,6 +264,7 @@ round_and_return (mp_limb_t *retval, int
+     }
+   if (exponent > MAX_EXP)
++  overflow:
+     return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+   return MPN2FLOAT (retval, exponent, negative);
+@@ -273,7 +278,7 @@ round_and_return (mp_limb_t *retval, int
+    factor for the resulting number (see code) multiply by it.  */
+ static const STRING_TYPE *
+ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
+-          int *exponent
++          intmax_t *exponent
+ #ifndef USE_WIDE_CHAR
+           , const char *decimal, size_t decimal_len, const char *thousands
+ #endif
+@@ -337,7 +342,7 @@ str_to_mpn (const STRING_TYPE *str, int
+     }
+   while (--digcnt > 0);
+-  if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB)
++  if (*exponent > 0 && *exponent <= MAX_DIG_PER_LIMB - cnt)
+     {
+       low *= _tens_in_limb[*exponent];
+       start = _tens_in_limb[cnt + *exponent];
+@@ -415,7 +420,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+ {
+   int negative;                       /* The sign of the number.  */
+   MPN_VAR (num);              /* MP representation of the number.  */
+-  int exponent;                       /* Exponent of the number.  */
++  intmax_t exponent;          /* Exponent of the number.  */
+   /* Numbers starting `0X' or `0x' have to be processed with base 16.  */
+   int base = 10;
+@@ -437,7 +442,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+   /* Points at the character following the integer and fractional digits.  */
+   const STRING_TYPE *expp;
+   /* Total number of digit and number of digits in integer part.  */
+-  int dig_no, int_no, lead_zero;
++  size_t dig_no, int_no, lead_zero;
+   /* Contains the last character read.  */
+   CHAR_TYPE c;
+@@ -769,7 +774,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+      are all or any is really a fractional digit will be decided
+      later.  */
+   int_no = dig_no;
+-  lead_zero = int_no == 0 ? -1 : 0;
++  lead_zero = int_no == 0 ? (size_t) -1 : 0;
+   /* Read the fractional digits.  A special case are the 'american
+      style' numbers like `16.' i.e. with decimal point but without
+@@ -791,12 +796,13 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+            (base == 16 && ({ CHAR_TYPE lo = TOLOWER (c);
+                              lo >= L_('a') && lo <= L_('f'); })))
+       {
+-        if (c != L_('0') && lead_zero == -1)
++        if (c != L_('0') && lead_zero == (size_t) -1)
+           lead_zero = dig_no - int_no;
+         ++dig_no;
+         c = *++cp;
+       }
+     }
++  assert (dig_no <= (uintmax_t) INTMAX_MAX);
+   /* Remember start of exponent (if any).  */
+   expp = cp;
+@@ -819,24 +825,80 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+       if (c >= L_('0') && c <= L_('9'))
+       {
+-        int exp_limit;
++        intmax_t exp_limit;
+         /* Get the exponent limit. */
+         if (base == 16)
+-          exp_limit = (exp_negative ?
+-                       -MIN_EXP + MANT_DIG + 4 * int_no :
+-                       MAX_EXP - 4 * int_no + 4 * lead_zero + 3);
++          {
++            if (exp_negative)
++              {
++                assert (int_no <= (uintmax_t) (INTMAX_MAX
++                                               + MIN_EXP - MANT_DIG) / 4);
++                exp_limit = -MIN_EXP + MANT_DIG + 4 * (intmax_t) int_no;
++              }
++            else
++              {
++                if (int_no)
++                  {
++                    assert (lead_zero == 0
++                            && int_no <= (uintmax_t) INTMAX_MAX / 4);
++                    exp_limit = MAX_EXP - 4 * (intmax_t) int_no + 3;
++                  }
++                else if (lead_zero == (size_t) -1)
++                  {
++                    /* The number is zero and this limit is
++                       arbitrary.  */
++                    exp_limit = MAX_EXP + 3;
++                  }
++                else
++                  {
++                    assert (lead_zero
++                            <= (uintmax_t) (INTMAX_MAX - MAX_EXP - 3) / 4);
++                    exp_limit = (MAX_EXP
++                                 + 4 * (intmax_t) lead_zero
++                                 + 3);
++                  }
++              }
++          }
+         else
+-          exp_limit = (exp_negative ?
+-                       -MIN_10_EXP + MANT_DIG + int_no :
+-                       MAX_10_EXP - int_no + lead_zero + 1);
++          {
++            if (exp_negative)
++              {
++                assert (int_no
++                        <= (uintmax_t) (INTMAX_MAX + MIN_10_EXP - MANT_DIG));
++                exp_limit = -MIN_10_EXP + MANT_DIG + (intmax_t) int_no;
++              }
++            else
++              {
++                if (int_no)
++                  {
++                    assert (lead_zero == 0
++                            && int_no <= (uintmax_t) INTMAX_MAX);
++                    exp_limit = MAX_10_EXP - (intmax_t) int_no + 1;
++                  }
++                else if (lead_zero == (size_t) -1)
++                  {
++                    /* The number is zero and this limit is
++                       arbitrary.  */
++                    exp_limit = MAX_10_EXP + 1;
++                  }
++                else
++                  {
++                    assert (lead_zero
++                            <= (uintmax_t) (INTMAX_MAX - MAX_10_EXP - 1));
++                    exp_limit = MAX_10_EXP + (intmax_t) lead_zero + 1;
++                  }
++              }
++          }
++
++        if (exp_limit < 0)
++          exp_limit = 0;
+         do
+           {
+-            exponent *= 10;
+-            exponent += c - L_('0');
+-
+-            if (__builtin_expect (exponent > exp_limit, 0))
++            if (__builtin_expect ((exponent > exp_limit / 10
++                                  || (exponent == exp_limit / 10
++                                      && c - L_('0') > exp_limit % 10)), 0))
+               /* The exponent is too large/small to represent a valid
+                  number.  */
+               {
+@@ -845,7 +907,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+                 /* We have to take care for special situation: a joker
+                    might have written "0.0e100000" which is in fact
+                    zero.  */
+-                if (lead_zero == -1)
++                if (lead_zero == (size_t) -1)
+                   result = negative ? -0.0 : 0.0;
+                 else
+                   {
+@@ -864,6 +926,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+                 /* NOTREACHED */
+               }
++            exponent *= 10;
++            exponent += c - L_('0');
++
+             c = *++cp;
+           }
+         while (c >= L_('0') && c <= L_('9'));
+@@ -932,7 +997,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+       }
+ #endif
+       startp += lead_zero + decimal_len;
+-      exponent -= base == 16 ? 4 * lead_zero : lead_zero;
++      assert (lead_zero <= (base == 16
++                          ? (uintmax_t) INTMAX_MAX / 4
++                          : (uintmax_t) INTMAX_MAX));
++      assert (lead_zero <= (base == 16
++                          ? ((uintmax_t) exponent
++                             - (uintmax_t) INTMAX_MIN) / 4
++                          : ((uintmax_t) exponent - (uintmax_t) INTMAX_MIN)));
++      exponent -= base == 16 ? 4 * (intmax_t) lead_zero : (intmax_t) lead_zero;
+       dig_no -= lead_zero;
+     }
+@@ -974,7 +1046,10 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+       }
+       /* Adjust the exponent for the bits we are shifting in.  */
+-      exponent += bits - 1 + (int_no - 1) * 4;
++      assert (int_no <= (uintmax_t) (exponent < 0
++                                   ? (INTMAX_MAX - bits + 1) / 4
++                                   : (INTMAX_MAX - exponent - bits + 1) / 4));
++      exponent += bits - 1 + ((intmax_t) int_no - 1) * 4;
+       while (--dig_no > 0 && idx >= 0)
+       {
+@@ -1014,13 +1089,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+      really integer digits or belong to the fractional part; i.e. we normalize
+      123e-2 to 1.23.  */
+   {
+-    register int incr = (exponent < 0 ? MAX (-int_no, exponent)
+-                       : MIN (dig_no - int_no, exponent));
++    register intmax_t incr = (exponent < 0
++                            ? MAX (-(intmax_t) int_no, exponent)
++                            : MIN ((intmax_t) dig_no - (intmax_t) int_no,
++                                   exponent));
+     int_no += incr;
+     exponent -= incr;
+   }
+-  if (__builtin_expect (int_no + exponent > MAX_10_EXP + 1, 0))
++  if (__builtin_expect (exponent > MAX_10_EXP + 1 - (intmax_t) int_no, 0))
+     {
+       __set_errno (ERANGE);
+       return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+@@ -1205,7 +1282,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+        digits we should have enough bits for the result.  The remaining
+        decimal digits give us the information that more bits are following.
+        This can be used while rounding.  (Two added as a safety margin.)  */
+-    if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 2)
++    if ((intmax_t) dig_no > (intmax_t) int_no + (MANT_DIG - bits + 2) / 3 + 2)
+       {
+       dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 2;
+       more_bits = 1;
+@@ -1213,7 +1290,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+     else
+       more_bits = 0;
+-    neg_exp = dig_no - int_no - exponent;
++    neg_exp = (intmax_t) dig_no - (intmax_t) int_no - exponent;
+     /* Construct the denominator.  */
+     densize = 0;
+@@ -1491,7 +1568,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
+                         register int i;
+                         (void) __mpn_lshift (&retval[used
+                                                      / BITS_PER_MP_LIMB],
+-                                             retval, RETURN_LIMB_SIZE,
++                                             retval,
++                                             (RETURN_LIMB_SIZE
++                                              - used / BITS_PER_MP_LIMB),
+                                              used % BITS_PER_MP_LIMB);
+                         for (i = used / BITS_PER_MP_LIMB - 1; i >= 0; --i)
+                           retval[i] = 0;
+diff -Nrup a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
+--- a/stdlib/tst-strtod-overflow.c     1969-12-31 17:00:00.000000000 -0700
++++ b/stdlib/tst-strtod-overflow.c     2012-08-15 09:25:01.098592764 -0600
+@@ -0,0 +1,48 @@
++/* Test for integer/buffer overflow in strtod.
++   Copyright (C) 2012 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   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, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#define EXPONENT "e-2147483649"
++#define SIZE 214748364
++
++static int
++do_test (void)
++{
++  char *p = malloc (1 + SIZE + sizeof (EXPONENT));
++  if (p == NULL)
++    {
++      puts ("malloc failed, cannot test for overflow");
++      return 0;
++    }
++  p[0] = '1';
++  memset (p + 1, '0', SIZE);
++  memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
++  double d = strtod (p, NULL);
++  if (d != 0)
++    {
++      printf ("strtod returned wrong value: %a\n", d);
++      return 1;
++    }
++  return 0;
++}
++
++#define TEST_FUNCTION do_test ()
++#include "../test-skeleton.c"
diff --git a/src/patches/glibc/glibc-rh848082.patch b/src/patches/glibc/glibc-rh848082.patch
new file mode 100644 (file)
index 0000000..dfb96bf
--- /dev/null
@@ -0,0 +1,88 @@
+commit 4f031072a5055abd83717820b59efdaa463d5853
+Author: Ulrich Drepper <drepper@gmail.com>
+Date:   Sat May 28 16:59:30 2011 -0400
+
+    Handle failure of _nl_explode_name in all cases
+
+ 2011-05-28  Ulrich Drepper  <drepper@gmail.com>
+       * locale/findlocale.c (_nl_find_locale): Return right away if
+       _nl_explode_name failed.
+       * locale/programs/locarchive.c (add_locale_to_archive): Likewise.
+
+diff --git a/locale/findlocale.c b/locale/findlocale.c
+index 6b88c96..2fec9a7 100644
+--- a/locale/findlocale.c
++++ b/locale/findlocale.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 1996-2001, 2002, 2003, 2006, 2010 Free Software Foundation, Inc.
++/* Copyright (C) 1996-2003, 2006, 2010, 2011 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+@@ -140,6 +140,9 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
+    */
+   mask = _nl_explode_name (loc_name, &language, &modifier, &territory,
+                          &codeset, &normalized_codeset);
++  if (mask == -1)
++    /* Memory allocate problem.  */
++    return NULL;
+   /* If exactly this locale was already asked for we have an entry with
+      the complete name.  */
+diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c
+index 85ba77d..e95bcf1 100644
+--- a/locale/programs/locarchive.c
++++ b/locale/programs/locarchive.c
+@@ -1,4 +1,4 @@
+-/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
++/* Copyright (C) 2002,2003,2005,2007,2009,2011 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+@@ -1079,6 +1079,8 @@ add_locale_to_archive (ah, name, data, replace)
+   int mask = _nl_explode_name (strdupa (name),
+                              &language, &modifier, &territory,
+                              &codeset, &normalized_codeset);
++  if (mask == -1)
++    return -1;
+   if (mask & XPG_NORM_CODESET)
+     /* This name contains a codeset in unnormalized form.
+@@ -1128,6 +1130,7 @@ add_locale_to_archive (ah, name, data, replace)
+   /* Now read the locale.alias files looking for lines whose
+      right hand side matches our name after normalization.  */
++  int result = 0;
+   if (alias_file != NULL)
+     {
+       FILE *fp;
+@@ -1207,6 +1210,11 @@ add_locale_to_archive (ah, name, data, replace)
+                                                    &rhs_territory,
+                                                    &rhs_codeset,
+                                                    &rhs_normalized_codeset);
++                  if (rhs_mask == 1)
++                    {
++                      result = -1;
++                      goto out;
++                    }
+                   if (!strcmp (language, rhs_language)
+                       && ((rhs_mask & XPG_CODESET)
+                           /* He has a codeset, it must match normalized.  */
+@@ -1240,6 +1248,7 @@ add_locale_to_archive (ah, name, data, replace)
+           }
+       }
++    out:
+       fclose (fp);
+     }
+@@ -1248,7 +1257,7 @@ add_locale_to_archive (ah, name, data, replace)
+   if (mask & XPG_NORM_CODESET)
+     free ((char *) normalized_codeset);
+-  return 0;
++  return result;
+ }
diff --git a/src/patches/glibc/glibc-rh849203.patch b/src/patches/glibc/glibc-rh849203.patch
new file mode 100644 (file)
index 0000000..ea50593
--- /dev/null
@@ -0,0 +1,195 @@
+diff -Nrup a/intl/Makefile b/intl/Makefile
+--- a/intl/Makefile    2010-05-04 05:27:23.000000000 -0600
++++ b/intl/Makefile    2012-08-17 14:40:00.457226629 -0600
+@@ -74,6 +74,16 @@ ifneq (no,$(PERL))
+ tests: $(objpfx)mtrace-tst-gettext
+ endif
+ endif
++
++# Multiple tests use this data.  Create it once to avoid racing and
++# spurious test failures.
++codeset_mo = $(objpfx)domaindir/de_DE/LC_MESSAGES/codeset.mo
++
++$(codeset_mo):
++      $(make-target-directory)
++      msgfmt -o $@T tstcodeset.po
++      mv -f $@T $@
++
+ $(objpfx)mtrace-tst-gettext: $(objpfx)tst-gettext.out
+       $(common-objpfx)malloc/mtrace $(objpfx)tst-gettext.mtrace > $@
+ $(objpfx)tst-gettext.out: tst-gettext.sh $(objpfx)tst-gettext
+@@ -83,16 +93,14 @@ $(objpfx)tst-translit.out: tst-translit.
+       $(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
+ $(objpfx)tst-gettext2.out: tst-gettext2.sh $(objpfx)tst-gettext2
+       $(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
+-$(objpfx)tst-codeset.out: tst-codeset.sh $(objpfx)tst-codeset
+-      $(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
+-$(objpfx)tst-gettext3.out: tst-gettext3.sh $(objpfx)tst-gettext3
+-      $(SHELL) -e $< $(common-objpfx) $(common-objpfx)intl/
+ $(objpfx)tst-gettext4.out: tst-gettext4.sh $(objpfx)tst-gettext4
+       $(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
+-$(objpfx)tst-gettext5.out: tst-gettext5.sh $(objpfx)tst-gettext5
+-      $(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
+ $(objpfx)tst-gettext6.out: tst-gettext6.sh $(objpfx)tst-gettext6
+       $(SHELL) -e $< $(common-objpfx) '$(run-program-prefix)' $(common-objpfx)intl/
++
++$(objpfx)tst-codeset.out: $(codeset_mo)
++$(objpfx)tst-gettext3.out: $(codeset_mo)
++$(objpfx)tst-gettext5.out: $(codeset_mo)
+ endif
+ endif
+@@ -109,6 +117,11 @@ CFLAGS-tst-gettext4.c = -DOBJPFX=\"$(obj
+ CFLAGS-tst-gettext5.c = -DOBJPFX=\"$(objpfx)\"
+ CFLAGS-tst-gettext6.c = -DOBJPFX=\"$(objpfx)\"
++LOCPATH-ENV = LOCPATH=$(common-objpfx)localedata
++tst-codeset-ENV = $(LOCPATH-ENV)
++tst-gettext3-ENV = $(LOCPATH-ENV)
++tst-gettext5-ENV = $(LOCPATH-ENV)
++
+ ifeq ($(have-thread-library),yes)
+ ifeq (yes,$(build-shared))
+ $(addprefix $(objpfx),$(multithread-test-srcs)): $(shared-thread-library)
+diff -Nrup a/intl/tst-codeset.sh b/intl/tst-codeset.sh
+--- a/intl/tst-codeset.sh      2010-05-04 05:27:23.000000000 -0600
++++ b/intl/tst-codeset.sh      1969-12-31 17:00:00.000000000 -0700
+@@ -1,43 +0,0 @@
+-#! /bin/sh
+-# Test of bind_textdomain_codeset.
+-# Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+-# This file is part of the GNU C Library.
+-#
+-
+-# 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.
+-
+-common_objpfx=$1
+-objpfx=$2
+-
+-LC_ALL=C
+-export LC_ALL
+-
+-# Generate the test data.
+-msgfmt -o ${objpfx}codeset.mo.$$ tstcodeset.po || exit
+-# Create the domain directories.
+-mkdir -p ${objpfx}domaindir/de_DE/LC_MESSAGES
+-# Populate them.
+-mv -f ${objpfx}codeset.mo.$$ ${objpfx}domaindir/de_DE/LC_MESSAGES/codeset.mo
+-
+-GCONV_PATH=${common_objpfx}iconvdata
+-export GCONV_PATH
+-LOCPATH=${common_objpfx}localedata
+-export LOCPATH
+-
+-${common_objpfx}elf/ld.so --library-path $common_objpfx \
+-${objpfx}tst-codeset > ${objpfx}tst-codeset.out
+-
+-exit $?
+diff -Nrup a/intl/tst-gettext3.sh b/intl/tst-gettext3.sh
+--- a/intl/tst-gettext3.sh     2010-05-04 05:27:23.000000000 -0600
++++ b/intl/tst-gettext3.sh     1969-12-31 17:00:00.000000000 -0700
+@@ -1,44 +0,0 @@
+-#! /bin/sh
+-# Test that the gettext() results come out in the correct encoding for
+-# locales that differ only in their encoding.
+-# Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+-# This file is part of the GNU C Library.
+-#
+-
+-# 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.
+-
+-common_objpfx=$1
+-objpfx=$2
+-
+-LC_ALL=C
+-export LC_ALL
+-
+-# Generate the test data.
+-msgfmt -o ${objpfx}codeset.mo.$$ tstcodeset.po || exit
+-# Create the domain directories.
+-mkdir -p ${objpfx}domaindir/de_DE/LC_MESSAGES
+-# Populate them.
+-mv -f ${objpfx}codeset.mo.$$ ${objpfx}domaindir/de_DE/LC_MESSAGES/codeset.mo
+-
+-GCONV_PATH=${common_objpfx}iconvdata
+-export GCONV_PATH
+-LOCPATH=${common_objpfx}localedata
+-export LOCPATH
+-
+-${common_objpfx}elf/ld.so --library-path $common_objpfx \
+-${objpfx}tst-gettext3 > ${objpfx}tst-gettext3.out
+-
+-exit $?
+diff -Nrup a/intl/tst-gettext5.sh b/intl/tst-gettext5.sh
+--- a/intl/tst-gettext5.sh     2010-05-04 05:27:23.000000000 -0600
++++ b/intl/tst-gettext5.sh     1969-12-31 17:00:00.000000000 -0700
+@@ -1,43 +0,0 @@
+-#! /bin/sh
+-# Test that gettext() in multithreaded applications works correctly if
+-# different threads operate in different locales referring to the same
+-# catalog file but with different encodings.
+-# Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+-# This file is part of the GNU C Library.
+-#
+-
+-# 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.
+-
+-common_objpfx=$1
+-run_program_prefix=$2
+-objpfx=$3
+-
+-LC_ALL=C
+-export LC_ALL
+-
+-# Create the domain directories.
+-mkdir -p ${objpfx}domaindir/de_DE/LC_MESSAGES
+-# Populate them.
+-msgfmt -o ${objpfx}domaindir/de_DE/LC_MESSAGES/codeset.mo tstcodeset.po
+-
+-GCONV_PATH=${common_objpfx}iconvdata
+-export GCONV_PATH
+-LOCPATH=${common_objpfx}localedata
+-export LOCPATH
+-
+-${run_program_prefix} ${objpfx}tst-gettext5 > ${objpfx}tst-gettext5.out
+-
+-exit $?
diff --git a/src/patches/glibc/glibc-rh849651.patch b/src/patches/glibc/glibc-rh849651.patch
new file mode 100644 (file)
index 0000000..97a5144
--- /dev/null
@@ -0,0 +1,343 @@
+diff -Nrup a/sysdeps/x86_64/fpu/e_expf.S b/sysdeps/x86_64/fpu/e_expf.S
+--- a/sysdeps/x86_64/fpu/e_expf.S      1969-12-31 17:00:00.000000000 -0700
++++ b/sysdeps/x86_64/fpu/e_expf.S      2012-08-20 09:47:15.551971545 -0600
+@@ -0,0 +1,339 @@
++/* Optimized __ieee754_expf function.
++   Copyright (C) 2012 Free Software Foundation, Inc.
++   Contributed by Intel Corporation.
++   This file is part of the GNU C Library.
++
++   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, see
++   <http://www.gnu.org/licenses/>.  */
++
++#include <sysdep.h>
++
++/* Short algorithm description:
++ *
++ *  Let K = 64 (table size).
++ *       e^x  = 2^(x/log(2)) = 2^n * T[j] * (1 + P(y))
++ *  where
++ *       x = m*log(2)/K + y,    y in [0.0..log(2)/K]
++ *       m = n*K + j,           m,n,j - signed integer, j in [0..K-1]
++ *       values of 2^(j/K) are tabulated as T[j].
++ *
++ *       P(y) is a minimax polynomial approximation of expf(x)-1
++ *       on small interval [0.0..log(2)/K].
++ *
++ *       P(y) = P3*y*y*y*y + P2*y*y*y + P1*y*y + P0*y, calculated as
++ *       z = y*y;    P(y) = (P3*z + P1)*z + (P2*z + P0)*y
++ *
++ * Special cases:
++ *  expf(NaN) = NaN
++ *  expf(+INF) = +INF
++ *  expf(-INF) = 0
++ *  expf(x) = 1 for subnormals
++ *  for finite argument, only expf(0)=1 is exact
++ *  expf(x) overflows if x>88.7228317260742190
++ *  expf(x) underflows if x<-103.972076416015620
++ */
++
++      .text
++ENTRY(__ieee754_expf)
++      /* Input: single precision x in %xmm0 */
++      cvtss2sd        %xmm0, %xmm1    /* Convert x to double precision */
++      movd    %xmm0, %ecx             /* Copy x */
++      movsd   L(DP_KLN2)(%rip), %xmm2 /* DP K/log(2) */
++      movsd   L(DP_P2)(%rip), %xmm3   /* DP P2 */
++      movl    %ecx, %eax              /* x */
++      mulsd   %xmm1, %xmm2            /* DP x*K/log(2) */
++      andl    $0x7fffffff, %ecx       /* |x| */
++      lea     L(DP_T)(%rip), %rsi     /* address of table T[j] */
++      cmpl    $0x42ad496b, %ecx       /* |x|<125*log(2) ? */
++      movsd   L(DP_P3)(%rip), %xmm4   /* DP P3 */
++      addsd   L(DP_RS)(%rip), %xmm2   /* DP x*K/log(2)+RS */
++      jae     L(special_paths)
++
++      /* Here if |x|<125*log(2) */
++      cmpl    $0x31800000, %ecx       /* |x|<2^(-28) ? */
++      jb      L(small_arg)
++
++      /* Main path: here if 2^(-28)<=|x|<125*log(2) */
++      cvtsd2ss        %xmm2, %xmm2    /* SP x*K/log(2)+RS */
++      movd    %xmm2, %eax             /* bits of n*K+j with trash */
++      subss   L(SP_RS)(%rip), %xmm2   /* SP t=round(x*K/log(2)) */
++      movl    %eax, %edx              /* n*K+j with trash */
++      cvtss2sd        %xmm2, %xmm2    /* DP t */
++      andl    $0x3f, %eax             /* bits of j */
++      mulsd   L(DP_NLN2K)(%rip), %xmm2/* DP -t*log(2)/K */
++      andl    $0xffffffc0, %edx       /* bits of n */
++#ifdef __AVX__
++      vaddsd  %xmm1, %xmm2, %xmm0     /* DP y=x-t*log(2)/K */
++      vmulsd  %xmm0, %xmm0, %xmm2     /* DP z=y*y */
++#else
++      addsd   %xmm1, %xmm2            /* DP y=x-t*log(2)/K */
++      movaps  %xmm2, %xmm0            /* DP y */
++      mulsd   %xmm2, %xmm2            /* DP z=y*y */
++#endif
++      mulsd   %xmm2, %xmm4            /* DP P3*z */
++      addl    $0x1fc0, %edx           /* bits of n + SP exponent bias */
++      mulsd   %xmm2, %xmm3            /* DP P2*z */
++      shll    $17, %edx               /* SP 2^n */
++      addsd   L(DP_P1)(%rip), %xmm4   /* DP P3*z+P1 */
++      addsd   L(DP_P0)(%rip), %xmm3   /* DP P2*z+P0 */
++      movd    %edx, %xmm1             /* SP 2^n */
++      mulsd   %xmm2, %xmm4            /* DP (P3*z+P1)*z */
++      mulsd   %xmm3, %xmm0            /* DP (P2*z+P0)*y */
++      addsd   %xmm4, %xmm0            /* DP P(y) */
++      mulsd   (%rsi,%rax,8), %xmm0    /* DP P(y)*T[j] */
++      addsd   (%rsi,%rax,8), %xmm0    /* DP T[j]*(P(y)+1) */
++      cvtsd2ss        %xmm0, %xmm0    /* SP T[j]*(P(y)+1) */
++      mulss   %xmm1, %xmm0            /* SP result=2^n*(T[j]*(P(y)+1)) */
++      ret
++
++      .p2align        4
++L(small_arg):
++      /* Here if 0<=|x|<2^(-28) */
++      addss   L(SP_ONE)(%rip), %xmm0  /* 1.0 + x */
++      /* Return 1.0 with inexact raised, except for x==0 */
++      ret
++
++      .p2align        4
++L(special_paths):
++      /* Here if 125*log(2)<=|x| */
++      shrl    $31, %eax               /* Get sign bit of x, and depending on it: */
++      lea     L(SP_RANGE)(%rip), %rdx /* load over/underflow bound */
++      cmpl    (%rdx,%rax,4), %ecx     /* |x|<under/overflow bound ? */
++      jbe     L(near_under_or_overflow)
++
++      /* Here if |x|>under/overflow bound */
++      cmpl    $0x7f800000, %ecx       /* |x| is finite ? */
++      jae     L(arg_inf_or_nan)
++
++      /* Here if |x|>under/overflow bound, and x is finite */
++      testq   %rax, %rax              /* sign of x nonzero ? */
++      je      L(res_overflow)
++
++      /* Here if -inf<x<underflow bound (x<0) */
++      movss   L(SP_SMALL)(%rip), %xmm0/* load small value 2^(-100) */
++      mulss   %xmm0, %xmm0            /* Return underflowed result (zero or subnormal) */
++      ret
++
++      .p2align        4
++L(res_overflow):
++      /* Here if overflow bound<x<inf (x>0) */
++      movss   L(SP_LARGE)(%rip), %xmm0/* load large value 2^100 */
++      mulss   %xmm0, %xmm0            /* Return overflowed result (Inf or max normal) */
++      ret
++
++      .p2align        4
++L(arg_inf_or_nan):
++      /* Here if |x| is Inf or NAN */
++      jne     L(arg_nan)      /* |x| is Inf ? */
++
++      /* Here if |x| is Inf */
++      lea     L(SP_INF_0)(%rip), %rdx /* depending on sign of x: */
++      movss   (%rdx,%rax,4), %xmm0    /* return zero or Inf */
++      ret
++
++      .p2align        4
++L(arg_nan):
++      /* Here if |x| is NaN */
++      addss   %xmm0, %xmm0            /* Return x+x (raise invalid) */
++      ret
++
++      .p2align        4
++L(near_under_or_overflow):
++      /* Here if 125*log(2)<=|x|<under/overflow bound */
++      cvtsd2ss        %xmm2, %xmm2    /* SP x*K/log(2)+RS */
++      movd    %xmm2, %eax             /* bits of n*K+j with trash */
++      subss   L(SP_RS)(%rip), %xmm2   /* SP t=round(x*K/log(2)) */
++      movl    %eax, %edx              /* n*K+j with trash */
++      cvtss2sd        %xmm2, %xmm2    /* DP t */
++      andl    $0x3f, %eax             /* bits of j */
++      mulsd   L(DP_NLN2K)(%rip), %xmm2/* DP -t*log(2)/K */
++      andl    $0xffffffc0, %edx       /* bits of n */
++#ifdef __AVX__
++      vaddsd  %xmm1, %xmm2, %xmm0     /* DP y=x-t*log(2)/K */
++      vmulsd  %xmm0, %xmm0, %xmm2     /* DP z=y*y */
++#else
++      addsd   %xmm1, %xmm2            /* DP y=x-t*log(2)/K */
++      movaps  %xmm2, %xmm0            /* DP y */
++      mulsd   %xmm2, %xmm2            /* DP z=y*y */
++#endif
++      mulsd   %xmm2, %xmm4            /* DP P3*z */
++      addl    $0xffc0, %edx           /* bits of n + DP exponent bias */
++      mulsd   %xmm2, %xmm3            /* DP P2*z */
++      shlq    $46, %rdx               /* DP 2^n */
++      addsd   L(DP_P1)(%rip), %xmm4   /* DP P3*z+P1 */
++      addsd   L(DP_P0)(%rip), %xmm3   /* DP P2*z+P0 */
++      movd    %rdx, %xmm1             /* DP 2^n */
++      mulsd   %xmm2, %xmm4            /* DP (P3*z+P1)*z */
++      mulsd   %xmm3, %xmm0            /* DP (P2*z+P0)*y */
++      addsd   %xmm4, %xmm0            /* DP P(y) */
++      mulsd   (%rsi,%rax,8), %xmm0    /* DP P(y)*T[j] */
++      addsd   (%rsi,%rax,8), %xmm0    /* DP T[j]*(P(y)+1) */
++      mulsd   %xmm1, %xmm0            /* DP result=2^n*(T[j]*(P(y)+1)) */
++      cvtsd2ss        %xmm0, %xmm0    /* convert result to single precision */
++      ret
++END(__ieee754_expf)
++
++      .section .rodata, "a"
++      .p2align 3
++L(DP_T): /* table of double precision values 2^(j/K) for j=[0..K-1] */
++      .long   0x00000000, 0x3ff00000
++      .long   0x3e778061, 0x3ff02c9a
++      .long   0xd3158574, 0x3ff059b0
++      .long   0x18759bc8, 0x3ff08745
++      .long   0x6cf9890f, 0x3ff0b558
++      .long   0x32d3d1a2, 0x3ff0e3ec
++      .long   0xd0125b51, 0x3ff11301
++      .long   0xaea92de0, 0x3ff1429a
++      .long   0x3c7d517b, 0x3ff172b8
++      .long   0xeb6fcb75, 0x3ff1a35b
++      .long   0x3168b9aa, 0x3ff1d487
++      .long   0x88628cd6, 0x3ff2063b
++      .long   0x6e756238, 0x3ff2387a
++      .long   0x65e27cdd, 0x3ff26b45
++      .long   0xf51fdee1, 0x3ff29e9d
++      .long   0xa6e4030b, 0x3ff2d285
++      .long   0x0a31b715, 0x3ff306fe
++      .long   0xb26416ff, 0x3ff33c08
++      .long   0x373aa9cb, 0x3ff371a7
++      .long   0x34e59ff7, 0x3ff3a7db
++      .long   0x4c123422, 0x3ff3dea6
++      .long   0x21f72e2a, 0x3ff4160a
++      .long   0x6061892d, 0x3ff44e08
++      .long   0xb5c13cd0, 0x3ff486a2
++      .long   0xd5362a27, 0x3ff4bfda
++      .long   0x769d2ca7, 0x3ff4f9b2
++      .long   0x569d4f82, 0x3ff5342b
++      .long   0x36b527da, 0x3ff56f47
++      .long   0xdd485429, 0x3ff5ab07
++      .long   0x15ad2148, 0x3ff5e76f
++      .long   0xb03a5585, 0x3ff6247e
++      .long   0x82552225, 0x3ff66238
++      .long   0x667f3bcd, 0x3ff6a09e
++      .long   0x3c651a2f, 0x3ff6dfb2
++      .long   0xe8ec5f74, 0x3ff71f75
++      .long   0x564267c9, 0x3ff75feb
++      .long   0x73eb0187, 0x3ff7a114
++      .long   0x36cf4e62, 0x3ff7e2f3
++      .long   0x994cce13, 0x3ff82589
++      .long   0x9b4492ed, 0x3ff868d9
++      .long   0x422aa0db, 0x3ff8ace5
++      .long   0x99157736, 0x3ff8f1ae
++      .long   0xb0cdc5e5, 0x3ff93737
++      .long   0x9fde4e50, 0x3ff97d82
++      .long   0x82a3f090, 0x3ff9c491
++      .long   0x7b5de565, 0x3ffa0c66
++      .long   0xb23e255d, 0x3ffa5503
++      .long   0x5579fdbf, 0x3ffa9e6b
++      .long   0x995ad3ad, 0x3ffae89f
++      .long   0xb84f15fb, 0x3ffb33a2
++      .long   0xf2fb5e47, 0x3ffb7f76
++      .long   0x904bc1d2, 0x3ffbcc1e
++      .long   0xdd85529c, 0x3ffc199b
++      .long   0x2e57d14b, 0x3ffc67f1
++      .long   0xdcef9069, 0x3ffcb720
++      .long   0x4a07897c, 0x3ffd072d
++      .long   0xdcfba487, 0x3ffd5818
++      .long   0x03db3285, 0x3ffda9e6
++      .long   0x337b9b5f, 0x3ffdfc97
++      .long   0xe78b3ff6, 0x3ffe502e
++      .long   0xa2a490da, 0x3ffea4af
++      .long   0xee615a27, 0x3ffefa1b
++      .long   0x5b6e4540, 0x3fff5076
++      .long   0x819e90d8, 0x3fffa7c1
++      .type L(DP_T), @object
++      ASM_SIZE_DIRECTIVE(L(DP_T))
++
++      .section .rodata.cst8,"aM",@progbits,8
++      .p2align 3
++L(DP_KLN2): /* double precision K/log(2) */
++      .long   0x652b82fe, 0x40571547
++      .type L(DP_KLN2), @object
++      ASM_SIZE_DIRECTIVE(L(DP_KLN2))
++
++      .p2align 3
++L(DP_NLN2K): /* double precision -log(2)/K */
++      .long   0xfefa39ef, 0xbf862e42
++      .type L(DP_NLN2K), @object
++      ASM_SIZE_DIRECTIVE(L(DP_NLN2K))
++
++      .p2align 3
++L(DP_RS): /* double precision 2^23+2^22 */
++      .long   0x00000000, 0x41680000
++      .type L(DP_RS), @object
++      ASM_SIZE_DIRECTIVE(L(DP_RS))
++
++      .p2align 3
++L(DP_P3): /* double precision polynomial coefficient P3 */
++      .long   0xeb78fa85, 0x3fa56420
++      .type L(DP_P3), @object
++      ASM_SIZE_DIRECTIVE(L(DP_P3))
++
++      .p2align 3
++L(DP_P1): /* double precision polynomial coefficient P1 */
++      .long   0x008d6118, 0x3fe00000
++      .type L(DP_P1), @object
++      ASM_SIZE_DIRECTIVE(L(DP_P1))
++
++      .p2align 3
++L(DP_P2): /* double precision polynomial coefficient P2 */
++      .long   0xda752d4f, 0x3fc55550
++      .type L(DP_P2), @object
++      ASM_SIZE_DIRECTIVE(L(DP_P2))
++
++      .p2align 3
++L(DP_P0): /* double precision polynomial coefficient P0 */
++      .long   0xffffe7c6, 0x3fefffff
++      .type L(DP_P0), @object
++      ASM_SIZE_DIRECTIVE(L(DP_P0))
++
++      .p2align 2
++L(SP_RANGE): /* single precision overflow/underflow bounds */
++      .long   0x42b17217      /* if x>this bound, then result overflows */
++      .long   0x42cff1b4      /* if x<this bound, then result underflows */
++      .type L(SP_RANGE), @object
++      ASM_SIZE_DIRECTIVE(L(SP_RANGE))
++
++      .p2align 2
++L(SP_INF_0):
++      .long   0x7f800000      /* single precision Inf */
++      .long   0               /* single precision zero */
++      .type L(SP_INF_0), @object
++      ASM_SIZE_DIRECTIVE(L(SP_INF_0))
++
++      .section .rodata.cst4,"aM",@progbits,4
++      .p2align 2
++L(SP_RS): /* single precision 2^23+2^22 */
++      .long   0x4b400000
++      .type L(SP_RS), @object
++      ASM_SIZE_DIRECTIVE(L(SP_RS))
++
++      .p2align 2
++L(SP_SMALL): /* single precision small value 2^(-100) */
++      .long   0x0d800000
++      .type L(SP_SMALL), @object
++      ASM_SIZE_DIRECTIVE(L(SP_SMALL))
++
++      .p2align 2
++L(SP_LARGE): /* single precision large value 2^100 */
++      .long   0x71800000
++      .type L(SP_LARGE), @object
++      ASM_SIZE_DIRECTIVE(L(SP_LARGE))
++
++      .p2align 2
++L(SP_ONE): /* single precision 1.0 */
++      .long   0x3f800000
++      .type L(SP_ONE), @object
++      ASM_SIZE_DIRECTIVE(L(SP_ONE))
++
++strong_alias (__ieee754_expf, __expf_finite)
diff --git a/src/patches/glibc/glibc-rh852445.patch b/src/patches/glibc/glibc-rh852445.patch
new file mode 100644 (file)
index 0000000..3c4e13f
--- /dev/null
@@ -0,0 +1,105 @@
+From libc-alpha-return-31329-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org Wed Jul 11 11:36:39 2012
+Return-Path: <libc-alpha-return-31329-listarch-libc-alpha=sources dot redhat dot com at sourceware dot org>
+Delivered-To: listarch-libc-alpha at sources dot redhat dot com
+Received: (qmail 15677 invoked by alias); 11 Jul 2012 11:36:39 -0000
+Received: (qmail 15654 invoked by uid 22791); 11 Jul 2012 11:36:37 -0000
+X-SWARE-Spam-Status: No, hits=-4.3 required=5.0
+       tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE
+X-Spam-Check-By: sourceware.org
+Date: Wed, 11 Jul 2012 21:06:06 +0930
+From: Alan Modra <amodra at gmail dot com>
+To: libc-alpha at sourceware dot org
+Cc: rsa at linux dot vnet dot ibm dot com
+Subject: powerpc pthread_once bug fix
+Message-ID: <20120711113606.GM3117@bubble.grove.modra.org>
+MIME-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+User-Agent: Mutt/1.5.21 (2010-09-15)
+Mailing-List: contact libc-alpha-help at sourceware dot org; run by ezmlm
+Precedence: bulk
+List-Id: <libc-alpha.sourceware.org>
+List-Subscribe: <mailto:libc-alpha-subscribe at sourceware dot org>
+List-Archive: <http://sourceware.org/ml/libc-alpha/>
+List-Post: <mailto:libc-alpha at sourceware dot org>
+List-Help: <mailto:libc-alpha-help at sourceware dot org>, <http://sourceware dot org/ml/#faqs>
+Sender: libc-alpha-owner at sourceware dot org
+Delivered-To: mailing list libc-alpha at sourceware dot org
+
+This fixes some bugs in the powerpc pthread_once code.  Ref
+gcc.gnu.org/bugzilla/show_bug.cgi?id=52839#c10
+
+Release barriers are needed to ensure any memory written by
+init_routine is seen by other threads before *once_control changes.
+In the case of clear_once_control we need to flush any partially
+written state.
+
+2012-06-28  Alan Modra  <amodra@gmail.com>
+
+       * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once):
+       Add release barrier before setting once_control to say
+       initialisation is done.  Add hints on lwarx.  Use macro in
+       place of isync.
+       (clear_once_control): Add release barrier.
+
+[ This was slightly edited -- the constraint for operand 0 in the last asm was changed
+  from "=&r" to "=&b" as using r0 in that context results in a load immediate 1 into
+  the target rather than incrementing the target. ]
+
+diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+index 4e3d7bd..bb1ebf2 100644
+--- a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
++++ b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c
+@@ -28,6 +28,7 @@ clear_once_control (void *arg)
+ {
+   pthread_once_t *once_control = (pthread_once_t *) arg;
++  __asm __volatile (__lll_rel_instr);
+   *once_control = 0;
+   lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+ }
+@@ -47,15 +48,15 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+        oldval = *once_control;
+        if ((oldval & 2) == 0)
+          *once_control = newval;
+-       Do this atomically.
++       Do this atomically with an acquire barrier.
+       */
+       newval = __fork_generation | 1;
+-      __asm __volatile ("1:   lwarx   %0,0,%3\n"
++      __asm __volatile ("1:   lwarx   %0,0,%3" MUTEX_HINT_ACQ "\n"
+                       "       andi.   %1,%0,2\n"
+                       "       bne     2f\n"
+                       "       stwcx.  %4,0,%3\n"
+                       "       bne     1b\n"
+-                      "2:     isync"
++                      "2:     " __lll_acq_instr
+                       : "=&r" (oldval), "=&r" (tmp), "=m" (*once_control)
+                       : "r" (once_control), "r" (newval), "m" (*once_control)
+                       : "cr0");
+@@ -87,8 +88,18 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
+   pthread_cleanup_pop (0);
+-  /* Add one to *once_control to take the bottom 2 bits from 01 to 10.  */
+-  atomic_increment (once_control);
++  /* Add one to *once_control to take the bottom 2 bits from 01 to 10.
++     A release barrier is needed to ensure memory written by init_routine
++     is seen in other threads before *once_control changes.  */
++  int tmp;
++  __asm __volatile (__lll_rel_instr "\n"
++                  "1: lwarx   %0,0,%2" MUTEX_HINT_REL "\n"
++                  "   addi    %0,%0,1\n"
++                  "   stwcx.  %0,0,%2\n"
++                  "   bne-    1b"
++                  : "=&b" (tmp), "=m" (*once_control)
++                  : "r" (once_control), "m" (*once_control)
++                  : "cr0");
+   /* Wake up all other threads.  */
+   lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
+
+-- 
+Alan Modra
+Australia Development Lab, IBM
+
diff --git a/src/patches/glibc/glibc-rh861167.patch b/src/patches/glibc/glibc-rh861167.patch
new file mode 100644 (file)
index 0000000..d7e982f
--- /dev/null
@@ -0,0 +1,86 @@
+commit be08eda54c7cf833ccfa4b8d1f1b1d668c26af66
+Author: Andreas Jaeger <aj@suse.de>
+Date:   Wed May 23 09:27:39 2012 +0200
+
+    Update from Linux 3.4
+
+[ Partial, unrelated bits not included. ]
+
+2012-05-23  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/powerpc/bits/mman.h
+       (MADV_DONTDUMP,MADV_DODUMP): New macros from Linux 3.4.
+       macro.
+       * sysdeps/unix/sysv/linux/s390/bits/mman.h
+       (MADV_DONTDUMP,MADV_DODUMP): Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/mman.h
+       (MADV_DONTDUMP,MADV_DODUMP): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/mman.h
+       (MADV_DONTDUMP,MADV_DODUMP): Likewise.
+
+diff -Nrup a/sysdeps/unix/sysv/linux/i386/bits/mman.h b/sysdeps/unix/sysv/linux/i386/bits/mman.h
+--- a/sysdeps/unix/sysv/linux/i386/bits/mman.h 2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/unix/sysv/linux/i386/bits/mman.h 2012-09-27 11:44:26.985150148 -0600
+@@ -1,5 +1,5 @@
+ /* Definitions for POSIX memory map interface.  Linux/i386 version.
+-   Copyright (C) 1997,2000,2003,2005,2006,2009 Free Software Foundation, Inc.
++   Copyright (C) 1997-2012 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -94,6 +94,9 @@
+ # define MADV_DOFORK    11    /* Do inherit across fork.  */
+ # define MADV_MERGEABLE         12    /* KSM may merge identical pages.  */
+ # define MADV_UNMERGEABLE 13  /* KSM may not merge identical pages.  */
++# define MADV_DONTDUMP          16    /* Explicity exclude from the core dump,
++                                   overrides the coredump filter bits.  */
++# define MADV_DODUMP    17    /* Clear the MADV_DONTDUMP flag.  */
+ # define MADV_HWPOISON          100   /* Poison a page for testing.  */
+ #endif
+diff -Nrup a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h      2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h      2012-09-27 11:43:37.161351259 -0600
+@@ -96,6 +96,9 @@
+ # define MADV_DOFORK    11    /* Do inherit across fork.  */
+ # define MADV_MERGEABLE         12    /* KSM may merge identical pages.  */
+ # define MADV_UNMERGEABLE 13  /* KSM may not merge identical pages.  */
++# define MADV_DONTDUMP          16    /* Explicity exclude from the core dump,
++                                   overrides the coredump filter bits.  */
++# define MADV_DODUMP    17    /* Clear the MADV_DONTDUMP flag.  */
+ # define MADV_HWPOISON          100   /* Poison a page for testing.  */
+ #endif
+diff -Nrup a/sysdeps/unix/sysv/linux/s390/bits/mman.h b/sysdeps/unix/sysv/linux/s390/bits/mman.h
+--- a/sysdeps/unix/sysv/linux/s390/bits/mman.h 2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/unix/sysv/linux/s390/bits/mman.h 2012-09-27 11:44:49.745059646 -0600
+@@ -94,6 +94,9 @@
+ # define MADV_DOFORK    11    /* Do inherit across fork.  */
+ # define MADV_MERGEABLE         12    /* KSM may merge identical pages.  */
+ # define MADV_UNMERGEABLE 13  /* KSM may not merge identical pages.  */
++# define MADV_DONTDUMP          16    /* Explicity exclude from the core dump,
++                                   overrides the coredump filter bits.  */
++# define MADV_DODUMP    17    /* Clear the MADV_DONTDUMP flag.  */
+ # define MADV_HWPOISON          100   /* Poison a page for testing.  */
+ #endif
+diff -Nrup a/sysdeps/unix/sysv/linux/x86_64/bits/mman.h b/sysdeps/unix/sysv/linux/x86_64/bits/mman.h
+--- a/sysdeps/unix/sysv/linux/x86_64/bits/mman.h       2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/unix/sysv/linux/x86_64/bits/mman.h       2012-09-27 11:42:08.314725733 -0600
+@@ -1,5 +1,5 @@
+ /* Definitions for POSIX memory map interface.  Linux/x86_64 version.
+-   Copyright (C) 2001, 2003, 2005, 2006, 2009 Free Software Foundation, Inc.
++   Copyright (C) 2001-2012 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    The GNU C Library is free software; you can redistribute it and/or
+@@ -95,6 +95,9 @@
+ # define MADV_DOFORK    11    /* Do inherit across fork.  */
+ # define MADV_MERGEABLE         12    /* KSM may merge identical pages.  */
+ # define MADV_UNMERGEABLE 13  /* KSM may not merge identical pages.  */
++# define MADV_DONTDUMP          16    /* Explicity exclude from the core dump,
++                                   overrides the coredump filter bits.  */
++# define MADV_DODUMP    17    /* Clear the MADV_DONTDUMP flag.  */
+ # define MADV_HWPOISON          100   /* Poison a page for testing.  */
+ #endif
diff --git a/src/patches/glibc/glibc-rh863453.patch b/src/patches/glibc/glibc-rh863453.patch
new file mode 100644 (file)
index 0000000..96fb769
--- /dev/null
@@ -0,0 +1,81 @@
+--- glibc-2.12-2-gc4ccff1/nscd/grpcache.c.lrgrpissue   2002-03-19 01:06:04.905969517 +0530
++++ glibc-2.12-2-gc4ccff1/nscd/grpcache.c      2002-03-19 01:09:46.495970850 +0530
+@@ -207,10 +207,11 @@ cache_addgr (struct database_dyn *db, in
+        change.  Allocate memory on the cache since it is likely
+        discarded anyway.  If it turns out to be necessary to have a
+        new record we can still allocate real memory.  */
+-      bool dataset_in_stack_or_freed = false;
++      bool dataset_temporary = false;
++      bool dataset_malloced = false; 
+       dataset = NULL;
+-      if (he == NULL || ! __libc_use_alloca (alloca_used + total + n))
++      if (he == NULL)
+       dataset = (struct dataset *) mempool_alloc (db, total + n, 1);
+       if (dataset == NULL)
+@@ -218,10 +219,16 @@ cache_addgr (struct database_dyn *db, in
+         /* We cannot permanently add the result in the moment.  But
+            we can provide the result as is.  Store the data in some
+            temporary memory.  */
+-        dataset = (struct dataset *) alloca_account (total + n, alloca_used);
+-
++        if (! __libc_use_alloca (alloca_used + total + n))
++        {
++              /* XXX What to do if malloc fails?  */
++              dataset = (struct dataset *) malloc (total + n);
++              dataset_malloced = true;
++        }
++        else
++              dataset = (struct dataset *) alloca_account (total + n, alloca_used); 
+         /* We cannot add this record to the permanent database.  */
+-        dataset_in_stack_or_freed = true;
++        dataset_temporary = true; 
+       }
+       dataset->head.allocsize = total + n;
+@@ -276,13 +283,10 @@ cache_addgr (struct database_dyn *db, in
+             dh->timeout = dataset->head.timeout;
+             ++dh->nreloads;
+-            /* If the new record was not allocated on the stack, then it must
+-               be freed.  Note that it can no longer be used.  */
+-            if (! dataset_in_stack_or_freed)
+-              {
+-                free (dataset);
+-                dataset_in_stack_or_freed = true;
+-              }
++            /* If the new record was allocated via malloc, then we
++               must free it here.  */
++            if (dataset_malloced)
++                free (dataset); 
+           }
+         else
+           {
+@@ -298,7 +302,7 @@ cache_addgr (struct database_dyn *db, in
+                 key_copy = (char *) newp + (key_copy - (char *) dataset);
+                 dataset = memcpy (newp, dataset, total + n);
+-                dataset_in_stack_or_freed = false;
++                dataset_temporary = false;
+               }
+             /* Mark the old record as obsolete.  */
+@@ -313,7 +317,7 @@ cache_addgr (struct database_dyn *db, in
+         assert (fd != -1);
+ #ifdef HAVE_SENDFILE
+-        if (__builtin_expect (db->mmap_used, 1) && !dataset_in_stack_or_freed)
++        if (__builtin_expect (db->mmap_used, 1) && ! dataset_temporary) 
+           {
+             assert (db->wr_fd != -1);
+             assert ((char *) &dataset->resp > (char *) db->data);
+@@ -340,7 +344,7 @@ cache_addgr (struct database_dyn *db, in
+       /* Add the record to the database.  But only if it has not been
+        stored on the stack.  */
+-      if (! dataset_in_stack_or_freed)
++       if (! dataset_temporary) 
+       {
+         /* If necessary, we also propagate the data to disk.  */
+         if (db->persistent)
diff --git a/src/patches/glibc/glibc-rh864322.patch b/src/patches/glibc/glibc-rh864322.patch
new file mode 100644 (file)
index 0000000..565a146
--- /dev/null
@@ -0,0 +1,12 @@
+diff -rup a/sysdeps/generic/netinet/ip.h b/sysdeps/generic/netinet/ip.h
+--- a/sysdeps/generic/netinet/ip.h     2010-05-04 05:27:23.000000000 -0600
++++ b/sysdeps/generic/netinet/ip.h     2012-10-11 09:22:12.620160387 -0600
+@@ -194,7 +194,7 @@ struct ip_timestamp
+  */
+ #define       IPTOS_CLASS_MASK                0xe0
+-#define       IPTOS_CLASS(class)              ((tos) & IPTOS_CLASS_MASK)
++#define       IPTOS_CLASS(class)              ((class) & IPTOS_CLASS_MASK)
+ #define       IPTOS_CLASS_CS0                 0x00
+ #define       IPTOS_CLASS_CS1                 0x20
+ #define       IPTOS_CLASS_CS2                 0x40
diff --git a/src/patches/glibc/glibc-rh929388.patch b/src/patches/glibc/glibc-rh929388.patch
new file mode 100644 (file)
index 0000000..44ddd17
--- /dev/null
@@ -0,0 +1,21 @@
+diff -pruN glibc-2.5-20061008T1257/sysdeps/x86_64/fpu/math_private.h glibc-2.5-20061008T1257.patched/sysdeps/x86_64/fpu/math_private.h
+--- glibc-2.5-20061008T1257/sysdeps/x86_64/fpu/math_private.h  2013-02-12 07:05:08.000000000 -0500
++++ glibc-2.5-20061008T1257.patched/sysdeps/x86_64/fpu/math_private.h  2013-02-12 06:59:08.000000000 -0500
+@@ -90,10 +90,14 @@ while (0)
+ #undef libc_feupdateenv
+ #define libc_feupdateenv(e) \
+   do {                                                                              \
+-    unsigned int mxcsr;                                                             \
++    unsigned int mxcsr, new_mxcsr;                                          \
+     asm volatile ("stmxcsr %0" : "=m" (*&mxcsr));                           \
+-    asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr));                             \
+-    feraiseexcept (mxcsr & FE_ALL_EXCEPT);                                  \
++    /* Merge in the old exceptions.  */                                             \
++    new_mxcsr = mxcsr & FE_ALL_EXCEPT | (e)->__mxcsr;                       \
++    asm volatile ("ldmxcsr %0" : : "m" (*&new_mxcsr));                              \
++    /* Only raise exception if there are any that are not masked.  */       \
++    if (~(mxcsr >> 7) & mxcsr & FE_ALL_EXCEPT)                                      \
++      feraiseexcept (mxcsr & FE_ALL_EXCEPT);                                \
+   } while (0)
+ #undef libc_feupdateenvf
+ #define libc_feupdateenvf(e) libc_feupdateenv (e)
diff --git a/src/patches/glibc/glibc-rh970992.patch b/src/patches/glibc/glibc-rh970992.patch
new file mode 100644 (file)
index 0000000..42aa819
--- /dev/null
@@ -0,0 +1,190 @@
+#
+# Patch provided by Ulrich Drepper in BZ#919562.
+#
+# Patch has not been sent upstream.
+#
+# 2013-03-08  Ulrich Drepper  <drepper@gmail.com>
+#
+#      * elf/rtld.c (dl_main): Correctly determine when the application
+#      required DSOs with TLS and bump the generation counter in that
+#      case.  The current condition does not account for an audit
+#      module using TLS.
+#      * elf/dl-tls.c (_dl_count_modids): New function.
+#      (_dl_allocate_tls_init): Add assertion to check TLS
+#      generation.
+#      * sysdeps/generic/ldsodefs.h: Declare _dl_count_modids.
+#      * elf/Makefile: Add rules to build and run tst-audit9.
+#      * elf/tst-audit9.c: New file.
+#      * elf/tst-auditmod9a.c: New file.
+#      * elf/tst-auditmod9b.c: New file.
+#
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/dl-tls.c glibc-2.12-2-gc4ccff1/elf/dl-tls.c
+--- glibc-2.12-2-gc4ccff1.orig/elf/dl-tls.c    2013-04-24 16:06:10.410756438 -0400
++++ glibc-2.12-2-gc4ccff1/elf/dl-tls.c 2013-04-24 16:06:49.092604707 -0400
+@@ -109,6 +109,28 @@
+ }
++size_t
++internal_function
++_dl_count_modids (void)
++{
++  if (! __builtin_expect (GL(dl_tls_dtv_gaps), true))
++    return GL(dl_tls_max_dtv_idx);
++
++  size_t n = 0;
++  struct dtv_slotinfo_list *runp = GL(dl_tls_dtv_slotinfo_list);
++  while (runp != NULL)
++    {
++      for (size_t i = 0; i < runp->len; ++i)
++      if (runp->slotinfo[i].map != NULL)
++        ++n;
++
++      runp = runp->next;
++    }
++
++  return n;
++}
++
++
+ #ifdef SHARED
+ void
+ internal_function
+@@ -411,6 +433,7 @@
+         /* Keep track of the maximum generation number.  This might
+            not be the generation counter.  */
++        assert (listp->slotinfo[cnt].gen <= GL(dl_tls_generation));
+         maxgen = MAX (maxgen, listp->slotinfo[cnt].gen);
+         if (map->l_tls_offset == NO_TLS_OFFSET
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/Makefile glibc-2.12-2-gc4ccff1/elf/Makefile
+--- glibc-2.12-2-gc4ccff1.orig/elf/Makefile    2013-04-24 16:06:10.408756448 -0400
++++ glibc-2.12-2-gc4ccff1/elf/Makefile 2013-04-24 16:07:29.475457962 -0400
+@@ -97,6 +97,8 @@
+                  tst-audit6.c tst-auditmod6a.c tst-auditmod6b.c \
+                  tst-auditmod6c.c \
+                  tst-audit7.c tst-auditmod7a.c tst-auditmod7b.c \
++                 tst-audit9.c \
++                 tst-auditmod9a.c tst-auditmod9b.c \
+                  order2mod1.c order2mod2.c order2mod3.c order2mod4.c \
+                  tst-stackguard1.c tst-stackguard1-static.c \
+                  tst-array5.c tst-array5-static.c tst-array5dep.c \
+@@ -198,7 +200,7 @@
+        tst-dlmodcount tst-dlopenrpath tst-deep1 \
+        tst-dlmopen1 tst-dlmopen2 tst-dlmopen3 \
+        unload3 unload4 unload5 unload6 unload7 unload8 tst-global1 order2 \
+-       tst-audit1 tst-audit2 \
++       tst-audit1 tst-audit2 tst-audit9 \
+        tst-stackguard1 tst-addr1 tst-thrlock \
+        tst-unique1 tst-unique2
+ #      reldep9
+@@ -251,7 +253,8 @@
+               unload8mod1 unload8mod1x unload8mod2 unload8mod3 \
+               order2mod1 order2mod2 order2mod3 order2mod4 \
+               tst-unique1mod1 tst-unique1mod2 \
+-              tst-unique2mod1 tst-unique2mod2
++              tst-unique2mod1 tst-unique2mod2 \
++              tst-auditmod9a tst-auditmod9b
+ ifeq (yes,$(have-initfini-array))
+ modules-names += tst-array2dep tst-array5dep
+ endif
+@@ -574,6 +577,8 @@
+ ifuncmod1.so-no-z-defs = yes
+ ifuncmod5.so-no-z-defs = yes
+ ifuncmod6.so-no-z-defs = yes
++tst-auditmod9a.so-no-z-defs = yes
++tst-auditmod9b.so-no-z-defs = yes
+ ifeq ($(build-shared),yes)
+ # Build all the modules even when not actually running test programs.
+@@ -1015,6 +1020,10 @@
+ $(objpfx)tst-audit7.out: $(objpfx)tst-auditmod7b.so
+ tst-audit7-ENV = LD_AUDIT=$(objpfx)tst-auditmod7b.so
++$(objpfx)tst-audit9: $(libdl)
++$(objpfx)tst-audit9.out: $(objpfx)tst-auditmod9a.so $(objpfx)tst-auditmod9b.so
++tst-audit9-ENV = LD_AUDIT=$(objpfx)tst-auditmod9a.so
++
+ $(objpfx)tst-global1: $(libdl)
+ $(objpfx)tst-global1.out: $(objpfx)testobj6.so $(objpfx)testobj2.so
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/rtld.c glibc-2.12-2-gc4ccff1/elf/rtld.c
+--- glibc-2.12-2-gc4ccff1.orig/elf/rtld.c      2013-04-24 16:06:10.410756438 -0400
++++ glibc-2.12-2-gc4ccff1/elf/rtld.c   2013-04-24 16:06:49.096604693 -0400
+@@ -1637,6 +1637,10 @@
+       }
+     }
++  /* Keep track of the currently loaded modules to count how many
++     non-audit modules which use TLS are loaded.  */
++  size_t count_modids = _dl_count_modids ();
++
+   /* Set up debugging before the debugger is notified for the first time.  */
+ #ifdef ELF_MACHINE_DEBUG_SETUP
+   /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way.  */
+@@ -2281,7 +2285,8 @@
+ # define NONTLS_INIT_TP do { } while (0)
+ #endif
+-  if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
++  if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
++      || count_modids != _dl_count_modids ())
+     ++GL(dl_tls_generation);
+   /* Now that we have completed relocation, the initializer data
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/tst-audit9.c glibc-2.12-2-gc4ccff1/elf/tst-audit9.c
+--- glibc-2.12-2-gc4ccff1.orig/elf/tst-audit9.c        1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.12-2-gc4ccff1/elf/tst-audit9.c     2013-04-24 16:06:49.096604693 -0400
+@@ -0,0 +1,8 @@
++#include <dlfcn.h>
++
++int main(void)
++{
++  void *h = dlopen("$ORIGIN/tst-auditmod9b.so", RTLD_LAZY);
++  int (*fp)(void) = dlsym(h, "f");
++  return fp() - 1;
++}
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/tst-auditmod9a.c glibc-2.12-2-gc4ccff1/elf/tst-auditmod9a.c
+--- glibc-2.12-2-gc4ccff1.orig/elf/tst-auditmod9a.c    1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.12-2-gc4ccff1/elf/tst-auditmod9a.c 2013-04-24 16:06:49.097604689 -0400
+@@ -0,0 +1,16 @@
++#include <stdint.h>
++
++__thread int var;
++
++unsigned int
++la_version (unsigned int v)
++{
++  return v;
++}
++
++void
++la_activity (uintptr_t *cookie, unsigned int flag)
++{
++  ++var;
++}
++
+diff -urN glibc-2.12-2-gc4ccff1.orig/elf/tst-auditmod9b.c glibc-2.12-2-gc4ccff1/elf/tst-auditmod9b.c
+--- glibc-2.12-2-gc4ccff1.orig/elf/tst-auditmod9b.c    1969-12-31 19:00:00.000000000 -0500
++++ glibc-2.12-2-gc4ccff1/elf/tst-auditmod9b.c 2013-04-24 16:06:49.097604689 -0400
+@@ -0,0 +1,6 @@
++__thread int a;
++
++int f(void)
++{
++  return ++a;
++}
+diff -urN glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
+--- glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h      2013-04-24 16:06:10.545755798 -0400
++++ glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h   2013-04-24 16:06:49.098604686 -0400
+@@ -1031,6 +1031,9 @@
+ /* Determine next available module ID.  */
+ extern size_t _dl_next_tls_modid (void) internal_function attribute_hidden;
++/* Count the modules with TLS segments.  */
++extern size_t _dl_count_modids (void) internal_function attribute_hidden;
++
+ /* Calculate offset of the TLS blocks in the static TLS block.  */
+ extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden;
diff --git a/src/patches/glibc/glibc-rh989558-2.patch b/src/patches/glibc/glibc-rh989558-2.patch
new file mode 100644 (file)
index 0000000..ad895c7
--- /dev/null
@@ -0,0 +1,107 @@
+2013-05-03  Carlos O'Donell  <carlos at redhat.com>
+
+        * intl/dcigettext.c (DCIGETTEXT): Skip translating if _nl_find_msg returns -1.
+        (_nl_find_msg): Return -1 if recursive call returned -1. If newmem is null
+        return -1.
+        * intl/loadmsgcat.c (_nl_load_domain): If _nl_find_msg returns -1 abort
+        loading the domain.
+
+diff -Nrup a/intl/dcigettext.c b/intl/dcigettext.c
+--- a/intl/dcigettext.c        2010-05-04 07:27:23.000000000 -0400
++++ b/intl/dcigettext.c        2013-08-01 00:11:54.616363264 -0400
+@@ -640,6 +640,11 @@ DCIGETTEXT (domainname, msgid1, msgid2, 
+                 retval = _nl_find_msg (domain->successor[cnt], binding,
+                                        msgid1, 1, &retlen);
++                /* Resource problems are not fatal, instead we return no
++                  translation.  */
++                if (__builtin_expect (retval == (char *) -1, 0))
++                  goto no_translation;
++
+                 if (retval != NULL)
+                   {
+                     domain = domain->successor[cnt];
+@@ -943,6 +948,11 @@ _nl_find_msg (domain_file, domainbinding
+           nullentry =
+             _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
++          /* Resource problems are fatal.  If we continue onwards we will
++             only attempt to calloc a new conv_tab and fail later.  */
++          if (__builtin_expect (nullentry == (char *) -1, 0))
++             return (char *) -1;
++
+           if (nullentry != NULL)
+             {
+               const char *charsetstr;
+@@ -1156,7 +1166,7 @@ _nl_find_msg (domain_file, domainbinding
+                                                            freemem_size);
+ # ifdef _LIBC
+                     if (newmem != NULL)
+-                      transmem_list = transmem_list->next;
++                      transmem_list = newmem;
+                     else
+                       {
+                         struct transmem_list *old = transmem_list;
+@@ -1171,6 +1181,16 @@ _nl_find_msg (domain_file, domainbinding
+                     malloc_count = 1;
+                     freemem_size = INITIAL_BLOCK_SIZE;
+                     newmem = (transmem_block_t *) malloc (freemem_size);
++# ifdef _LIBC
++                    if (newmem != NULL)
++                      {
++                        /* Add the block to the list of blocks we have to free
++                           at some point.  */
++                        newmem->next = transmem_list;
++                        transmem_list = newmem;
++                      }
++                    /* Fall through and return -1.  */
++# endif
+                   }
+                 if (__builtin_expect (newmem == NULL, 0))
+                   {
+@@ -1181,11 +1201,6 @@ _nl_find_msg (domain_file, domainbinding
+                   }
+ # ifdef _LIBC
+-                /* Add the block to the list of blocks we have to free
+-                   at some point.  */
+-                newmem->next = transmem_list;
+-                transmem_list = newmem;
+-
+                 freemem = (unsigned char *) newmem->data;
+                 freemem_size -= offsetof (struct transmem_list, data);
+ # else
+@@ -1402,7 +1417,7 @@ get_output_charset (domainbinding)
+         return _NL_CURRENT (LC_CTYPE, CODESET);
+ # else
+ #  if HAVE_ICONV
+-        extern const char *locale_charset PARAMS ((void);
++        extern const char *locale_charset PARAMS ((void));
+         return locale_charset ();
+ #  endif
+ # endif
+diff -Nrup a/intl/loadmsgcat.c b/intl/loadmsgcat.c
+--- a/intl/loadmsgcat.c        2010-05-04 07:27:23.000000000 -0400
++++ b/intl/loadmsgcat.c        2013-08-01 00:12:48.448237849 -0400
+@@ -1235,7 +1235,7 @@ _nl_load_domain (domain_file, domainbind
+     default:
+       /* This is an invalid revision.  */
+     invalid:
+-      /* This is an invalid .mo file.  */
++      /* This is an invalid .mo file or we ran out of resources.  */
+       free (domain->malloced);
+ #ifdef HAVE_MMAP
+       if (use_mmap)
+@@ -1255,6 +1255,12 @@ _nl_load_domain (domain_file, domainbind
+   /* Get the header entry and look for a plural specification.  */
+   nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
++  if (__builtin_expect (nullentry == (char *) -1, 0))
++    {
++      __libc_rwlock_fini (domain->conversions_lock);
++      goto invalid;
++    }
++
+   EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
+  out:
diff --git a/src/patches/glibc/glibc-rh989558.patch b/src/patches/glibc/glibc-rh989558.patch
new file mode 100644 (file)
index 0000000..61ddbe8
--- /dev/null
@@ -0,0 +1,181 @@
+#
+# Red Hat BZ:
+# https://bugzilla.redhat.com/show_bug.cgi?id=816647
+#
+# ChangeLog
+#
+#2013-04-30  Patsy Franklin  <pfrankli@redhat.com>
+#
+#      * iconv/gconv_cache.c (find_module): Demangle init_fct before 
+#      checking for NULL. Mangle __btowc_fct if init_fct is non-NULL.
+#      * iconv/gconv_db.c (free_derivation): Check that __shlib_handle 
+#      is non-NULL before demangling the end_fct.  Check for NULL
+#      end_fct after demangling.
+#      (__gconv_release_step): Demangle the end_fct before checking 
+#      it for NULL.   Remove assert on __shlibc_handle != NULL.
+#      (gen_steps): Don't check btowc_fct for NULL before mangling.  
+#      Demangle init_fct before checking for NULL.
+#      (increment_counter): Likewise
+#      * gconv_dl.c (__gconv_find_shlib): Don't check init_fct or
+#      end_fct for NULL before mangling.
+#      * wcsmbs/btowc.c (__btowc): Demangle btowc_fct before checking
+#      for NULL.
+#
+diff -Nrup a/iconv/gconv_cache.c b/iconv/gconv_cache.c
+--- a/iconv/gconv_cache.c      2012-12-24 22:02:13.000000000 -0500
++++ b/iconv/gconv_cache.c      2013-04-30 11:34:20.112389987 -0400
+@@ -207,17 +207,16 @@ find_module (const char *directory, cons
+       result->__data = NULL;
+       /* Call the init function.  */
+-      if (result->__init_fct != NULL)
+-      {
+-        __gconv_init_fct init_fct = result->__init_fct;
++      __gconv_init_fct init_fct = result->__init_fct;
+ #ifdef PTR_DEMANGLE
+-        PTR_DEMANGLE (init_fct);
++      PTR_DEMANGLE (init_fct);
+ #endif
++      if (init_fct != NULL)
++      {
+         status = DL_CALL_FCT (init_fct, (result));
+ #ifdef PTR_MANGLE
+-        if (result->__btowc_fct != NULL)
+-          PTR_MANGLE (result->__btowc_fct);
++        PTR_MANGLE (result->__btowc_fct);
+ #endif
+       }
+     }
+diff -Nrup a/iconv/gconv_db.c b/iconv/gconv_db.c
+--- a/iconv/gconv_db.c 2012-12-24 22:02:13.000000000 -0500
++++ b/iconv/gconv_db.c 2013-04-30 11:32:42.700592914 -0400
+@@ -179,16 +179,15 @@ free_derivation (void *p)
+   size_t cnt;
+   for (cnt = 0; cnt < deriv->nsteps; ++cnt)
+-    if (deriv->steps[cnt].__counter > 0
+-      && deriv->steps[cnt].__end_fct != NULL)
++    if ((deriv->steps[cnt].__counter > 0)
++      && (deriv->steps[cnt].__shlib_handle != NULL))
+       {
+-      assert (deriv->steps[cnt].__shlib_handle != NULL);
+-
+       __gconv_end_fct end_fct = deriv->steps[cnt].__end_fct;
+ #ifdef PTR_DEMANGLE
+       PTR_DEMANGLE (end_fct);
+ #endif
+-      DL_CALL_FCT (end_fct, (&deriv->steps[cnt]));
++      if (end_fct != NULL)
++        DL_CALL_FCT (end_fct, (&deriv->steps[cnt]));
+       }
+   /* Free the name strings.  */
+@@ -212,16 +211,12 @@ __gconv_release_step (struct __gconv_ste
+   if (step->__shlib_handle != NULL && --step->__counter == 0)
+     {
+       /* Call the destructor.  */
+-      if (step->__end_fct != NULL)
+-      {
+-        assert (step->__shlib_handle != NULL);
+-
+-        __gconv_end_fct end_fct = step->__end_fct;
++      __gconv_end_fct end_fct = step->__end_fct;
+ #ifdef PTR_DEMANGLE
+-        PTR_DEMANGLE (end_fct);
++      PTR_DEMANGLE (end_fct);
+ #endif
+-        DL_CALL_FCT (end_fct, (step));
+-      }
++      if (end_fct != NULL)
++      DL_CALL_FCT (end_fct, (step));
+ #ifndef STATIC_GCONV
+       /* Release the loaded module.  */
+@@ -293,13 +288,11 @@ gen_steps (struct derivation_step *best,
+             /* Call the init function.  */
+             __gconv_init_fct init_fct = result[step_cnt].__init_fct;
+-            if (init_fct != NULL)
+-              {
+-                assert (result[step_cnt].__shlib_handle != NULL);
+-
+ # ifdef PTR_DEMANGLE
+-                PTR_DEMANGLE (init_fct);
++            PTR_DEMANGLE (init_fct);
+ # endif
++            if (init_fct != NULL)
++              {
+                 status = DL_CALL_FCT (init_fct, (&result[step_cnt]));
+                 if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK)
+@@ -312,8 +305,7 @@ gen_steps (struct derivation_step *best,
+                   }
+ # ifdef PTR_MANGLE
+-                if (result[step_cnt].__btowc_fct != NULL)
+-                  PTR_MANGLE (result[step_cnt].__btowc_fct);
++                PTR_MANGLE (result[step_cnt].__btowc_fct);
+ # endif
+               }
+           }
+@@ -393,16 +385,15 @@ increment_counter (struct __gconv_step *
+         /* Call the init function.  */
+         __gconv_init_fct init_fct = step->__init_fct;
+-        if (init_fct != NULL)
+-          {
+ #ifdef PTR_DEMANGLE
+-            PTR_DEMANGLE (init_fct);
++        PTR_DEMANGLE (init_fct);
+ #endif
++        if (init_fct != NULL)
++          {
+             DL_CALL_FCT (init_fct, (step));
+ #ifdef PTR_MANGLE
+-            if (step->__btowc_fct != NULL)
+-              PTR_MANGLE (step->__btowc_fct);
++            PTR_MANGLE (step->__btowc_fct);
+ #endif
+           }
+       }
+diff -Nrup a/iconv/gconv_dl.c b/iconv/gconv_dl.c
+--- a/iconv/gconv_dl.c 2012-12-24 22:02:13.000000000 -0500
++++ b/iconv/gconv_dl.c 2013-04-30 11:32:42.701592922 -0400
+@@ -132,10 +132,8 @@ __gconv_find_shlib (const char *name)
+ #ifdef PTR_MANGLE
+                 PTR_MANGLE (found->fct);
+-                if (found->init_fct != NULL)
+-                  PTR_MANGLE (found->init_fct);
+-                if (found->end_fct !=  NULL)
+-                  PTR_MANGLE (found->end_fct);
++                PTR_MANGLE (found->init_fct);
++                PTR_MANGLE (found->end_fct);
+ #endif
+                 /* We have succeeded in loading the shared object.  */
+diff -Nrup a/wcsmbs/btowc.c b/wcsmbs/btowc.c
+--- a/wcsmbs/btowc.c   2012-12-24 22:02:13.000000000 -0500
++++ b/wcsmbs/btowc.c   2013-04-30 11:32:42.701592922 -0400
+@@ -47,15 +47,15 @@ __btowc (c)
+   /* Get the conversion functions.  */
+   fcts = get_gconv_fcts (_NL_CURRENT_DATA (LC_CTYPE));
+   __gconv_btowc_fct btowc_fct = fcts->towc->__btowc_fct;
++#ifdef PTR_DEMANGLE
++  if (fcts->towc->__shlib_handle != NULL)
++    PTR_DEMANGLE (btowc_fct);
++#endif
+   if (__builtin_expect (fcts->towc_nsteps == 1, 1)
+       && __builtin_expect (btowc_fct != NULL, 1))
+     {
+       /* Use the shortcut function.  */
+-#ifdef PTR_DEMANGLE
+-      if (fcts->towc->__shlib_handle != NULL)
+-      PTR_DEMANGLE (btowc_fct);
+-#endif
+       return DL_CALL_FCT (btowc_fct, (fcts->towc, (unsigned char) c));
+     }
+   else