This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch ibm/2.19/master created. glibc-2.19-56-g88a8a35


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, ibm/2.19/master has been created
        at  88a8a351f3a6a95205a1499fd68b79fc3d0b9d19 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=88a8a351f3a6a95205a1499fd68b79fc3d0b9d19

commit 88a8a351f3a6a95205a1499fd68b79fc3d0b9d19
Author: Carlos O'Donell <carlos@redhat.com>
Date:   Wed Nov 19 11:44:12 2014 -0500

    CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
    
    The function wordexp() fails to properly handle the WRDE_NOCMD
    flag when processing arithmetic inputs in the form of "$((... ``))"
    where "..." can be anything valid. The backticks in the arithmetic
    epxression are evaluated by in a shell even if WRDE_NOCMD forbade
    command substitution. This allows an attacker to attempt to pass
    dangerous commands via constructs of the above form, and bypass
    the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
    in exec_comm(), the only place that can execute a shell. All other
    checks for WRDE_NOCMD are superfluous and removed.
    
    We expand the testsuite and add 3 new regression tests of roughly
    the same form but with a couple of nested levels.
    
    On top of the 3 new tests we add fork validation to the WRDE_NOCMD
    testing. If any forks are detected during the execution of a wordexp()
    call with WRDE_NOCMD, the test is marked as failed. This is slightly
    heuristic since vfork might be used in the future, but it provides a
    higher level of assurance that no shells were executed as part of
    command substitution with WRDE_NOCMD in effect. In addition it doesn't
    require libpthread or libdl, instead we use the public implementation
    namespace function __register_atfork (already part of the public ABI
    for libpthread).
    
    Tested on x86_64 with no regressions.

diff --git a/ChangeLog b/ChangeLog
index f66dfe3..1e9511e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2014-11-19  Carlos O'Donell  <carlos@redhat.com>
+	    Florian Weimer  <fweimer@redhat.com>
+	    Joseph Myers  <joseph@codesourcery.com>
+	    Adam Conrad  <adconrad@0c3.net>
+	    Andreas Schwab  <schwab@suse.de>
+	    Brooks  <bmoses@google.com>
+
+	[BZ #17625]
+	* wordexp-test.c (__dso_handle): Add prototype.
+	(__register_atfork): Likewise.
+	(__app_register_atfork): New function.
+	(registered_forks): New global.
+	(register_fork): New function.
+	(test_case): Add 3 new tests for WRDE_CMDSUB.
+	(main): Call __app_register_atfork.
+	(testit): If WRDE_NOCMD set registered_forks to zero, run test, and if
+	fork count is non-zero fail the test.
+	* posix/wordexp.c (exec_comm): Return WRDE_CMDSUB if WRDE_NOCMD flag
+	is set.
+	(parse_dollars): Remove check for WRDE_NOCMD.
+	(parse_dquote): Likewise.
+
 2014-12-16  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17630]
diff --git a/NEWS b/NEWS
index b4ed743..8048bdb 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,13 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16617, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619,
-  16740, 17031, 17048, 17137, 17153, 17187, 17213, 17325, 17630.
+  16740, 17031, 17048, 17137, 17153, 17187, 17213, 17325, 17625, 17630.
+
+* CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
+  under certain input conditions resulting in the execution of a shell for
+  command substitution when the applicaiton did not request it. The
+  implementation now checks WRDE_NOCMD immediately before executing the
+  shell and returns the error WRDE_CMDSUB as expected.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index 4957006..bdd65e4 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -27,6 +27,25 @@
 
 #define IFS " \n\t"
 
+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
+extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
+
+static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
+{
+  return __register_atfork (prepare, parent, child,
+			    &__dso_handle == NULL ? NULL : __dso_handle);
+}
+
+/* Number of forks seen.  */
+static int registered_forks;
+
+/* For each fork increment the fork count.  */
+static void
+register_fork (void)
+{
+  registered_forks++;
+}
+
 struct test_case_struct
 {
   int retval;
@@ -206,6 +225,12 @@ struct test_case_struct
     { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
     { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
     { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
+    /* Test for CVE-2014-7817. We test 3 combinations of command
+       substitution inside an arithmetic expression to make sure that
+       no commands are executed and error is returned.  */
+    { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
+    { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
+    { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
 
     { -1, NULL, NULL, 0, 0, { NULL, }, IFS },
   };
@@ -258,6 +283,15 @@ main (int argc, char *argv[])
 	  return -1;
     }
 
+  /* If we are not allowed to do command substitution, we install
+     fork handlers to verify that no forks happened.  No forks should
+     happen at all if command substitution is disabled.  */
+  if (__app_register_atfork (register_fork, NULL, NULL) != 0)
+    {
+      printf ("Failed to register fork handler.\n");
+      return -1;
+    }
+
   for (test = 0; test_case[test].retval != -1; test++)
     if (testit (&test_case[test]))
       ++fail;
@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
 
   printf ("Test %d (%s): ", ++tests, tc->words);
 
+  if (tc->flags & WRDE_NOCMD)
+    registered_forks = 0;
+
   if (tc->flags & WRDE_APPEND)
     {
       /* initial wordexp() call, to be appended to */
@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
     }
   retval = wordexp (tc->words, &we, tc->flags);
 
+  if ((tc->flags & WRDE_NOCMD)
+      && (registered_forks > 0))
+    {
+	  printf ("FAILED fork called for WRDE_NOCMD\n");
+	  return 1;
+    }
+
   if (tc->flags & WRDE_DOOFFS)
       start_offs = sav_we.we_offs;
 
diff --git a/posix/wordexp.c b/posix/wordexp.c
index 366ec18..36a1367 100644
--- a/posix/wordexp.c
+++ b/posix/wordexp.c
@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
   pid_t pid;
   int noexec = 0;
 
+  /* Do nothing if command substitution should not succeed.  */
+  if (flags & WRDE_NOCMD)
+    return WRDE_CMDSUB;
+
   /* Don't fork() unless necessary */
   if (!comm || !*comm)
     return 0;
@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
 	    }
 	}
 
-      if (flags & WRDE_NOCMD)
-	return WRDE_CMDSUB;
-
       (*offset) += 2;
       return parse_comm (word, word_length, max_length, words, offset, flags,
 			 quoted? NULL : pwordexp, ifs, ifs_white);
@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length,
 	  break;
 
 	case '`':
-	  if (flags & WRDE_NOCMD)
-	    return WRDE_CMDSUB;
-
 	  ++(*offset);
 	  error = parse_backtick (word, word_length, max_length, words,
 				  offset, flags, NULL, NULL, NULL);
@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
 	break;
 
       case '`':
-	if (flags & WRDE_NOCMD)
-	  {
-	    error = WRDE_CMDSUB;
-	    goto do_error;
-	  }
-
 	++words_offset;
 	error = parse_backtick (&word, &word_length, &max_length, words,
 				&words_offset, flags, pwordexp, ifs,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=32404a33a03747951daafde164e3b14464c28fe9

commit 32404a33a03747951daafde164e3b14464c28fe9
Author: Allan McRae <allan@archlinux.org>
Date:   Thu Dec 18 11:01:43 2014 +1000

    Label CVE-2014-9402 in NEWS

diff --git a/NEWS b/NEWS
index c969924..b4ed743 100644
--- a/NEWS
+++ b/NEWS
@@ -42,8 +42,9 @@ Version 2.19.1
 * CVE-2012-3406 printf-style functions could run into a stack overflow when
   processing format strings with a large number of format specifiers.
 
-* The nss_dns implementation of getnetbyname could run into an infinite loop
-  if the DNS response contained a PTR record of an unexpected format.
+* CVE-2014-9402 The nss_dns implementation of getnetbyname could run into an
+  infinite loop if the DNS response contained a PTR record of an unexpected
+  format.
 
 Version 2.19
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=d2a6f3a27b791d91beec2ea91f293ec898080904

commit d2a6f3a27b791d91beec2ea91f293ec898080904
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon Dec 15 17:41:13 2014 +0100

    Avoid infinite loop in nss_dns getnetbyname [BZ #17630]

diff --git a/ChangeLog b/ChangeLog
index fc39411..f66dfe3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-16  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17630]
+	* resolv/nss_dns/dns-network.c (getanswer_r): Iterate over alias
+	names.
+
 2014-12-15  Jeff Law  <law@redhat.com>
 
 	[BZ #16617]
diff --git a/NEWS b/NEWS
index 1f83025..c969924 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16617, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619,
-  16740, 17031, 17048, 17137, 17153, 17187, 17213, 17325.
+  16740, 17031, 17048, 17137, 17153, 17187, 17213, 17325, 17630.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
@@ -41,6 +41,9 @@ Version 2.19.1
 
 * CVE-2012-3406 printf-style functions could run into a stack overflow when
   processing format strings with a large number of format specifiers.
+
+* The nss_dns implementation of getnetbyname could run into an infinite loop
+  if the DNS response contained a PTR record of an unexpected format.
 
 Version 2.19
 
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index 8e80a60..60c94f3 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -398,8 +398,8 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
 
 	case BYNAME:
 	  {
-	    char **ap = result->n_aliases++;
-	    while (*ap != NULL)
+	    char **ap;
+	    for (ap = result->n_aliases; *ap != NULL; ++ap)
 	      {
 		/* Check each alias name for being of the forms:
 		   4.3.2.1.in-addr.arpa		= net 1.2.3.4

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=39700792d4224af99ab52ea26e98a0a2a2ed6ac6

commit 39700792d4224af99ab52ea26e98a0a2a2ed6ac6
Author: Jeff Law <law@redhat.com>
Date:   Mon Dec 15 10:09:32 2014 +0100

    CVE-2012-3406: Stack overflow in vfprintf [BZ #16617]
    
    A larger number of format specifiers coudld cause a stack overflow,
    potentially allowing to bypass _FORTIFY_SOURCE format string
    protection.

diff --git a/ChangeLog b/ChangeLog
index b399a9b..fc39411 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-12-15  Jeff Law  <law@redhat.com>
+
+	[BZ #16617]
+	* stdio-common/vfprintf.c (vfprintf): Allocate large specs array
+	on the heap.  (CVE-2012-3406)
+	* stdio-common/bug23-2.c, stdio-common/bug23-3.c: New file.
+	* stdio-common/bug23-4.c: New file.  Test case by Joseph Myers.
+	* stdio-common/Makefile (tests): Add bug23-2, bug23-3, bug23-4.
+
 2014-06-21  Allan McRae  <allan@archlinux.org>
 
 	* NEWS: Mention CVE-2014-4043.
diff --git a/NEWS b/NEWS
index 7aa51f1..1f83025 100644
--- a/NEWS
+++ b/NEWS
@@ -9,8 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17048, 17137, 17153, 17187, 17213, 17325.
+  16545, 16617, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619,
+  16740, 17031, 17048, 17137, 17153, 17187, 17213, 17325.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
@@ -38,6 +38,9 @@ Version 2.19.1
   deference a dangling pointer, or use an unexpected pathname argument if
   the string was modified after the posix_spawn_file_actions_addopen
   invocation.
+
+* CVE-2012-3406 printf-style functions could run into a stack overflow when
+  processing format strings with a large number of format specifiers.
 
 Version 2.19
 
diff --git a/stdio-common/Makefile b/stdio-common/Makefile
index 76eccb0..cb671e2 100644
--- a/stdio-common/Makefile
+++ b/stdio-common/Makefile
@@ -57,7 +57,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
 	 bug19 bug19a tst-popen2 scanf13 scanf14 scanf15 bug20 bug21 bug22 \
 	 scanf16 scanf17 tst-setvbuf1 tst-grouping bug23 bug24 \
 	 bug-vfprintf-nargs tst-long-dbl-fphex tst-fphex-wide tst-sprintf3 \
-	 bug25 tst-printf-round bug26
+	 bug25 tst-printf-round bug23-2 bug23-3 bug23-4
 
 test-srcs = tst-unbputc tst-printf
 
diff --git a/stdio-common/bug23-2.c b/stdio-common/bug23-2.c
new file mode 100644
index 0000000..9e0cfe6
--- /dev/null
+++ b/stdio-common/bug23-2.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static const char expected[] = "\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55\
+\n\
+a\n\
+abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
+
+static int
+do_test (void)
+{
+  char *buf = malloc (strlen (expected) + 1);
+  snprintf (buf, strlen (expected) + 1,
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+	    "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",
+	    "a", "b", "c", "d", 5);
+  return strcmp (buf, expected) != 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/bug23-3.c b/stdio-common/bug23-3.c
new file mode 100644
index 0000000..57c8cef
--- /dev/null
+++ b/stdio-common/bug23-3.c
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+do_test (void)
+{
+  size_t instances = 16384;
+#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d"
+  const char *item = "\na\nabbcd55";
+#define X3 X0 X0 X0 X0 X0 X0 X0 X0
+#define X6 X3 X3 X3 X3 X3 X3 X3 X3
+#define X9 X6 X6 X6 X6 X6 X6 X6 X6
+#define X12 X9 X9 X9 X9 X9 X9 X9 X9
+#define X14 X12 X12 X12 X12
+#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%"
+#define TRAILER2 TRAILER TRAILER
+  size_t length = instances * strlen (item) + strlen (TRAILER) + 1;
+
+  char *buf = malloc (length + 1);
+  snprintf (buf, length + 1,
+	    X14 TRAILER2 "\n",
+	    "a", "b", "c", "d", 5);
+
+  const char *p = buf;
+  size_t i;
+  for (i = 0; i < instances; ++i)
+    {
+      const char *expected;
+      for (expected = item; *expected; ++expected)
+	{
+	  if (*p != *expected)
+	    {
+	      printf ("mismatch at offset %zu (%zu): expected %d, got %d\n",
+		      (size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF);
+	      return 1;
+	    }
+	  ++p;
+	}
+    }
+  if (strcmp (p, TRAILER "\n") != 0)
+    {
+      printf ("mismatch at trailer: [%s]\n", p);
+      return 1;
+    }
+  free (buf);
+  return 0;
+}
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdio-common/bug23-4.c b/stdio-common/bug23-4.c
new file mode 100644
index 0000000..a478564
--- /dev/null
+++ b/stdio-common/bug23-4.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+
+#define LIMIT 1000000
+
+int
+main (void)
+{
+  struct rlimit lim;
+  getrlimit (RLIMIT_STACK, &lim);
+  lim.rlim_cur = 1048576;
+  setrlimit (RLIMIT_STACK, &lim);
+  char *fmtstr = malloc (4 * LIMIT + 1);
+  if (fmtstr == NULL)
+    abort ();
+  char *output = malloc (LIMIT + 1);
+  if (output == NULL)
+    abort ();
+  for (size_t i = 0; i < LIMIT; i++)
+    memcpy (fmtstr + 4 * i, "%1$d", 4);
+  fmtstr[4 * LIMIT] = '\0';
+  int ret = snprintf (output, LIMIT + 1, fmtstr, 0);
+  if (ret != LIMIT)
+    abort ();
+  for (size_t i = 0; i < LIMIT; i++)
+    if (output[i] != '0')
+      abort ();
+  return 0;
+}
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index f7e5f61..f423be6 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -263,6 +263,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
   /* For the argument descriptions, which may be allocated on the heap.  */
   void *args_malloced = NULL;
 
+  /* For positional argument handling.  */
+  struct printf_spec *specs;
+
+  /* Track if we malloced the SPECS array and thus must free it.  */
+  bool specs_malloced = false;
+
   /* This table maps a character into a number representing a
      class.  In each step there is a destination label for each
      class.  */
@@ -1678,8 +1684,8 @@ do_positional:
     size_t nspecs = 0;
     /* A more or less arbitrary start value.  */
     size_t nspecs_size = 32 * sizeof (struct printf_spec);
-    struct printf_spec *specs = alloca (nspecs_size);
 
+    specs = alloca (nspecs_size);
     /* The number of arguments the format string requests.  This will
        determine the size of the array needed to store the argument
        attributes.  */
@@ -1720,11 +1726,39 @@ do_positional:
 	if (nspecs * sizeof (*specs) >= nspecs_size)
 	  {
 	    /* Extend the array of format specifiers.  */
+	    if (nspecs_size * 2 < nspecs_size)
+	      {
+		__set_errno (ENOMEM);
+		done = -1;
+		goto all_done;
+	      }
 	    struct printf_spec *old = specs;
-	    specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
+	    if (__libc_use_alloca (2 * nspecs_size))
+	      specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size);
+	    else
+	      {
+		nspecs_size *= 2;
+		specs = malloc (nspecs_size);
+		if (specs == NULL)
+		  {
+		    __set_errno (ENOMEM);
+		    specs = old;
+		    done = -1;
+		    goto all_done;
+		  }
+	      }
 
 	    /* Copy the old array's elements to the new space.  */
 	    memmove (specs, old, nspecs * sizeof (*specs));
+
+	    /* If we had previously malloc'd space for SPECS, then
+	       release it after the copy is complete.  */
+	    if (specs_malloced)
+	      free (old);
+
+	    /* Now set SPECS_MALLOCED if needed.  */
+	    if (!__libc_use_alloca (nspecs_size))
+	      specs_malloced = true;
 	  }
 
 	/* Parse the format specifier.  */
@@ -2045,6 +2079,8 @@ do_positional:
   }
 
 all_done:
+  if (specs_malloced)
+    free (specs);
   if (__glibc_unlikely (args_malloced != NULL))
     free (args_malloced);
   if (__glibc_unlikely (workstart != NULL))

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5cefe3fc8f35b50eb84cbb740268539a40651173

commit 5cefe3fc8f35b50eb84cbb740268539a40651173
Author: Allan McRae <allan@archlinux.org>
Date:   Sat Jun 21 17:23:55 2014 +1000

    Mention CVE-2014-4043 in NEWS

diff --git a/ChangeLog b/ChangeLog
index 45675f2..b399a9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-06-21  Allan McRae  <allan@archlinux.org>
+
+	* NEWS: Mention CVE-2014-4043.
+
 2014-06-11  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17048]
diff --git a/NEWS b/NEWS
index b6d603a..7aa51f1 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,12 @@ Version 2.19.1
   silently replaced with the "C" locale when running in AT_SECURE mode
   (e.g., in a SUID program).  This is no longer necessary because of the
   additional checks.
+
+* CVE-2014-4043 The posix_spawn_file_actions_addopen implementation did not
+  copy the path argument.  This allowed programs to cause posix_spawn to
+  deference a dangling pointer, or use an unexpected pathname argument if
+  the string was modified after the posix_spawn_file_actions_addopen
+  invocation.
 
 Version 2.19
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=eece504424b59a1d8de7b4da9c64e24acaa6fbe0

commit eece504424b59a1d8de7b4da9c64e24acaa6fbe0
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Jun 11 23:12:52 2014 +0200

    posix_spawn_file_actions_addopen needs to copy the path argument (BZ 17048)
    
    POSIX requires that we make a copy, so we allocate a new string
    and free it in posix_spawn_file_actions_destroy.
    
    Reported by David Reid, Alex Gaynor, and Glyph Lefkowitz.  This bug
    may have security implications.

diff --git a/ChangeLog b/ChangeLog
index 074747f..45675f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-06-11  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17048]
+	* posix/spawn_int.h (struct __spawn_action): Make the path string
+	non-const to support deallocation.
+	* posix/spawn_faction_addopen.c
+	(posix_spawn_file_actions_addopen): Make a copy of the pathname.
+	* posix/spawn_faction_destroy.c
+	(posix_spawn_file_actions_destroy): Adjust comment.  Deallocate
+	path in all spawn_do_open actions.
+	* posix/tst-spawn.c (do_test): Exercise the copy operation in
+	posix_spawn_file_actions_addopen.
+
 2014-07-02  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17137]
diff --git a/NEWS b/NEWS
index 0298834..b6d603a 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17137, 17153, 17187, 17213, 17325.
+  17031, 17048, 17137, 17153, 17187, 17213, 17325.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
diff --git a/posix/spawn_faction_addopen.c b/posix/spawn_faction_addopen.c
index 47f6242..40800b8 100644
--- a/posix/spawn_faction_addopen.c
+++ b/posix/spawn_faction_addopen.c
@@ -35,17 +35,24 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions,
   if (fd < 0 || fd >= maxfd)
     return EBADF;
 
+  char *path_copy = strdup (path);
+  if (path_copy == NULL)
+    return ENOMEM;
+
   /* Allocate more memory if needed.  */
   if (file_actions->__used == file_actions->__allocated
       && __posix_spawn_file_actions_realloc (file_actions) != 0)
-    /* This can only mean we ran out of memory.  */
-    return ENOMEM;
+    {
+      /* This can only mean we ran out of memory.  */
+      free (path_copy);
+      return ENOMEM;
+    }
 
   /* Add the new value.  */
   rec = &file_actions->__actions[file_actions->__used];
   rec->tag = spawn_do_open;
   rec->action.open_action.fd = fd;
-  rec->action.open_action.path = path;
+  rec->action.open_action.path = path_copy;
   rec->action.open_action.oflag = oflag;
   rec->action.open_action.mode = mode;
 
diff --git a/posix/spawn_faction_destroy.c b/posix/spawn_faction_destroy.c
index 4d165aa..1b87010 100644
--- a/posix/spawn_faction_destroy.c
+++ b/posix/spawn_faction_destroy.c
@@ -18,11 +18,29 @@
 #include <spawn.h>
 #include <stdlib.h>
 
-/* Initialize data structure for file attribute for `spawn' call.  */
+#include "spawn_int.h"
+
+/* Deallocate the file actions.  */
 int
 posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
 {
-  /* Free the memory allocated.  */
+  /* Free the paths in the open actions.  */
+  for (int i = 0; i < file_actions->__used; ++i)
+    {
+      struct __spawn_action *sa = &file_actions->__actions[i];
+      switch (sa->tag)
+	{
+	case spawn_do_open:
+	  free (sa->action.open_action.path);
+	  break;
+	case spawn_do_close:
+	case spawn_do_dup2:
+	  /* No cleanup required.  */
+	  break;
+	}
+    }
+
+  /* Free the array of actions.  */
   free (file_actions->__actions);
   return 0;
 }
diff --git a/posix/spawn_int.h b/posix/spawn_int.h
index 5609e58..861e3b4 100644
--- a/posix/spawn_int.h
+++ b/posix/spawn_int.h
@@ -22,7 +22,7 @@ struct __spawn_action
     struct
     {
       int fd;
-      const char *path;
+      char *path;
       int oflag;
       mode_t mode;
     } open_action;
diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
index 84cecf2..6cd874a 100644
--- a/posix/tst-spawn.c
+++ b/posix/tst-spawn.c
@@ -168,6 +168,7 @@ do_test (int argc, char *argv[])
   char fd2name[18];
   char fd3name[18];
   char fd4name[18];
+  char *name3_copy;
   char *spargv[12];
   int i;
 
@@ -222,9 +223,15 @@ do_test (int argc, char *argv[])
    if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
    /* We want to open the third file.  */
-   if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
+   name3_copy = strdup (name3);
+   if (name3_copy == NULL)
+     error (EXIT_FAILURE, errno, "strdup");
+   if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
 					 O_RDONLY, 0666) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
+   /* Overwrite the name to check that a copy has been made.  */
+   memset (name3_copy, 'X', strlen (name3_copy));
+
    /* We dup the second descriptor.  */
    fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
    if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
@@ -253,6 +260,7 @@ do_test (int argc, char *argv[])
    /* Cleanup.  */
    if (posix_spawn_file_actions_destroy (&actions) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
+   free (name3_copy);
 
   /* Wait for the child.  */
   if (waitpid (pid, &status, 0) != pid)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=dcf0cce30d91100005e9aeb002096236325648fb

commit dcf0cce30d91100005e9aeb002096236325648fb
Author: Florian Weimer <fweimer@redhat.com>
Date:   Mon May 12 15:24:12 2014 +0200

    _nl_find_locale: Improve handling of crafted locale names [BZ #17137]
    
    Prevent directory traversal in locale-related environment variables
    (CVE-2014-0475).

diff --git a/ChangeLog b/ChangeLog
index 555d724..074747f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17137]
+	* locale/findlocale.c (name_present, valid_locale_name): New
+	functions.
+	(_nl_find_locale): Use the loc_name variable to store name
+	candidates.  Call name_present and valid_locale_name to check and
+	validate locale names.  Return an error if the locale is invalid.
+
 2014-08-26  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17187]
diff --git a/NEWS b/NEWS
index 7a64a0b..0298834 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17153, 17187, 17213, 17325.
+  17031, 17137, 17153, 17187, 17213, 17325.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
@@ -23,6 +23,15 @@ Version 2.19.1
   normal gconv conversion modules are still supported.  Transliteration
   with //TRANSLIT is still possible, and the //IGNORE specifier
   continues to be  supported. (CVE-2014-5519)
+
+* Locale names, including those obtained from environment variables (LANG
+  and the LC_* variables), are more tightly checked for proper syntax.
+  setlocale will now fail (with EINVAL) for locale names that are overly
+  long, contain slashes without starting with a slash, or contain ".." path
+  components. (CVE-2014-0475)  Previously, some valid locale names were
+  silently replaced with the "C" locale when running in AT_SECURE mode
+  (e.g., in a SUID program).  This is no longer necessary because of the
+  additional checks.
 
 Version 2.19
 
diff --git a/locale/findlocale.c b/locale/findlocale.c
index 0c42b99..faeee61 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <assert.h>
+#include <errno.h>
 #include <locale.h>
 #include <stdlib.h>
 #include <string.h>
@@ -57,6 +58,45 @@ struct loaded_l10nfile *_nl_locale_file_list[__LC_LAST];
 
 const char _nl_default_locale_path[] attribute_hidden = LOCALEDIR;
 
+/* Checks if the name is actually present, that is, not NULL and not
+   empty.  */
+static inline int
+name_present (const char *name)
+{
+  return name != NULL && name[0] != '\0';
+}
+
+/* Checks that the locale name neither extremely long, nor contains a
+   ".." path component (to prevent directory traversal).  */
+static inline int
+valid_locale_name (const char *name)
+{
+  /* Not set.  */
+  size_t namelen = strlen (name);
+  /* Name too long.  The limit is arbitrary and prevents stack overflow
+     issues later.  */
+  if (__glibc_unlikely (namelen > 255))
+    return 0;
+  /* Directory traversal attempt.  */
+  static const char slashdot[4] = {'/', '.', '.', '/'};
+  if (__glibc_unlikely (memmem (name, namelen,
+				slashdot, sizeof (slashdot)) != NULL))
+    return 0;
+  if (namelen == 2 && __glibc_unlikely (name[0] == '.' && name [1] == '.'))
+    return 0;
+  if (namelen >= 3
+      && __glibc_unlikely (((name[0] == '.'
+			     && name[1] == '.'
+			     && name[2] == '/')
+			    || (name[namelen - 3] == '/'
+				&& name[namelen - 2] == '.'
+				&& name[namelen - 1] == '.'))))
+    return 0;
+  /* If there is a slash in the name, it must start with one.  */
+  if (__glibc_unlikely (memchr (name, '/', namelen) != NULL) && name[0] != '/')
+    return 0;
+  return 1;
+}
 
 struct __locale_data *
 internal_function
@@ -65,7 +105,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 {
   int mask;
   /* Name of the locale for this category.  */
-  char *loc_name;
+  char *loc_name = (char *) *name;
   const char *language;
   const char *modifier;
   const char *territory;
@@ -73,31 +113,39 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
   const char *normalized_codeset;
   struct loaded_l10nfile *locale_file;
 
-  if ((*name)[0] == '\0')
+  if (loc_name[0] == '\0')
     {
       /* The user decides which locale to use by setting environment
 	 variables.  */
-      *name = getenv ("LC_ALL");
-      if (*name == NULL || (*name)[0] == '\0')
-	*name = getenv (_nl_category_names.str
+      loc_name = getenv ("LC_ALL");
+      if (!name_present (loc_name))
+	loc_name = getenv (_nl_category_names.str
 			+ _nl_category_name_idxs[category]);
-      if (*name == NULL || (*name)[0] == '\0')
-	*name = getenv ("LANG");
+      if (!name_present (loc_name))
+	loc_name = getenv ("LANG");
+      if (!name_present (loc_name))
+	loc_name = (char *) _nl_C_name;
     }
 
-  if (*name == NULL || (*name)[0] == '\0'
-      || (__builtin_expect (__libc_enable_secure, 0)
-	  && strchr (*name, '/') != NULL))
-    *name = (char *) _nl_C_name;
+  /* We used to fall back to the C locale if the name contains a slash
+     character '/', but we now check for directory traversal in
+     valid_locale_name, so this is no longer necessary.  */
 
-  if (__builtin_expect (strcmp (*name, _nl_C_name), 1) == 0
-      || __builtin_expect (strcmp (*name, _nl_POSIX_name), 1) == 0)
+  if (__builtin_expect (strcmp (loc_name, _nl_C_name), 1) == 0
+      || __builtin_expect (strcmp (loc_name, _nl_POSIX_name), 1) == 0)
     {
       /* We need not load anything.  The needed data is contained in
 	 the library itself.  */
       *name = (char *) _nl_C_name;
       return _nl_C[category];
     }
+  else if (!valid_locale_name (loc_name))
+    {
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  *name = loc_name;
 
   /* We really have to load some data.  First we try the archive,
      but only if there was no LOCPATH environment variable specified.  */
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index a570767..ff7ecb6 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-02  Florian Weimer  <fweimer@redhat.com>
+
+	* tst-setlocale3.c: New file.
+	* Makefile (tests): Add tst-setlocale3.
+	(tst-setlocale3-ENV): New variable.
+
 2013-12-26  Chris Leonard  <cjl@sugarlabs.org>
 
 	* locales/sa_IN: Add lang_name.
diff --git a/localedata/Makefile b/localedata/Makefile
index 7d157bf..9daa470 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -77,7 +77,7 @@ locale_test_suite := tst_iswalnum tst_iswalpha tst_iswcntrl            \
 
 tests = $(locale_test_suite) tst-digits tst-setlocale bug-iconv-trans \
 	tst-leaks tst-mbswcs6 tst-xlocale1 tst-xlocale2 bug-usesetlocale \
-	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2
+	tst-strfmon1 tst-sscanf bug-setlocale1 tst-setlocale2 tst-setlocale3
 tests-static = bug-setlocale1-static
 tests += $(tests-static)
 ifeq (yes,$(build-shared))
diff --git a/localedata/tst-setlocale3.c b/localedata/tst-setlocale3.c
new file mode 100644
index 0000000..e3b21a9
--- /dev/null
+++ b/localedata/tst-setlocale3.c
@@ -0,0 +1,203 @@
+/* Regression test for setlocale invalid environment variable handling.
+   Copyright (C) 2014 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 <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* The result of setlocale may be overwritten by subsequent calls, so
+   this wrapper makes a copy.  */
+static char *
+setlocale_copy (int category, const char *locale)
+{
+  const char *result = setlocale (category, locale);
+  if (result == NULL)
+    return NULL;
+  return strdup (result);
+}
+
+static char *de_locale;
+
+static void
+setlocale_fail (const char *envstring)
+{
+  setenv ("LC_CTYPE", envstring, 1);
+  if (setlocale (LC_CTYPE, "") != NULL)
+    {
+      printf ("unexpected setlocale success for \"%s\" locale\n", envstring);
+      exit (1);
+    }
+  const char *newloc = setlocale (LC_CTYPE, NULL);
+  if (strcmp (newloc, de_locale) != 0)
+    {
+      printf ("failed setlocale call \"%s\" changed locale to \"%s\"\n",
+	      envstring, newloc);
+      exit (1);
+    }
+}
+
+static void
+setlocale_success (const char *envstring)
+{
+  setenv ("LC_CTYPE", envstring, 1);
+  char *newloc = setlocale_copy (LC_CTYPE, "");
+  if (newloc == NULL)
+    {
+      printf ("setlocale for \"%s\": %m\n", envstring);
+      exit (1);
+    }
+  if (strcmp (newloc, de_locale) == 0)
+    {
+      printf ("setlocale with LC_CTYPE=\"%s\" left locale at \"%s\"\n",
+	      envstring, de_locale);
+      exit (1);
+    }
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+	      de_locale, envstring);
+      exit (1);
+    }
+  char *newloc2 = setlocale_copy (LC_CTYPE, newloc);
+  if (newloc2 == NULL)
+    {
+      printf ("restoring locale \"%s\" following \"%s\": %m\n",
+	      newloc, envstring);
+      exit (1);
+    }
+  if (strcmp (newloc, newloc2) != 0)
+    {
+      printf ("representation of locale \"%s\" changed from \"%s\" to \"%s\"",
+	      envstring, newloc, newloc2);
+      exit (1);
+    }
+  free (newloc);
+  free (newloc2);
+
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("restoring locale \"%s\" with LC_CTYPE=\"%s\": %m\n",
+	      de_locale, envstring);
+      exit (1);
+    }
+}
+
+/* Checks that a known-good locale still works if LC_ALL contains a
+   value which should be ignored.  */
+static void
+setlocale_ignore (const char *to_ignore)
+{
+  const char *fr_locale = "fr_FR.UTF-8";
+  setenv ("LC_CTYPE", fr_locale, 1);
+  char *expected_locale = setlocale_copy (LC_CTYPE, "");
+  if (expected_locale == NULL)
+    {
+      printf ("setlocale with LC_CTYPE=\"%s\" failed: %m\n", fr_locale);
+      exit (1);
+    }
+  if (setlocale (LC_CTYPE, de_locale) == NULL)
+    {
+      printf ("failed to restore locale: %m\n");
+      exit (1);
+    }
+  unsetenv ("LC_CTYPE");
+
+  setenv ("LC_ALL", to_ignore, 1);
+  setenv ("LC_CTYPE", fr_locale, 1);
+  const char *actual_locale = setlocale (LC_CTYPE, "");
+  if (actual_locale == NULL)
+    {
+      printf ("setlocale with LC_ALL, LC_CTYPE=\"%s\" failed: %m\n",
+	      fr_locale);
+      exit (1);
+    }
+  if (strcmp (actual_locale, expected_locale) != 0)
+    {
+      printf ("setlocale under LC_ALL failed: got \"%s\", expected \"%s\"\n",
+	      actual_locale, expected_locale);
+      exit (1);
+    }
+  unsetenv ("LC_CTYPE");
+  setlocale_success (fr_locale);
+  unsetenv ("LC_ALL");
+  free (expected_locale);
+}
+
+static int
+do_test (void)
+{
+  /* The glibc test harness sets this environment variable
+     uncondionally.  */
+  unsetenv ("LC_ALL");
+
+  de_locale = setlocale_copy (LC_CTYPE, "de_DE.UTF-8");
+  if (de_locale == NULL)
+    {
+      printf ("setlocale (LC_CTYPE, \"de_DE.UTF-8\"): %m\n");
+      return 1;
+    }
+  setlocale_success ("C");
+  setlocale_success ("en_US.UTF-8");
+  setlocale_success ("/en_US.UTF-8");
+  setlocale_success ("//en_US.UTF-8");
+  setlocale_ignore ("");
+
+  setlocale_fail ("does-not-exist");
+  setlocale_fail ("/");
+  setlocale_fail ("/../localedata/en_US.UTF-8");
+  setlocale_fail ("en_US.UTF-8/");
+  setlocale_fail ("en_US.UTF-8/..");
+  setlocale_fail ("en_US.UTF-8/../en_US.UTF-8");
+  setlocale_fail ("../localedata/en_US.UTF-8");
+  {
+    size_t large_length = 1024;
+    char *large_name = malloc (large_length + 1);
+    if (large_name == NULL)
+      {
+	puts ("malloc failure");
+	return 1;
+      }
+    memset (large_name, '/', large_length);
+    const char *suffix = "en_US.UTF-8";
+    strcpy (large_name + large_length - strlen (suffix), suffix);
+    setlocale_fail (large_name);
+    free (large_name);
+  }
+  {
+    size_t huge_length = 64 * 1024 * 1024;
+    char *huge_name = malloc (huge_length + 1);
+    if (huge_name == NULL)
+      {
+	puts ("malloc failure");
+	return 1;
+      }
+    memset (huge_name, 'X', huge_length);
+    huge_name[huge_length] = '\0';
+    /* Construct a composite locale specification. */
+    const char *prefix = "LC_CTYPE=de_DE.UTF-8;LC_TIME=";
+    memcpy (huge_name, prefix, strlen (prefix));
+    setlocale_fail (huge_name);
+    free (huge_name);
+  }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a5da5d74ff2e0a6ee267f283be8dbccc92cec59a

commit a5da5d74ff2e0a6ee267f283be8dbccc92cec59a
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Aug 26 19:38:59 2014 +0200

    __gconv_translit_find: Disable function [BZ #17187]
    
    This functionality has never worked correctly, and the implementation
    contained a security vulnerability (CVE-2014-5119).

diff --git a/ChangeLog b/ChangeLog
index 120cae5..555d724 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-08-26  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17187]
+	* iconv/gconv_trans.c (struct known_trans, search_tree, lock,
+	trans_compare, open_translit, __gconv_translit_find):
+	Remove module loading code.
+
 2014-09-03  Florian Weimer  <fweimer@redhat.com>
 
 	[BZ #17325]
diff --git a/NEWS b/NEWS
index a6ca053..7a64a0b 100644
--- a/NEWS
+++ b/NEWS
@@ -10,12 +10,19 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17153, 17213, 17325.
+  17031, 17153, 17187, 17213, 17325.
 
 * Decoding a crafted input sequence in the character sets IBM933, IBM935,
   IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
   resulting a denial-of-service security vulnerability in applications which
   use functions related to iconv. (CVE-2014-6040)
+
+* Support for loadable gconv transliteration modules has been removed.
+  The support for transliteration modules has been non-functional for
+  over a decade, and the removal is prompted by security defects.  The
+  normal gconv conversion modules are still supported.  Transliteration
+  with //TRANSLIT is still possible, and the //IGNORE specifier
+  continues to be  supported. (CVE-2014-5519)
 
 Version 2.19
 
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c
index 1e25854..e0835fc 100644
--- a/iconv/gconv_trans.c
+++ b/iconv/gconv_trans.c
@@ -238,181 +238,12 @@ __gconv_transliterate (struct __gconv_step *step,
   return __GCONV_ILLEGAL_INPUT;
 }
 
-
-/* Structure to represent results of found (or not) transliteration
-   modules.  */
-struct known_trans
-{
-  /* This structure must remain the first member.  */
-  struct trans_struct info;
-
-  char *fname;
-  void *handle;
-  int open_count;
-};
-
-
-/* Tree with results of previous calls to __gconv_translit_find.  */
-static void *search_tree;
-
-/* We modify global data.   */
-__libc_lock_define_initialized (static, lock);
-
-
-/* Compare two transliteration entries.  */
-static int
-trans_compare (const void *p1, const void *p2)
-{
-  const struct known_trans *s1 = (const struct known_trans *) p1;
-  const struct known_trans *s2 = (const struct known_trans *) p2;
-
-  return strcmp (s1->info.name, s2->info.name);
-}
-
-
-/* Open (maybe reopen) the module named in the struct.  Get the function
-   and data structure pointers we need.  */
-static int
-open_translit (struct known_trans *trans)
-{
-  __gconv_trans_query_fct queryfct;
-
-  trans->handle = __libc_dlopen (trans->fname);
-  if (trans->handle == NULL)
-    /* Not available.  */
-    return 1;
-
-  /* Find the required symbol.  */
-  queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");
-  if (queryfct == NULL)
-    {
-      /* We cannot live with that.  */
-    close_and_out:
-      __libc_dlclose (trans->handle);
-      trans->handle = NULL;
-      return 1;
-    }
-
-  /* Get the context.  */
-  if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)
-      != 0)
-    goto close_and_out;
-
-  /* Of course we also have to have the actual function.  */
-  trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");
-  if (trans->info.trans_fct == NULL)
-    goto close_and_out;
-
-  /* Now the optional functions.  */
-  trans->info.trans_init_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_init");
-  trans->info.trans_context_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_context");
-  trans->info.trans_end_fct =
-    __libc_dlsym (trans->handle, "gconv_trans_end");
-
-  trans->open_count = 1;
-
-  return 0;
-}
-
-
 int
 internal_function
 __gconv_translit_find (struct trans_struct *trans)
 {
-  struct known_trans **found;
-  const struct path_elem *runp;
-  int res = 1;
-
-  /* We have to have a name.  */
-  assert (trans->name != NULL);
-
-  /* Acquire the lock.  */
-  __libc_lock_lock (lock);
-
-  /* See whether we know this module already.  */
-  found = __tfind (trans, &search_tree, trans_compare);
-  if (found != NULL)
-    {
-      /* Is this module available?  */
-      if ((*found)->handle != NULL)
-	{
-	  /* Maybe we have to reopen the file.  */
-	  if ((*found)->handle != (void *) -1)
-	    /* The object is not unloaded.  */
-	    res = 0;
-	  else if (open_translit (*found) == 0)
-	    {
-	      /* Copy the data.  */
-	      *trans = (*found)->info;
-	      (*found)->open_count++;
-	      res = 0;
-	    }
-	}
-    }
-  else
-    {
-      size_t name_len = strlen (trans->name) + 1;
-      int need_so = 0;
-      struct known_trans *newp;
-
-      /* We have to continue looking for the module.  */
-      if (__gconv_path_elem == NULL)
-	__gconv_get_path ();
-
-      /* See whether we have to append .so.  */
-      if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0)
-	need_so = 1;
-
-      /* Create a new entry.  */
-      newp = (struct known_trans *) malloc (sizeof (struct known_trans)
-					    + (__gconv_max_path_elem_len
-					       + name_len + 3)
-					    + name_len);
-      if (newp != NULL)
-	{
-	  char *cp;
-
-	  /* Clear the struct.  */
-	  memset (newp, '\0', sizeof (struct known_trans));
-
-	  /* Store a copy of the module name.  */
-	  newp->info.name = cp = (char *) (newp + 1);
-	  cp = __mempcpy (cp, trans->name, name_len);
-
-	  newp->fname = cp;
-
-	  /* Search in all the directories.  */
-	  for (runp = __gconv_path_elem; runp->name != NULL; ++runp)
-	    {
-	      cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name),
-			      trans->name, name_len);
-	      if (need_so)
-		memcpy (cp, ".so", sizeof (".so"));
-
-	      if (open_translit (newp) == 0)
-		{
-		  /* We found a module.  */
-		  res = 0;
-		  break;
-		}
-	    }
-
-	  if (res)
-	    newp->fname = NULL;
-
-	  /* In any case we'll add the entry to our search tree.  */
-	  if (__tsearch (newp, &search_tree, trans_compare) == NULL)
-	    {
-	      /* Yickes, this should not happen.  Unload the object.  */
-	      res = 1;
-	      /* XXX unload here.  */
-	    }
-	}
-    }
-
-  __libc_lock_unlock (lock);
-
-  return res;
+  /* Transliteration module loading has been removed because it never
+     worked as intended and suffered from a security vulnerability.
+     Consequently, this function always fails.  */
+  return 1;
 }

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e6cbfc1fa2c64cad3c599f419dd154cec5af23cc

commit e6cbfc1fa2c64cad3c599f419dd154cec5af23cc
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Sep 3 19:45:43 2014 +0200

    CVE-2014-6040: Crashes on invalid input in IBM gconv modules [BZ #17325]
    
    These changes are based on the fix for BZ #14134 in commit
    6e230d11837f3ae7b375ea69d7905f0d18eb79e5.

diff --git a/ChangeLog b/ChangeLog
index 914fca9..120cae5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-09-03  Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #17325]
+	* iconvdata/ibm1364.c (BODY): Fix check for sentinel.
+	* iconvdata/ibm932.c (BODY): Replace invalid sentinel check with
+	assert.
+	* iconvdata/ibm933.c (BODY): Fix check for sentinel.
+	* iconvdata/ibm935.c (BODY): Likewise.
+	* iconvdata/ibm937.c (BODY): Likewise.
+	* iconvdata/ibm939.c (BODY): Likewise.
+	* iconvdata/ibm943.c (BODY): Replace invalid sentinel check with
+	assert.
+	* iconvdata/Makefile (iconv-test.out): Pass module list to test
+	script.
+	* iconvdata/run-iconv-test.sh: New test loop for checking for
+	decoder crashers.
+
 2013-07-29  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #17213]
diff --git a/NEWS b/NEWS
index a007829..a6ca053 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,12 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17153, 17213.
+  17031, 17153, 17213, 17325.
+
+* Decoding a crafted input sequence in the character sets IBM933, IBM935,
+  IBM937, IBM939, IBM1364 could result in an out-of-bounds array read,
+  resulting a denial-of-service security vulnerability in applications which
+  use functions related to iconv. (CVE-2014-6040)
 
 Version 2.19
 
diff --git a/iconvdata/Makefile b/iconvdata/Makefile
index 5c2154e..7b9ee48 100644
--- a/iconvdata/Makefile
+++ b/iconvdata/Makefile
@@ -299,7 +299,10 @@ $(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
 			 $(addprefix $(objpfx),$(modules.so)) \
 			 $(common-objdir)/iconv/iconv_prog TESTS
-	$(SHELL) $< $(common-objdir) '$(test-wrapper)' > $@
+	iconv_modules="$(modules)" \
+	$(SHELL) $< $(common-objdir) '$(test-wrapper-env)' \
+		 '$(run-program-env)' > $@; \
+	$(evaluate-test)
 
 $(objpfx)tst-tables.out: tst-tables.sh $(objpfx)gconv-modules \
 			 $(addprefix $(objpfx),$(modules.so)) \
diff --git a/iconvdata/ibm1364.c b/iconvdata/ibm1364.c
index 373d49a..e9ea405 100644
--- a/iconvdata/ibm1364.c
+++ b/iconvdata/ibm1364.c
@@ -220,7 +220,8 @@ enum
 	  ++rp2;							      \
 									      \
 	uint32_t res;							      \
-	if (__builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
+	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = DB_TO_UCS4[ch + rp2->idx],			      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
 	  {								      \
diff --git a/iconvdata/ibm932.c b/iconvdata/ibm932.c
index 4ceeaae..a3f2583 100644
--- a/iconvdata/ibm932.c
+++ b/iconvdata/ibm932.c
@@ -73,11 +73,12 @@
 	  }								      \
 									      \
 	ch = (ch * 0x100) + inptr[1];					      \
+	/* ch was less than 0xfd.  */					      \
+	assert (ch < 0xfd00);						      \
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
-	    || __builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm932db_to_ucs4[ch + rp2->idx],		      \
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
 	  {								      \
diff --git a/iconvdata/ibm933.c b/iconvdata/ibm933.c
index 4723df4..7323df4 100644
--- a/iconvdata/ibm933.c
+++ b/iconvdata/ibm933.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm933db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm935.c b/iconvdata/ibm935.c
index 1ed311b..1af85df 100644
--- a/iconvdata/ibm935.c
+++ b/iconvdata/ibm935.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm935db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm937.c b/iconvdata/ibm937.c
index 1edaf62..a979bf4 100644
--- a/iconvdata/ibm937.c
+++ b/iconvdata/ibm937.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm937db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm939.c b/iconvdata/ibm939.c
index b40c486..93582bf 100644
--- a/iconvdata/ibm939.c
+++ b/iconvdata/ibm939.c
@@ -161,7 +161,7 @@ enum
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
+	if (__builtin_expect (rp2->start == 0xffff, 0)			      \
 	    || __builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm939db_to_ucs4[ch + rp2->idx],		      \
 		__builtin_expect (res, L'\1') == L'\0' && ch != '\0'))	      \
diff --git a/iconvdata/ibm943.c b/iconvdata/ibm943.c
index 495e379..815c3d4 100644
--- a/iconvdata/ibm943.c
+++ b/iconvdata/ibm943.c
@@ -74,11 +74,12 @@
 	  }								      \
 									      \
 	ch = (ch * 0x100) + inptr[1];					      \
+	/* ch was less than 0xfd.  */					      \
+	assert (ch < 0xfd00);						      \
 	while (ch > rp2->end)						      \
 	  ++rp2;							      \
 									      \
-	if (__builtin_expect (rp2 == NULL, 0)				      \
-	    || __builtin_expect (ch < rp2->start, 0)			      \
+	if (__builtin_expect (ch < rp2->start, 0)			      \
 	    || (res = __ibm943db_to_ucs4[ch + rp2->idx],		      \
 	    __builtin_expect (res, '\1') == 0 && ch !=0))		      \
 	  {								      \
diff --git a/iconvdata/run-iconv-test.sh b/iconvdata/run-iconv-test.sh
index e23f60d..565600a 100755
--- a/iconvdata/run-iconv-test.sh
+++ b/iconvdata/run-iconv-test.sh
@@ -188,6 +188,24 @@ while read utf8 from filename; do
 
 done < TESTS2
 
+# Check for crashes in decoders.
+printf '\016\377\377\377\377\377\377\377' > $temp1
+for from in $iconv_modules ; do
+    echo $ac_n "test decoder $from $ac_c"
+    PROG=`eval echo $ICONV`
+    if $PROG < $temp1 >/dev/null 2>&1 ; then
+	: # fall through
+    else
+	status=$?
+	if test $status -gt 1 ; then
+	    echo "/FAILED"
+	    failed=1
+	    continue
+	fi
+    fi
+    echo "OK"
+done
+
 exit $failed
 # Local Variables:
 #  mode:shell-script

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fa7cc069f4eb29c00ec3a833d73ec4a473b11c8a

commit fa7cc069f4eb29c00ec3a833d73ec4a473b11c8a
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jul 29 13:56:44 2014 -0500

    PowerPC: Fix gprof entry point for LE
    
    This patch fixes the ELFv2 gprof entry point since the ABI
    does not define function descriptors.  It fixes BZ#17213.
    
    This is a backport of a53fbd8e6cd2f69bdfa3431d616a5f332aea6664.

diff --git a/ChangeLog b/ChangeLog
index 63e2be7..914fca9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-07-29  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	[BZ #17213]
+	* sysdeps/powerpc/powerpc64/entry.h: Fix TEXT_START definition for
+	powerpc64le.
+
 2014-07-14  Alan Modra  <amodra@gmail.com>
 
 	[BZ #17153]
diff --git a/NEWS b/NEWS
index d830583..a007829 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031, 17153.
+  17031, 17153, 17213.
 
 Version 2.19
 
diff --git a/sysdeps/powerpc/powerpc64/entry.h b/sysdeps/powerpc/powerpc64/entry.h
index 76ead1d..30553c1 100644
--- a/sysdeps/powerpc/powerpc64/entry.h
+++ b/sysdeps/powerpc/powerpc64/entry.h
@@ -23,6 +23,7 @@ extern void _start (void);
 
 #define ENTRY_POINT _start
 
+#if _CALL_ELF != 2
 /* We have to provide a special declaration.  */
 #define ENTRY_POINT_DECL(class) class void _start (void);
 
@@ -33,3 +34,4 @@ extern void _start (void);
 #define TEXT_START \
   ({ extern unsigned long int _start_as_data[] asm ("_start");  \
      _start_as_data[0]; })
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=3c640c4acb9bc2c2cc7fa77d5ce1254953761dc1

commit 3c640c4acb9bc2c2cc7fa77d5ce1254953761dc1
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jul 14 21:14:50 2014 +0930

    Correct DT_PPC64_NUM
    
    	[BZ #17153]
    	* elf/elf.h (DT_PPC64_NUM): Correct value.
    	* NEWS: Add to fixed bug list.
    
    This is a backport of f6c44d475104e931bab2b4ffa499961088de673c.

diff --git a/ChangeLog b/ChangeLog
index b23aace..63e2be7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-14  Alan Modra  <amodra@gmail.com>
+
+	[BZ #17153]
+	* elf/elf.h (DT_PPC64_NUM): Correct value.
+	* NEWS: Add to fixed bug list.
+
 2014-07-08  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/memmove.c: Remove file.
diff --git a/NEWS b/NEWS
index 96b7621..d830583 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,7 @@ Version 2.19.1
 * The following bugs are resolved with this release:
 
   16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
-  17031.
+  17031, 17153.
 
 Version 2.19
 
diff --git a/elf/elf.h b/elf/elf.h
index 40e87b2..78815e8 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -2283,7 +2283,7 @@ typedef Elf32_Addr Elf32_Conflict;
 #define DT_PPC64_OPD	(DT_LOPROC + 1)
 #define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
 #define DT_PPC64_OPT	(DT_LOPROC + 3)
-#define DT_PPC64_NUM    3
+#define DT_PPC64_NUM    4
 
 /* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
 #define PPC64_OPT_TLS		1

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=957afa3407c426969eaaa348981b9648d5191ae2

commit 957afa3407c426969eaaa348981b9648d5191ae2
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jul 8 08:54:09 2014 -0500

    PowerPC: Cleanup powerpc memmove
    
    Now that MEMCPY_OK_FOR_FWD_MEMMOVE should be define on memcopy.h there
    is no need to specialized powerpc memmove implementation.  This patch
    moves the define set to powerpc memcopy and cleanup its definition on
    powerpc code.

diff --git a/ChangeLog b/ChangeLog
index 46028e5..b23aace 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2014-07-08  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/memmove.c: Remove file.
+	* sysdeps/powerpc/powerpc32/power4/memcopy.h
+	[MEMCPY_OK_FOR_FWD_MEMMOVE]: Define it to 1.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
+	[MEMCPY_OK_FOR_FWD_MEMMOVE]: Remove define.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c:
+	[MEMCPY_OK_FOR_FWD_MEMMOVE]: Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c: Include default
+	string memmove instead of removed powerpc one.
+
 	* sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S:
 	[weak_alias]: Fix compiler warning due trailing data.
 	* sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S:
diff --git a/sysdeps/powerpc/memmove.c b/sysdeps/powerpc/memmove.c
deleted file mode 100644
index 9c62ecb..0000000
--- a/sysdeps/powerpc/memmove.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copy memory to memory until the specified number of bytes
-   has been copied.  Overlap is handled correctly.
-   Copyright (C) 1991-2014 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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; see the file COPYING.LIB.  If
-   not, see <http://www.gnu.org/licenses/>.  */
-
-#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
-#include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/memcopy.h b/sysdeps/powerpc/powerpc32/power4/memcopy.h
index d3752dc..3431084 100644
--- a/sysdeps/powerpc/powerpc32/power4/memcopy.h
+++ b/sysdeps/powerpc/powerpc32/power4/memcopy.h
@@ -110,3 +110,7 @@
 	  ((byte *) dst_ep)[0] = __x;					      \
 	}								      \
     } while (0)
+
+/* The powerpc memcpy implementation is safe to use for memmove.  */
+#undef MEMCPY_OK_FOR_FWD_MEMMOVE
+#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
index 2861071..b14c3b1 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
@@ -27,5 +27,4 @@ extern __typeof (memmove) __memmove_power7;
 #undef libc_hidden_builtin_def
 #define libc_hidden_builtin_def(name)
 
-#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
 #include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c
index e323a4d..d56b77a 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c
@@ -30,5 +30,4 @@ extern __typeof (memmove) __memmove_ppc;
   __hidden_ver1 (__memmove_ppc, __GI_memmove, __memmove_ppc);
 #endif
 
-#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
 #include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
index b39348f..ff78fe6 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
@@ -25,4 +25,4 @@
 
 extern __typeof (memmove) __memmove_ppc attribute_hidden;
 
-#include <sysdeps/powerpc/memmove.c>
+#include <string/memmove.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=8d9513a103bdd202ffa4884bdedc2c3c0dbab210

commit 8d9513a103bdd202ffa4884bdedc2c3c0dbab210
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jul 8 08:49:54 2014 -0500

    PowerPC: Fix compiler warnings
    
    This patch fixes some compiler due trailing data in #undef directives
    and due missing prototypes.

diff --git a/ChangeLog b/ChangeLog
index 547dd56..46028e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2014-07-08  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S:
+	[weak_alias]: Fix compiler warning due trailing data.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S:
+	[weak_alias]: Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c: Fix compile
+	warnigs due missing definition of __strcpy_power7 and __strlen_power7.
+
 	* sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
 	(__libc_ifunc_impl_list): Add memmove functions.
 
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S b/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S
index 930564c..0b00011 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp-power7.S
@@ -30,7 +30,7 @@
  cfi_endproc;							\
  ASM_SIZE_DIRECTIVE(__strcasecmp_power7)
 
-#undef weak_alias(name, alias)
+#undef weak_alias
 #define weak_alias(name, alias)
 
 #undef libc_hidden_builtin_def
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S b/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S
index 46733f5..4b3ce51 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strcasecmp_l-power7.S
@@ -30,7 +30,7 @@
  cfi_endproc;							\
  ASM_SIZE_DIRECTIVE(__strcasecmp_l_power7)
 
-#undef weak_alias(name, alias)
+#undef weak_alias
 #define weak_alias(name, alias)
 
 #undef libc_hidden_builtin_def
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
index ba9a460..628f8bd 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
@@ -22,7 +22,9 @@
 #undef libc_hidden_def
 #define libc_hidden_def(name)
 
+extern typeof (strcpy) __strcpy_power7;
+extern typeof (strlen) __strlen_power7;
+
 #define strcpy __strcpy_power7
 #define strlen __strlen_power7
-
 #include <sysdeps/powerpc/strcat.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b00ec143897f076ecbcedc7369b4b74e0c7f6d14

commit b00ec143897f076ecbcedc7369b4b74e0c7f6d14
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jul 8 08:35:44 2014 -0500

    PowerPC: Add ifunc tests for memmove
    
    This patch add the missing ifunc tests definition for memmove ppc32
    optimization patch (commit 07aedd7).
    
    This is a backport of 91f4b564bd7bedcd93e7047cad570ce292d6330b.

diff --git a/ChangeLog b/ChangeLog
index 3c12f8d..547dd56 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-08  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
+	(__libc_ifunc_impl_list): Add memmove functions.
+
 2014-07-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/memcpy.S: Align VSX copies to 16B
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
index 8ba6a80..38bf28e 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/ifunc-impl-list.c
@@ -59,6 +59,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memcpy_cell)
 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc))
 
+  /* Support sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c.  */
+  IFUNC_IMPL (i, name, memmove,
+	      IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_HAS_VSX,
+			      __memmove_power7)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ppc))
+
   /* Support sysdeps/powerpc/powerpc32/power4/multiarch/memset.c.  */
   IFUNC_IMPL (i, name, memset,
 	      IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX,

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=565e3d6c8230affd7089bf5ebfcebbf72f32a27c

commit 565e3d6c8230affd7089bf5ebfcebbf72f32a27c
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Wed Jun 25 11:54:31 2014 -0500

    PowerPC: Align power7 memcpy using VSX to quadword
    
    This patch changes power7 memcpy to use VSX instructions only when
    memory is aligned to quardword.  It is to avoid unaligned kernel traps
    on non-cacheable memory (for instance, memory-mapped I/O).

diff --git a/ChangeLog b/ChangeLog
index c3ee635..3c12f8d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2014-07-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/power7/memcpy.S: Align VSX copies to 16B
+	to avoid alignment traps in non-cacheable memory.
+	* sysdeps/powerpc/powerpc32/power7/memcpy.S: Likewise.
+
 	* sysdeps/powerpc/powerpc32/power4/multiarch/Makefile: Add memmove
 	multiarch objects.
 	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c: New
diff --git a/sysdeps/powerpc/powerpc32/power7/memcpy.S b/sysdeps/powerpc/powerpc32/power7/memcpy.S
index 52c2a6b..e540fea 100644
--- a/sysdeps/powerpc/powerpc32/power7/memcpy.S
+++ b/sysdeps/powerpc/powerpc32/power7/memcpy.S
@@ -38,8 +38,8 @@ EALIGN (memcpy, 5, 0)
 	ble	cr1, L(copy_LT_32)  /* If move < 32 bytes use short move
 				    code.  */
 
-	andi.   11,3,7	      /* Check alignment of DST.  */
-	clrlwi  10,4,29	      /* Check alignment of SRC.  */
+	andi.   11,3,15	      /* Check alignment of DST.  */
+	clrlwi  10,4,28	      /* Check alignment of SRC.  */
 	cmplw   cr6,10,11     /* SRC and DST alignments match?  */
 	mr	12,4
 	mr	31,5
diff --git a/sysdeps/powerpc/powerpc64/power7/memcpy.S b/sysdeps/powerpc/powerpc64/power7/memcpy.S
index bbfd381..58d9b12 100644
--- a/sysdeps/powerpc/powerpc64/power7/memcpy.S
+++ b/sysdeps/powerpc/powerpc64/power7/memcpy.S
@@ -36,16 +36,11 @@ EALIGN (memcpy, 5, 0)
 	ble	cr1, L(copy_LT_32)  /* If move < 32 bytes use short move
 				    code.  */
 
-#ifdef __LITTLE_ENDIAN__
-/* In little-endian mode, power7 takes an alignment trap on any lxvd2x
-   or stxvd2x crossing a 32-byte boundary, so ensure the aligned_copy
-   loop is only used for quadword aligned copies.  */
+/* Align copies using VSX instructions to quadword. It is to avoid alignment
+   traps when memcpy is used on non-cacheable memory (for instance, memory
+   mapped I/O).  */
 	andi.	10,3,15
 	clrldi	11,4,60
-#else
-	andi.	10,3,7		/* Check alignment of DST.  */
-	clrldi	11,4,61		/* Check alignment of SRC.  */
-#endif
 	cmpld	cr6,10,11	/* SRC and DST alignments match?  */
 
 	mr	dst,3
@@ -53,13 +48,9 @@ EALIGN (memcpy, 5, 0)
 	beq	L(aligned_copy)
 
 	mtocrf	0x01,0
-#ifdef __LITTLE_ENDIAN__
 	clrldi	0,0,60
-#else
-	clrldi	0,0,61
-#endif
 
-/* Get the DST and SRC aligned to 8 bytes (16 for little-endian).  */
+/* Get the DST and SRC aligned to 16 bytes.  */
 1:
 	bf	31,2f
 	lbz	6,0(src)
@@ -79,14 +70,12 @@ EALIGN (memcpy, 5, 0)
 	stw	6,0(dst)
 	addi	dst,dst,4
 8:
-#ifdef __LITTLE_ENDIAN__
 	bf	28,16f
 	ld	6,0(src)
 	addi	src,src,8
 	std	6,0(dst)
 	addi	dst,dst,8
 16:
-#endif
 	subf	cnt,0,cnt
 
 /* Main aligned copy loop. Copies 128 bytes at a time. */
@@ -298,9 +287,6 @@ L(copy_LE_8):
 	.align	4
 L(copy_GE_32_unaligned):
 	clrldi	0,0,60	      /* Number of bytes until the 1st dst quadword.  */
-#ifndef __LITTLE_ENDIAN__
-	andi.	10,3,15	      /* Check alignment of DST (against quadwords).  */
-#endif
 	srdi	9,cnt,4	      /* Number of full quadwords remaining.  */
 
 	beq	L(copy_GE_32_unaligned_cont)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6fae3527af330c32399e3a4cdfac3958fc440eb8

commit 6fae3527af330c32399e3a4cdfac3958fc440eb8
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jun 24 08:47:52 2014 -0500

    PowerPC: optimized memmove for POWER7/PPC32
    
    This patch adds a optimized memmove for power7 by using the optimized
    power7 memcpy for forward copying.

diff --git a/ChangeLog b/ChangeLog
index 1cd2280..c3ee635 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2014-07-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc32/power4/multiarch/Makefile: Add memmove
+	multiarch objects.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c: New
+	file: multiarch power7 memmove.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c: New file:
+	multiarch default memmove.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c: New file:
+	multiarch memove for powerpc32/power4.
+
 	* string/bcopy.c: Use full path to include memmove.c.
 	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add memmove and bcopy
 	multiarch objects.
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile
index a465685..a7d33b9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/Makefile
@@ -11,7 +11,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strchr-power7 strchr-ppc32 wcschr-power7 wcschr-power6 \
 		   wcschr-ppc32 wcsrchr-power7 wcsrchr-power6 wcsrchr-ppc32 \
 		   wcscpy-power7 wcscpy-power6 wcscpy-ppc32 wordcopy-power7 \
-		   wordcopy-power6 wordcopy-ppc32
+		   wordcopy-power6 wordcopy-ppc32 memmove-power7 memmove-ppc
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
new file mode 100644
index 0000000..2861071
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-power7.c
@@ -0,0 +1,31 @@
+/* Power7 multiarch memmove.
+   Copyright (C) 2014 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+extern __typeof (memcpy) __memcpy_power7;
+#define memcpy __memcpy_power7
+
+extern __typeof (memmove) __memmove_power7;
+#define MEMMOVE __memmove_power7
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
+#include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c
new file mode 100644
index 0000000..e323a4d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove-ppc.c
@@ -0,0 +1,34 @@
+/* Power7 multiarch memmove.
+   Copyright (C) 2014 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; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+extern __typeof (memcpy) __memcpy_ppc;
+#define memcpy __memcpy_ppc
+
+extern __typeof (memmove) __memmove_ppc;
+#define MEMMOVE __memmove_ppc
+
+#if defined SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)  \
+  __hidden_ver1 (__memmove_ppc, __GI_memmove, __memmove_ppc);
+#endif
+
+#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
+#include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
new file mode 100644
index 0000000..1070148
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
@@ -0,0 +1,34 @@
+/* Multiple versions of memmove. PowerPC32 version.
+   Copyright (C) 2014 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/>.  */
+
+#if defined SHARED && !defined NOT_IN_libc
+/* Redefine memmove so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# include <string.h>
+# include "init-arch.h"
+
+extern __typeof (memmove) __memmove_ppc attribute_hidden;
+extern __typeof (memmove) __memmove_power7 attribute_hidden;
+
+libc_ifunc (memmove,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __memmove_power7
+            : __memmove_ppc);
+#else
+# include <string/memmove.c>
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5d55f9b05ecb85b7a543f641829479cfb081f380

commit 5d55f9b05ecb85b7a543f641829479cfb081f380
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Jun 20 12:55:16 2014 -0500

    PowerPC: optimized memmove for POWER7/PPC64
    
    This patch adds an optimized memmove optimization for POWER7/powerpc64.
    Basically the idea is to use the memcpy for POWER7 on non-overlapped
    memory regions and a optimized backward memcpy for memory regions
    that overlap (similar to the idea of string/memmove.c).
    
    The backward memcpy algorithm used is similar the one use for memcpy for
    POWER7, with adjustments done for alignment.  The difference is memory
    is always aligned to 16 bytes before using VSX/altivec instructions.

diff --git a/ChangeLog b/ChangeLog
index 3edba9f..1cd2280 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2014-07-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* string/bcopy.c: Use full path to include memmove.c.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add memmove and bcopy
+	multiarch objects.
+	* sysdeps/powerpc/powerpc64/multiarch/bcopy-ppc64.c: New file: default
+	bcopy for powerpc64.
+	* sysdeps/powerpc/powerpc64/multiarch/bcopy.c: New file: multiarch
+	bcopy for powerpc64.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: Add bcopy
+	and memmove implementations.
+	* sysdeps/powerpc/powerpc64/multiarch/memmove-power7.S: New file:
+	optimized multiarch memmove for POWER7/powerpc64.
+	* sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c: New file:
+	default multiarch memmove for powerpc64.
+	* sysdeps/powerpc/powerpc64/multiarch/memmove.c: New file: memmove
+	multiarch for powerpc64.
+	* sysdeps/powerpc/powerpc64/power7/bcopy.c: New file: optimized bcopy
+	for POWER7/powerpc64.
+	* sysdeps/powerpc/powerpc64/power7/memmove.S: New file: optimized
+	memmove for POWER7/powerpc64.
+
 	* sysdeps/powerpc/memmove.c (memmove): Cleanup impplementation to use
 	glibc default one.
 
diff --git a/string/bcopy.c b/string/bcopy.c
index 7c1225c..f497b5d 100644
--- a/string/bcopy.c
+++ b/string/bcopy.c
@@ -25,4 +25,4 @@
 #define	a2		dest
 #define	a2const
 
-#include <memmove.c>
+#include <string/memmove.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 524055f..82722fb 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -18,7 +18,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64 \
 		   strpbrk-power7 strpbrk-ppc64 strncpy-power7 strncpy-ppc64 \
 		   stpncpy-power7 stpncpy-ppc64 strcmp-power7 strcmp-ppc64 \
-		   strcat-power7 strcat-ppc64
+		   strcat-power7 strcat-ppc64 memmove-power7 memmove-ppc64 \
+		   bcopy-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/string/bcopy.c b/sysdeps/powerpc/powerpc64/multiarch/bcopy-ppc64.c
similarity index 77%
copy from string/bcopy.c
copy to sysdeps/powerpc/powerpc64/multiarch/bcopy-ppc64.c
index 7c1225c..f8d5aa5 100644
--- a/string/bcopy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/bcopy-ppc64.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* PowerPC64 default bcopy.
+   Copyright (C) 2014 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
@@ -17,12 +18,8 @@
 
 #include <string.h>
 
-#define	memmove		bcopy
-#define	rettype		void
-#define	RETURN(s)	return
-#define	a1		src
-#define	a1const		const
-#define	a2		dest
-#define	a2const
+extern __typeof (bcopy) __bcopy_ppc attribute_hidden;
 
-#include <memmove.c>
+#define bcopy __bcopy_ppc
+
+#include <string/bcopy.c>
diff --git a/string/bcopy.c b/sysdeps/powerpc/powerpc64/multiarch/bcopy.c
similarity index 65%
copy from string/bcopy.c
copy to sysdeps/powerpc/powerpc64/multiarch/bcopy.c
index 7c1225c..0688907 100644
--- a/string/bcopy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/bcopy.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* PowerPC64 multiarch bcopy.
+   Copyright (C) 2014 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
@@ -16,13 +17,13 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <string.h>
+#include "init-arch.h"
 
-#define	memmove		bcopy
-#define	rettype		void
-#define	RETURN(s)	return
-#define	a1		src
-#define	a1const		const
-#define	a2		dest
-#define	a2const
+extern __typeof (bcopy) __bcopy_ppc attribute_hidden;
+/* __bcopy_power7 symbol is implemented at memmove-power7.S  */
+extern __typeof (bcopy) __bcopy_power7 attribute_hidden;
 
-#include <memmove.c>
+libc_ifunc (bcopy,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __bcopy_power7
+            : __bcopy_ppc);
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index ec2e027..a574487 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -61,6 +61,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memcpy_power4)
 	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/memmove.c.  */
+  IFUNC_IMPL (i, name, memmove,
+	      IFUNC_IMPL_ADD (array, i, memmove, hwcap & PPC_FEATURE_HAS_VSX,
+			      __memmove_power7)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ppc))
+
   /* Support sysdeps/powerpc/powerpc64/multiarch/memset.c.  */
   IFUNC_IMPL (i, name, memset,
 	      IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX,
@@ -136,6 +142,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __bzero_power4)
 	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/bcopy.c.  */
+  IFUNC_IMPL (i, name, bcopy,
+	      IFUNC_IMPL_ADD (array, i, bcopy, hwcap & PPC_FEATURE_HAS_VSX,
+			      __bcopy_power7)
+	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ppc))
+
   /* Support sysdeps/powerpc/powerpc64/multiarch/mempcpy.c.  */
   IFUNC_IMPL (i, name, mempcpy,
 	      IFUNC_IMPL_ADD (array, i, mempcpy,
diff --git a/string/bcopy.c b/sysdeps/powerpc/powerpc64/multiarch/memmove-power7.S
similarity index 50%
copy from string/bcopy.c
copy to sysdeps/powerpc/powerpc64/multiarch/memmove-power7.S
index 7c1225c..667e7bc 100644
--- a/string/bcopy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memmove-power7.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Optimized memmove implementation for PowerPC64/POWER7.
+   Copyright (C) 2014 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
@@ -15,14 +16,28 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
+#include <sysdep.h>
 
-#define	memmove		bcopy
-#define	rettype		void
-#define	RETURN(s)	return
-#define	a1		src
-#define	a1const		const
-#define	a2		dest
-#define	a2const
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__memmove_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__memmove_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__memmove_power7)
 
-#include <memmove.c>
+#undef END_GEN_TB
+#define END_GEN_TB(name, mask)					\
+  cfi_endproc;							\
+  TRACEBACK_MASK(__memmove_power7,mask)				\
+  END_2(__memmove_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#undef bcopy
+#define bcopy __bcopy_power7
+
+#include <sysdeps/powerpc/powerpc64/power7/memmove.S>
diff --git a/string/bcopy.c b/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
similarity index 71%
copy from string/bcopy.c
copy to sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
index 7c1225c..b39348f 100644
--- a/string/bcopy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memmove-ppc64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -17,12 +17,12 @@
 
 #include <string.h>
 
-#define	memmove		bcopy
-#define	rettype		void
-#define	RETURN(s)	return
-#define	a1		src
-#define	a1const		const
-#define	a2		dest
-#define	a2const
+#define MEMMOVE __memmove_ppc
+#if !defined(NOT_IN_libc) && defined(SHARED)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
 
-#include <memmove.c>
+extern __typeof (memmove) __memmove_ppc attribute_hidden;
+
+#include <sysdeps/powerpc/memmove.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memmove.c b/sysdeps/powerpc/powerpc64/multiarch/memmove.c
new file mode 100644
index 0000000..9a1ce8f
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/memmove.c
@@ -0,0 +1,45 @@
+/* Multiple versions of memmove. PowerPC64 version.
+   Copyright (C) 2014 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/>.  */
+
+/* Define multiple versions only for the definition in lib and for
+   DSO.  In static binaries we need memmove before the initialization
+   happened.  */
+#if defined SHARED && !defined NOT_IN_libc
+/* Redefine memmove so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memmove
+# define memmove __redirect_memmove
+# include <string.h>
+# include "init-arch.h"
+
+extern __typeof (__redirect_memmove) __libc_memmove;
+
+extern __typeof (__redirect_memmove) __memmove_ppc attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_power7 attribute_hidden;
+
+libc_ifunc (__libc_memmove,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __memmove_power7
+            : __memmove_ppc);
+
+#undef memmove
+strong_alias (__libc_memmove, memmove);
+libc_hidden_ver (__libc_memmove, memmove);
+#else
+# include <string/memmove.c>
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/bcopy.c b/sysdeps/powerpc/powerpc64/power7/bcopy.c
new file mode 100644
index 0000000..4a6a400
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/bcopy.c
@@ -0,0 +1 @@
+/* Implemented at memmove.S  */
diff --git a/sysdeps/powerpc/powerpc64/power7/memmove.S b/sysdeps/powerpc/powerpc64/power7/memmove.S
new file mode 100644
index 0000000..8663dfb
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/memmove.S
@@ -0,0 +1,831 @@
+/* Optimized memmove implementation for PowerPC64/POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+
+/* void* [r3] memmove (void *dest [r3], const void *src [r4], size_t len [r5])
+
+   This optimization check if memory 'dest'  overlaps with 'src'. If it does
+   not then it calls an optimized memcpy call (similar to memcpy for POWER7,
+   embedded here to gain some cycles).
+   If source and destiny overlaps, a optimized backwards memcpy is used
+   instead.  */
+
+	.machine power7
+EALIGN (memmove, 5, 0)
+	CALL_MCOUNT 3
+
+L(_memmove):
+	subf    r9,r4,r3
+	cmpld   cr7,r9,r5
+	blt	cr7,L(memmove_bwd)
+
+	cmpldi	cr1,r5,31
+	neg	0,3
+	ble	cr1, L(copy_LT_32)  /* If move < 32 bytes use short move
+				       code.  */
+
+	andi.	10,3,15
+	clrldi	11,4,60
+	cmpld	cr6,10,11	/* SRC and DST alignments match?  */
+
+	mr	r11,3
+	bne	cr6,L(copy_GE_32_unaligned)
+	beq	L(aligned_copy)
+
+	mtocrf	0x01,0
+	clrldi	0,0,60
+
+/* Get the DST and SRC aligned to 8 bytes (16 for little-endian).  */
+1:
+	bf	31,2f
+	lbz	6,0(r4)
+	addi	r4,r4,1
+	stb	6,0(r11)
+	addi	r11,r11,1
+2:
+	bf	30,4f
+	lhz	6,0(r4)
+	addi	r4,r4,2
+	sth	6,0(r11)
+	addi	r11,r11,2
+4:
+	bf	29,8f
+	lwz	6,0(r4)
+	addi	r4,r4,4
+	stw	6,0(r11)
+	addi	r11,r11,4
+8:
+	bf	28,16f
+	ld	6,0(r4)
+	addi	r4,r4,8
+	std	6,0(r11)
+	addi	r11,r11,8
+16:
+	subf	r5,0,r5
+
+/* Main aligned copy loop. Copies 128 bytes at a time. */
+L(aligned_copy):
+	li	6,16
+	li	7,32
+	li	8,48
+	mtocrf	0x02,r5
+	srdi	12,r5,7
+	cmpdi	12,0
+	beq	L(aligned_tail)
+	lxvd2x	6,0,r4
+	lxvd2x	7,r4,6
+	mtctr	12
+	b	L(aligned_128loop)
+
+	.align  4
+L(aligned_128head):
+	/* for the 2nd + iteration of this loop. */
+	lxvd2x	6,0,r4
+	lxvd2x	7,r4,6
+L(aligned_128loop):
+	lxvd2x	8,r4,7
+	lxvd2x	9,r4,8
+	stxvd2x	6,0,r11
+	addi	r4,r4,64
+	stxvd2x	7,r11,6
+	stxvd2x	8,r11,7
+	stxvd2x	9,r11,8
+	lxvd2x	6,0,r4
+	lxvd2x	7,r4,6
+	addi	r11,r11,64
+	lxvd2x	8,r4,7
+	lxvd2x	9,r4,8
+	addi	r4,r4,64
+	stxvd2x	6,0,r11
+	stxvd2x	7,r11,6
+	stxvd2x	8,r11,7
+	stxvd2x	9,r11,8
+	addi	r11,r11,64
+	bdnz	L(aligned_128head)
+
+L(aligned_tail):
+	mtocrf	0x01,r5
+	bf	25,32f
+	lxvd2x	6,0,r4
+	lxvd2x	7,r4,6
+	lxvd2x	8,r4,7
+	lxvd2x	9,r4,8
+	addi	r4,r4,64
+	stxvd2x	6,0,r11
+	stxvd2x	7,r11,6
+	stxvd2x	8,r11,7
+	stxvd2x	9,r11,8
+	addi	r11,r11,64
+32:
+	bf	26,16f
+	lxvd2x	6,0,r4
+	lxvd2x	7,r4,6
+	addi	r4,r4,32
+	stxvd2x	6,0,r11
+	stxvd2x	7,r11,6
+	addi	r11,r11,32
+16:
+	bf	27,8f
+	lxvd2x	6,0,r4
+	addi	r4,r4,16
+	stxvd2x	6,0,r11
+	addi	r11,r11,16
+8:
+	bf	28,4f
+	ld	6,0(r4)
+	addi	r4,r4,8
+	std     6,0(r11)
+	addi	r11,r11,8
+4:	/* Copies 4~7 bytes.  */
+	bf	29,L(tail2)
+	lwz	6,0(r4)
+	stw     6,0(r11)
+	bf      30,L(tail5)
+	lhz     7,4(r4)
+	sth     7,4(r11)
+	bflr	31
+	lbz     8,6(r4)
+	stb     8,6(r11)
+	/* Return original DST pointer.  */
+	blr
+
+/* Handle copies of 0~31 bytes.  */
+	.align	4
+L(copy_LT_32):
+	mr	r11,3
+	cmpldi	cr6,r5,8
+	mtocrf	0x01,r5
+	ble	cr6,L(copy_LE_8)
+
+	/* At least 9 bytes to go.  */
+	neg	8,4
+	andi.	0,8,3
+	cmpldi	cr1,r5,16
+	beq	L(copy_LT_32_aligned)
+
+	/* Force 4-byte alignment for SRC.  */
+	mtocrf	0x01,0
+	subf	r5,0,r5
+2:
+	bf	30,1f
+	lhz	6,0(r4)
+	addi	r4,r4,2
+	sth	6,0(r11)
+	addi	r11,r11,2
+1:
+	bf	31,L(end_4bytes_alignment)
+	lbz	6,0(r4)
+	addi	r4,r4,1
+	stb	6,0(r11)
+	addi	r11,r11,1
+
+	.align	4
+L(end_4bytes_alignment):
+	cmpldi	cr1,r5,16
+	mtocrf	0x01,r5
+
+L(copy_LT_32_aligned):
+	/* At least 6 bytes to go, and SRC is word-aligned.  */
+	blt	cr1,8f
+
+	/* Copy 16 bytes.  */
+	lwz	6,0(r4)
+	lwz	7,4(r4)
+	stw	6,0(r11)
+	lwz	8,8(r4)
+	stw	7,4(r11)
+	lwz	6,12(r4)
+	addi	r4,r4,16
+	stw	8,8(r11)
+	stw	6,12(r11)
+	addi	r11,r11,16
+8:	/* Copy 8 bytes.  */
+	bf	28,L(tail4)
+	lwz	6,0(r4)
+	lwz	7,4(r4)
+	addi	r4,r4,8
+	stw	6,0(r11)
+	stw	7,4(r11)
+	addi	r11,r11,8
+
+	.align	4
+/* Copies 4~7 bytes.  */
+L(tail4):
+	bf	29,L(tail2)
+	lwz	6,0(r4)
+	stw	6,0(r11)
+	bf	30,L(tail5)
+	lhz	7,4(r4)
+	sth	7,4(r11)
+	bflr	31
+	lbz	8,6(r4)
+	stb	8,6(r11)
+	/* Return original DST pointer.  */
+	blr
+
+	.align	4
+/* Copies 2~3 bytes.  */
+L(tail2):
+	bf	30,1f
+	lhz	6,0(r4)
+	sth	6,0(r11)
+	bflr	31
+	lbz	7,2(r4)
+	stb	7,2(r11)
+	blr
+
+	.align	4
+L(tail5):
+	bflr	31
+	lbz	6,4(r4)
+	stb	6,4(r11)
+	blr
+
+	.align	4
+1:
+	bflr	31
+	lbz	6,0(r4)
+	stb	6,0(r11)
+	/* Return original DST pointer.  */
+	blr
+
+/* Handles copies of 0~8 bytes.  */
+	.align	4
+L(copy_LE_8):
+	bne	cr6,L(tail4)
+
+	/* Though we could've used ld/std here, they are still
+	slow for unaligned cases.  */
+
+	lwz	6,0(r4)
+	lwz	7,4(r4)
+	stw	6,0(r11)
+	stw	7,4(r11)
+	blr
+
+
+/* Handle copies of 32+ bytes where DST is aligned (to quadword) but
+   SRC is not.	Use aligned quadword loads from SRC, shifted to realign
+   the data, allowing for aligned DST stores.  */
+	.align	4
+L(copy_GE_32_unaligned):
+	clrldi	0,0,60	      /* Number of bytes until the 1st r11 quadword.  */
+	srdi	9,r5,4	      /* Number of full quadwords remaining.  */
+
+	beq	L(copy_GE_32_unaligned_cont)
+
+	/* DST is not quadword aligned, get it aligned.  */
+
+	mtocrf	0x01,0
+	subf	r5,0,r5
+
+	/* Vector instructions work best when proper alignment (16-bytes)
+	is present.  Move 0~15 bytes as needed to get DST quadword-aligned.  */
+1:
+	bf	31,2f
+	lbz	6,0(r4)
+	addi	r4,r4,1
+	stb	6,0(r11)
+	addi	r11,r11,1
+2:
+	bf	30,4f
+	lhz	6,0(r4)
+	addi	r4,r4,2
+	sth	6,0(r11)
+	addi	r11,r11,2
+4:
+	bf	29,8f
+	lwz	6,0(r4)
+	addi	r4,r4,4
+	stw	6,0(r11)
+	addi	r11,r11,4
+8:
+	bf	28,0f
+	ld	6,0(r4)
+	addi	r4,r4,8
+	std	6,0(r11)
+	addi	r11,r11,8
+0:
+	srdi	9,r5,4	      /* Number of full quadwords remaining.  */
+
+	/* The proper alignment is present, it is OK to copy the bytes now.  */
+L(copy_GE_32_unaligned_cont):
+
+	/* Setup two indexes to speed up the indexed vector operations.  */
+	clrldi	10,r5,60
+	li	6,16	      /* Index for 16-bytes offsets.  */
+	li	7,32	      /* Index for 32-bytes offsets.  */
+	cmpldi	cr1,10,0
+	srdi	8,r5,5	      /* Setup the loop counter.  */
+	mtocrf	0x01,9
+	cmpldi	cr6,9,1
+#ifdef __LITTLE_ENDIAN__
+	lvsr	5,0,r4
+#else
+	lvsl	5,0,r4
+#endif
+	lvx	3,0,r4
+	li	0,0
+	bf	31,L(setup_unaligned_loop)
+
+	/* Copy another 16 bytes to align to 32-bytes due to the loop.  */
+	lvx	4,r4,6
+#ifdef __LITTLE_ENDIAN__
+	vperm	6,4,3,5
+#else
+	vperm	6,3,4,5
+#endif
+	addi	r4,r4,16
+	stvx	6,0,r11
+	addi	r11,r11,16
+	vor	3,4,4
+	clrrdi	0,r4,60
+
+L(setup_unaligned_loop):
+	mtctr	8
+	ble	cr6,L(end_unaligned_loop)
+
+	/* Copy 32 bytes at a time using vector instructions.  */
+	.align	4
+L(unaligned_loop):
+
+	/* Note: vr6/vr10 may contain data that was already copied,
+	but in order to get proper alignment, we may have to copy
+	some portions again. This is faster than having unaligned
+	vector instructions though.  */
+
+	lvx	4,r4,6
+#ifdef __LITTLE_ENDIAN__
+	vperm	6,4,3,5
+#else
+	vperm	6,3,4,5
+#endif
+	lvx	3,r4,7
+#ifdef __LITTLE_ENDIAN__
+	vperm	10,3,4,5
+#else
+	vperm	10,4,3,5
+#endif
+	addi	r4,r4,32
+	stvx	6,0,r11
+	stvx	10,r11,6
+	addi	r11,r11,32
+	bdnz	L(unaligned_loop)
+
+	clrrdi	0,r4,60
+
+	.align	4
+L(end_unaligned_loop):
+
+	/* Check for tail bytes.  */
+	mtocrf	0x01,r5
+	beqlr	cr1
+
+	add	r4,r4,0
+
+	/*  We have 1~15 tail bytes to copy, and DST is quadword aligned.  */
+	/* Copy 8 bytes.  */
+	bf	28,4f
+	lwz	6,0(r4)
+	lwz	7,4(r4)
+	addi	r4,r4,8
+	stw	6,0(r11)
+	stw	7,4(r11)
+	addi	r11,r11,8
+4:	/* Copy 4~7 bytes.  */
+	bf	29,L(tail2)
+	lwz	6,0(r4)
+	stw	6,0(r11)
+	bf	30,L(tail5)
+	lhz	7,4(r4)
+	sth	7,4(r11)
+	bflr	31
+	lbz	8,6(r4)
+	stb	8,6(r11)
+	/* Return original DST pointer.  */
+	blr
+
+	/* Start to memcpy backward implementation: the algorith first check if
+	   src and dest have the same alignment and if it does align both to 16
+	   bytes and copy using VSX instructions.
+	   If does not, align dest to 16 bytes and use VMX (altivec) instruction
+	   to read two 16 bytes at time, shift/permute the bytes read and write
+	   aligned to dest.  */
+L(memmove_bwd):
+	cmpldi	cr1,r5,31
+	/* Copy is done backwards: update the pointers and check alignment.  */
+	add	r11,r3,r5
+	add	r4,r4,r5
+	mr	r0,r11
+	ble	cr1, L(copy_LT_32_bwd)  /* If move < 32 bytes use short move
+				           code.  */
+
+	andi.	r10,r11,15	    /* Check if r11 is aligned to 16 bytes  */
+	clrldi	r9,r4,60	    /* Check if r4 is aligned to 16 bytes  */
+	cmpld	cr6,r10,r9	    /* SRC and DST alignments match?  */
+
+	bne     cr6,L(copy_GE_32_unaligned_bwd)
+	beq     L(aligned_copy_bwd)
+
+	mtocrf	0x01,r0
+	clrldi	r0,r0,60
+
+/* Get the DST and SRC aligned to 16 bytes.  */
+1:
+	bf	31,2f
+	lbz	r6,-1(r4)
+	subi	r4,r4,1
+	stb	r6,-1(r11)
+	subi	r11,r11,1
+2:
+	bf	30,4f
+	lhz	r6,-2(r4)
+	subi	r4,r4,2
+	sth	r6,-2(r11)
+	subi	r11,r11,2
+4:
+	bf	29,8f
+	lwz	r6,-4(r4)
+	subi	r4,r4,4
+	stw	r6,-4(r11)
+	subi	r11,r11,4
+8:
+	bf	28,16f
+	ld	r6,-8(r4)
+	subi	r4,r4,8
+	std	r6,-8(r11)
+	subi	r11,r11,8
+16:
+	subf	r5,0,r5
+
+/* Main aligned copy loop. Copies 128 bytes at a time. */
+L(aligned_copy_bwd):
+	li	r6,-16
+	li	r7,-32
+	li	r8,-48
+	li	r9,-64
+	mtocrf	0x02,r5
+	srdi	r12,r5,7
+	cmpdi	r12,0
+	beq	L(aligned_tail_bwd)
+	lxvd2x	v6,r4,r6
+	lxvd2x	v7,r4,r7
+	mtctr	12
+	b	L(aligned_128loop_bwd)
+
+	.align  4
+L(aligned_128head_bwd):
+	/* for the 2nd + iteration of this loop. */
+	lxvd2x	v6,r4,r6
+	lxvd2x	v7,r4,r7
+L(aligned_128loop_bwd):
+	lxvd2x	v8,r4,r8
+	lxvd2x	v9,r4,r9
+	stxvd2x	v6,r11,r6
+	subi	r4,r4,64
+	stxvd2x	v7,r11,r7
+	stxvd2x	v8,r11,r8
+	stxvd2x	v9,r11,r9
+	lxvd2x	v6,r4,r6
+	lxvd2x	v7,r4,7
+	subi	r11,r11,64
+	lxvd2x	v8,r4,r8
+	lxvd2x	v9,r4,r9
+	subi	r4,r4,64
+	stxvd2x	v6,r11,r6
+	stxvd2x	v7,r11,r7
+	stxvd2x	v8,r11,r8
+	stxvd2x	v9,r11,r9
+	subi	r11,r11,64
+	bdnz	L(aligned_128head_bwd)
+
+L(aligned_tail_bwd):
+	mtocrf	0x01,r5
+	bf	25,32f
+	lxvd2x	v6,r4,r6
+	lxvd2x	v7,r4,r7
+	lxvd2x	v8,r4,r8
+	lxvd2x	v9,r4,r9
+	subi	r4,r4,64
+	stxvd2x	v6,r11,r6
+	stxvd2x	v7,r11,r7
+	stxvd2x	v8,r11,r8
+	stxvd2x	v9,r11,r9
+	subi	r11,r11,64
+32:
+	bf	26,16f
+	lxvd2x	v6,r4,r6
+	lxvd2x	v7,r4,r7
+	subi	r4,r4,32
+	stxvd2x	v6,r11,r6
+	stxvd2x	v7,r11,r7
+	subi	r11,r11,32
+16:
+	bf	27,8f
+	lxvd2x	v6,r4,r6
+	subi	r4,r4,16
+	stxvd2x	v6,r11,r6
+	subi	r11,r11,16
+8:
+	bf	28,4f
+	ld	r6,-8(r4)
+	subi	r4,r4,8
+	std     r6,-8(r11)
+	subi	r11,r11,8
+4:	/* Copies 4~7 bytes.  */
+	bf	29,L(tail2_bwd)
+	lwz	r6,-4(r4)
+	stw     r6,-4(r11)
+	bf      30,L(tail5_bwd)
+	lhz     r7,-6(r4)
+	sth     r7,-6(r11)
+	bflr	31
+	lbz     r8,-7(r4)
+	stb     r8,-7(r11)
+	/* Return original DST pointer.  */
+	blr
+
+/* Handle copies of 0~31 bytes.  */
+	.align	4
+L(copy_LT_32_bwd):
+	cmpldi	cr6,r5,8
+	mtocrf	0x01,r5
+	ble	cr6,L(copy_LE_8_bwd)
+
+	/* At least 9 bytes to go.  */
+	neg	r8,r4
+	andi.	r0,r8,3
+	cmpldi	cr1,r5,16
+	beq	L(copy_LT_32_aligned_bwd)
+
+	/* Force 4-byte alignment for SRC.  */
+	mtocrf	0x01,0
+	subf	r5,0,r5
+2:
+	bf	30,1f
+	lhz	r6,-2(r4)
+	subi	r4,r4,2
+	sth	r6,-2(r11)
+	subi	r11,r11,2
+1:
+	bf	31,L(end_4bytes_alignment_bwd)
+	lbz	6,-1(r4)
+	subi	r4,r4,1
+	stb	6,-1(r11)
+	subi	r11,r11,1
+
+	.align	4
+L(end_4bytes_alignment_bwd):
+	cmpldi	cr1,r5,16
+	mtocrf	0x01,r5
+
+L(copy_LT_32_aligned_bwd):
+	/* At least 6 bytes to go, and SRC is word-aligned.  */
+	blt	cr1,8f
+
+	/* Copy 16 bytes.  */
+	lwz	r6,-4(r4)
+	lwz	r7,-8(r4)
+	stw	r6,-4(r11)
+	lwz	r8,-12(r4)
+	stw	r7,-8(r11)
+	lwz	r6,-16(r4)
+	subi	r4,r4,16
+	stw	r8,-12(r11)
+	stw	r6,-16(r11)
+	subi	r11,r11,16
+8:	/* Copy 8 bytes.  */
+	bf	28,L(tail4_bwd)
+	lwz	r6,-4(r4)
+	lwz	r7,-8(r4)
+	subi	r4,r4,8
+	stw	r6,-4(r11)
+	stw	r7,-8(r11)
+	subi	r11,r11,8
+
+	.align	4
+/* Copies 4~7 bytes.  */
+L(tail4_bwd):
+	bf	29,L(tail2_bwd)
+	lwz	6,-4(r4)
+	stw	6,-4(r11)
+	bf	30,L(tail5_bwd)
+	lhz	7,-6(r4)
+	sth	7,-6(r11)
+	bflr	31
+	lbz	8,-7(r4)
+	stb	8,-7(r11)
+	/* Return original DST pointer.  */
+	blr
+
+	.align	4
+/* Copies 2~3 bytes.  */
+L(tail2_bwd):
+	bf	30,1f
+	lhz	6,-2(r4)
+	sth	6,-2(r11)
+	bflr	31
+	lbz	7,-3(r4)
+	stb	7,-3(r11)
+	blr
+
+	.align	4
+L(tail5_bwd):
+	bflr	31
+	lbz	6,-5(r4)
+	stb	6,-5(r11)
+	blr
+
+	.align	4
+1:
+	bflr	31
+	lbz	6,-1(r4)
+	stb	6,-1(r11)
+	/* Return original DST pointer.  */
+	blr
+
+
+/* Handles copies of 0~8 bytes.  */
+	.align	4
+L(copy_LE_8_bwd):
+	bne	cr6,L(tail4_bwd)
+
+	/* Though we could've used ld/std here, they are still
+	   slow for unaligned cases.  */
+	lwz	6,-8(r4)
+	lwz	7,-4(r4)
+	stw	6,-8(r11)
+	stw	7,-4(r11)
+	blr
+
+
+/* Handle copies of 32+ bytes where DST is aligned (to quadword) but
+   SRC is not.	Use aligned quadword loads from SRC, shifted to realign
+   the data, allowing for aligned DST stores.  */
+	.align	4
+L(copy_GE_32_unaligned_bwd):
+	andi.	r10,r11,15      /* Check alignment of DST against 16 bytes..  */
+	srdi	r9,r5,4		/* Number of full quadwords remaining.  */
+
+	beq	L(copy_GE_32_unaligned_cont_bwd)
+
+	/* DST is not quadword aligned and r10 holds the address masked to
+           compare alignments.  */
+	mtocrf	0x01,r10
+	subf	r5,r10,r5
+
+	/* Vector instructions work best when proper alignment (16-bytes)
+	is present.  Move 0~15 bytes as needed to get DST quadword-aligned.  */
+1:
+	bf	31,2f
+	lbz	r6,-1(r4)
+	subi	r4,r4,1
+	stb	r6,-1(r11)
+	subi	r11,r11,1
+2:
+	bf	30,4f
+	lhz	r6,-2(r4)
+	subi	r4,r4,2
+	sth	r6,-2(r11)
+	subi	r11,r11,2
+4:
+	bf	29,8f
+	lwz	r6,-4(r4)
+	subi	r4,r4,4
+	stw	r6,-4(r11)
+	subi	r11,r11,4
+8:
+	bf	28,0f
+	ld	r6,-8(r4)
+	subi	r4,r4,8
+	std	r6,-8(r11)
+	subi	r11,r11,8
+0:
+	srdi	r9,r5,4	      /* Number of full quadwords remaining.  */
+
+	/* The proper alignment is present, it is OK to copy the bytes now.  */
+L(copy_GE_32_unaligned_cont_bwd):
+
+	/* Setup two indexes to speed up the indexed vector operations.  */
+	clrldi	r10,r5,60
+	li	r6,-16	      /* Index for 16-bytes offsets.  */
+	li	r7,-32	      /* Index for 32-bytes offsets.  */
+	cmpldi	cr1,10,0
+	srdi	r8,r5,5	      /* Setup the loop counter.  */
+	mtocrf	0x01,9
+	cmpldi	cr6,r9,1
+#ifdef __LITTLE_ENDIAN__
+	lvsr	v5,r0,r4
+#else
+	lvsl	v5,r0,r4
+#endif
+	lvx	v3,0,r4
+	li	r0,0
+	bf	31,L(setup_unaligned_loop_bwd)
+
+	/* Copy another 16 bytes to align to 32-bytes due to the loop.  */
+	lvx	v4,r4,r6
+#ifdef __LITTLE_ENDIAN__
+	vperm	v6,v3,v4,v5
+#else
+	vperm	v6,v4,v3,v5
+#endif
+	subi	r4,r4,16
+	stvx	v6,r11,r6
+	subi	r11,r11,16
+	vor	v3,v4,v4
+	clrrdi	r0,r4,60
+
+L(setup_unaligned_loop_bwd):
+	mtctr	r8
+	ble	cr6,L(end_unaligned_loop_bwd)
+
+	/* Copy 32 bytes at a time using vector instructions.  */
+	.align	4
+L(unaligned_loop_bwd):
+
+	/* Note: vr6/vr10 may contain data that was already copied,
+	but in order to get proper alignment, we may have to copy
+	some portions again. This is faster than having unaligned
+	vector instructions though.  */
+
+	lvx	v4,r4,r6
+#ifdef __LITTLE_ENDIAN__
+	vperm	v6,v3,v4,v5
+#else
+	vperm	v6,v4,v3,v5
+#endif
+	lvx	v3,r4,r7
+#ifdef __LITTLE_ENDIAN__
+	vperm	v10,v4,v3,v5
+#else
+	vperm	v10,v3,v4,v5
+#endif
+	subi	r4,r4,32
+	stvx	v6,r11,r6
+	stvx	v10,r11,r7
+	subi	r11,r11,32
+	bdnz	L(unaligned_loop_bwd)
+
+	clrrdi	r0,r4,60
+
+	.align	4
+L(end_unaligned_loop_bwd):
+
+	/* Check for tail bytes.  */
+	mtocrf	0x01,r5
+	beqlr	cr1
+
+	add	r4,r4,0
+
+	/*  We have 1~15 tail bytes to copy, and DST is quadword aligned.  */
+	/* Copy 8 bytes.  */
+	bf	28,4f
+	lwz	r6,-4(r4)
+	lwz	r7,-8(r4)
+	subi	r4,r4,8
+	stw	r6,-4(r11)
+	stw	r7,-8(r11)
+	subi	r11,r11,8
+4:	/* Copy 4~7 bytes.  */
+	bf	29,L(tail2_bwd)
+	lwz	r6,-4(r4)
+	stw	r6,-4(r11)
+	bf	30,L(tail5_bwd)
+	lhz	r7,-6(r4)
+	sth	r7,-6(r11)
+	bflr	31
+	lbz	r8,-7(r4)
+	stb	r8,-7(r11)
+	/* Return original DST pointer.  */
+	blr
+END_GEN_TB (memmove, TB_TOCLESS)
+libc_hidden_builtin_def (memmove)
+
+
+/* void bcopy(const void *src [r3], void *dest [r4], size_t n [r5])
+   Implemented in this file to avoid linker create a stub function call
+   in the branch to '_memmove'.  */
+ENTRY (bcopy)
+	mr	r6,r3
+	mr	r3,r4
+	mr	r4,r6
+	b	L(_memmove)
+END (bcopy)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=dde00e9914370ddd90c9bbc4f3f0e455efae4b47

commit dde00e9914370ddd90c9bbc4f3f0e455efae4b47
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Jun 24 06:42:31 2014 -0500

    PowerPC: memmove default implementation cleanup
    
    This patch removes the powerpc specific logic in memmove and instead
    include default implementation with MEMCPY_OK_FOR_FWD_MEMMOVE defined.
    This lead in a increase performance, since the constraints to use
    memcpy in powerpc code are too restrictive and memcpy can be used for
    any forward memmove.
    
    This is a backport of d6f68bbef4427850c2901728a1d13efc0e687297.

diff --git a/ChangeLog b/ChangeLog
index 54db831..3edba9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/memmove.c (memmove): Cleanup impplementation to use
+	glibc default one.
+
 2014-07-02  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 	    Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
diff --git a/sysdeps/powerpc/memmove.c b/sysdeps/powerpc/memmove.c
index 3859da8..9c62ecb 100644
--- a/sysdeps/powerpc/memmove.c
+++ b/sysdeps/powerpc/memmove.c
@@ -18,101 +18,5 @@
    License along with the GNU C Library; see the file COPYING.LIB.  If
    not, see <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
-#include <memcopy.h>
-#include <pagecopy.h>
-
-/* All this is so that bcopy.c can #include
-   this file after defining some things.  */
-#ifndef        a1
-#define        a1      dest    /* First arg is DEST.  */
-#define        a1const
-#define        a2      src     /* Second arg is SRC.  */
-#define        a2const const
-#undef memmove
-#endif
-#if    !defined(RETURN) || !defined(rettype)
-#define        RETURN(s)       return (s)      /* Return DEST.  */
-#define        rettype         void *
-#endif
-
-#ifndef MEMMOVE
-#define MEMMOVE memmove
-#endif
-
-rettype
-MEMMOVE (a1, a2, len)
-     a1const void *a1;
-     a2const void *a2;
-     size_t len;
-{
-  unsigned long int dstp = (long int) dest;
-  unsigned long int srcp = (long int) src;
-
-  /* If there is no overlap between ranges, call the builtin memcpy.  */
-  if (dstp >= srcp + len || srcp > dstp + len)
-    __builtin_memcpy (dest, src, len);
-
-  /* This test makes the forward copying code be used whenever possible.
-     Reduces the working set.  */
-  else if (dstp - srcp >= len)      /* *Unsigned* compare!  */
-    {
-      /* Copy from the beginning to the end.  */
-
-      /* If there not too few bytes to copy, use word copy.  */
-      if (len >= OP_T_THRES)
-       {
-         /* Copy just a few bytes to make DSTP aligned.  */
-         len -= (-dstp) % OPSIZ;
-         BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
-
-         /* Copy whole pages from SRCP to DSTP by virtual address
-            manipulation, as much as possible.  */
-
-         PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
-
-         /* Copy from SRCP to DSTP taking advantage of the known
-            alignment of DSTP.  Number of bytes remaining is put
-            in the third argument, i.e. in LEN.  This number may
-            vary from machine to machine.  */
-
-         WORD_COPY_FWD (dstp, srcp, len, len);
-
-         /* Fall out and copy the tail.  */
-       }
-
-      /* There are just a few bytes to copy.  Use byte memory operations.  */
-      BYTE_COPY_FWD (dstp, srcp, len);
-    }
-  else
-    {
-      /* Copy from the end to the beginning.  */
-      srcp += len;
-      dstp += len;
-
-      /* If there not too few bytes to copy, use word copy.  */
-      if (len >= OP_T_THRES)
-       {
-         /* Copy just a few bytes to make DSTP aligned.  */
-         len -= dstp % OPSIZ;
-         BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
-
-         /* Copy from SRCP to DSTP taking advantage of the known
-            alignment of DSTP.  Number of bytes remaining is put
-            in the third argument, i.e. in LEN.  This number may
-            vary from machine to machine.  */
-
-         WORD_COPY_BWD (dstp, srcp, len, len);
-
-         /* Fall out and copy the tail.  */
-       }
-
-      /* There are just a few bytes to copy.  Use byte memory operations.  */
-      BYTE_COPY_BWD (dstp, srcp, len);
-    }
-
-  RETURN (dest);
-}
-#ifndef memmove
-libc_hidden_builtin_def (memmove)
-#endif
+#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
+#include <string/memmove.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=9841a0850ed3be4310ec6b49c3349e39a6f0f481

commit 9841a0850ed3be4310ec6b49c3349e39a6f0f481
Author: Vidya Ranganathan <vidya@linux.vnet.ibm.com>
Date:   Wed Jun 11 22:21:20 2014 -0500

    PowerPC: strcat optimization for PPC64/POWER7
    
    This patch adds an ifunc power7 strcat symbol that uses the logic on
    sysdeps/powerpc/strcat.c but call power7 strlen/strcpy symbols instead
    of default ones.
    
    This is a backport of bc8ea38590070604006399e42469087e943fc8ec.

diff --git a/ChangeLog b/ChangeLog
index 39d09d7..54db831 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-07-02  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+	    Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/strcat.c: Using macro to redefine symbol name.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcat multiarch
+	optimizations.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/strcat.c: New file:
+	multiarch strcat for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c: New file/
+	* sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c: New file.
+
 2014-06-23  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/bits/hwcap.h [PPC_FEATURE2_HAS_VEC_CRYPTO]: New
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 05744e9..524055f 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -17,7 +17,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
 		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64 \
 		   strpbrk-power7 strpbrk-ppc64 strncpy-power7 strncpy-ppc64 \
-		   stpncpy-power7 stpncpy-ppc64 strcmp-power7 strcmp-ppc64
+		   stpncpy-power7 stpncpy-ppc64 strcmp-power7 strcmp-ppc64 \
+		   strcat-power7 strcat-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index b3933a5..ec2e027 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -301,5 +301,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcmp_power7)
 	      IFUNC_IMPL_ADD (array, i, strcmp, 1,
 			     __strcmp_ppc))
+
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strcat.c.  */
+  IFUNC_IMPL (i, name, strcat,
+	      IFUNC_IMPL_ADD (array, i, strcat,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strcat_power7)
+	      IFUNC_IMPL_ADD (array, i, strcat, 1,
+			     __strcat_ppc))
+
   return i;
 }
diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
similarity index 61%
copy from sysdeps/powerpc/strcat.c
copy to sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
index 06ceca7..ba9a460 100644
--- a/sysdeps/powerpc/strcat.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-power7.c
@@ -1,5 +1,4 @@
-/* strcat version that uses fast strcpy/strlen.
-   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -9,22 +8,21 @@
 
    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
+   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/>.  */
+   <http://www.gnu.org/licenses/ >.  */
 
 #include <string.h>
 
-#undef strcat
+#define STRCAT __strcat_power7
 
-/* Append SRC on the end of DEST.  */
-char *
-strcat (char *dest, const char *src)
-{
-  strcpy (dest + strlen (dest), src);
-  return dest;
-}
-libc_hidden_builtin_def (strcat)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+
+#define strcpy __strcpy_power7
+#define strlen __strlen_power7
+
+#include <sysdeps/powerpc/strcat.c>
diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c
similarity index 59%
copy from sysdeps/powerpc/strcat.c
copy to sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c
index 06ceca7..1245764 100644
--- a/sysdeps/powerpc/strcat.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat-ppc64.c
@@ -1,5 +1,4 @@
-/* strcat version that uses fast strcpy/strlen.
-   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -9,22 +8,22 @@
 
    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
+   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/>.  */
+   <http://www.gnu.org/licenses/ >.  */
 
 #include <string.h>
 
-#undef strcat
+#define STRCAT __strcat_ppc
+#ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1 (__strcat_ppc, __GI_strcat, __strcat_ppc);
+#endif
 
-/* Append SRC on the end of DEST.  */
-char *
-strcat (char *dest, const char *src)
-{
-  strcpy (dest + strlen (dest), src);
-  return dest;
-}
-libc_hidden_builtin_def (strcat)
+extern __typeof (strcat) __strcat_ppc attribute_hidden;
+
+#include <sysdeps/powerpc/strcat.c>
diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
similarity index 62%
copy from sysdeps/powerpc/strcat.c
copy to sysdeps/powerpc/powerpc64/multiarch/strcat.c
index 06ceca7..847a62d 100644
--- a/sysdeps/powerpc/strcat.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
@@ -1,5 +1,5 @@
-/* strcat version that uses fast strcpy/strlen.
-   Copyright (C) 1997-2014 Free Software Foundation, Inc.
+/* Multiple versions of strcat. PowerPC64 version.
+   Copyright (C) 2014 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
@@ -16,15 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
 
-#undef strcat
+extern __typeof (strcat) __strcat_ppc attribute_hidden;
+extern __typeof (strcat) __strcat_power7 attribute_hidden;
 
-/* Append SRC on the end of DEST.  */
-char *
-strcat (char *dest, const char *src)
-{
-  strcpy (dest + strlen (dest), src);
-  return dest;
-}
-libc_hidden_builtin_def (strcat)
+libc_ifunc (strcat,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strcat_power7
+            : __strcat_ppc);
+#endif
diff --git a/sysdeps/powerpc/strcat.c b/sysdeps/powerpc/strcat.c
index 06ceca7..4ff37ea 100644
--- a/sysdeps/powerpc/strcat.c
+++ b/sysdeps/powerpc/strcat.c
@@ -18,13 +18,16 @@
 
 #include <string.h>
 
-#undef strcat
+#ifndef STRCAT
+# undef strcat
+# define STRCAT  strcat
+#endif
 
 /* Append SRC on the end of DEST.  */
 char *
-strcat (char *dest, const char *src)
+STRCAT(char *dest, const char *src)
 {
   strcpy (dest + strlen (dest), src);
   return dest;
 }
-libc_hidden_builtin_def (strcat)
+libc_hidden_builtin_def (STRCAT)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ded8852b37f673b8e66163b44f70504dc5af0985

commit ded8852b37f673b8e66163b44f70504dc5af0985
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Mon Jun 23 09:38:47 2014 -0500

    PowerPC: sync hwcap.h capabilities
    
    Linux commit dd58a092c4202f2bd490adab7285b3ff77f8e467 added the
    PPC_FEATURE2_VEC_CRYPTO auvx capability to indicate whether to
    hardware supports vector crypto hardware instructions.  This patch
    adds its definition to powerpc hwcap bits.
    
    This is a backport of db22400947e1c82153e5270d23fed53fc1e3a659.

diff --git a/ChangeLog b/ChangeLog
index 95dcce8..39d09d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-06-23  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/bits/hwcap.h [PPC_FEATURE2_HAS_VEC_CRYPTO]: New
+	macro: hardware supports Vector Crypto instructions.
+
 2014-16-17  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
 
 	[BZ #17031]
diff --git a/sysdeps/powerpc/bits/hwcap.h b/sysdeps/powerpc/bits/hwcap.h
index 1af8c82..dab1a58 100644
--- a/sysdeps/powerpc/bits/hwcap.h
+++ b/sysdeps/powerpc/bits/hwcap.h
@@ -62,3 +62,5 @@
 #define PPC_FEATURE2_HAS_EBB       0x10000000 /* Event Base Branching */
 #define PPC_FEATURE2_HAS_ISEL      0x08000000 /* Integer Select */
 #define PPC_FEATURE2_HAS_TAR       0x04000000 /* Target Address Register */
+#define PPC_FEATURE2_HAS_VEC_CRYPTO  0x02000000  /* Target supports vector
+						    instruction.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7e986751f5c05f3363c01c717972f87a681da0d0

commit 7e986751f5c05f3363c01c717972f87a681da0d0
Author: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
Date:   Tue Jun 17 08:46:25 2014 -0500

    PowerPC: Fix nearbyintl failure for few inputs
    
    This patch fixes few failures in nearbyintl() where the fraction part is
    close to 0.5.i  The new tests added report few extra failures in
    nearbyint_downward and nearbyint_towardzero which is a known issue.
    
    Fixes #17031.
    
    This is a backport of 754c5a08aacb44895d1ab97c553ce424eb43f761.

diff --git a/ChangeLog b/ChangeLog
index a8a24b5..95dcce8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-16-17  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+
+	[BZ #17031]
+	* sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c: Consider the low
+	double, adjusted for any remainder from the high double.
+	* math/libm-test.inc (nearbyint): Add tests.
+	(rint): Likewise.
+
 2014-06-11  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strcmp.S: New file: Optimization.
diff --git a/NEWS b/NEWS
index 99bda3c..96b7621 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740.
+  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
+  17031.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 1c5c022..848b89e 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -10519,6 +10519,10 @@ static const struct test_f_f_data nearbyint_test_data[] =
     TEST_f_f (nearbyint,  34503599627370498.515625L, 34503599627370499.0L),
     TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L),
 # if LDBL_MANT_DIG >= 106
+    TEST_f_f (nearbyint, 1024.5000000000001L, 1025.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, 1025.5000000000001L, 1026.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1024.5000000000001L, -1025.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1025.5000000000001L, -1026.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
     TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
 # endif
@@ -11335,6 +11339,10 @@ static const struct test_f_f_data rint_test_data[] =
     TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L, INEXACT_EXCEPTION),
 
 # if LDBL_MANT_DIG > 100
+    TEST_f_f (rint, 1024.5000000000001L, 1025.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, 1025.5000000000001L, 1026.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1024.5000000000001L, -1025.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1025.5000000000001L, -1026.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L, INEXACT_EXCEPTION),
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
index 4e997a6..8f34604 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
@@ -38,6 +38,7 @@ __nearbyintl (long double x)
 
   if (fabs (u.d[0].d) < TWO52)
     {
+      double xh = u.d[0].d;
       double high = u.d[0].d;
       feholdexcept (&env);
       if (high > 0.0)
@@ -52,6 +53,10 @@ __nearbyintl (long double x)
 	  high += TWO52;
           if (high == 0.0) high = -0.0;
 	}
+      if (u.d[1].d > 0.0 && (xh - high == 0.5))
+        high += 1.0;
+      else if (u.d[1].d < 0.0 && (-(xh - high) == 0.5))
+        high -= 1.0;
       u.d[0].d = high;
       u.d[1].d = 0.0;
       math_force_eval (u.d[0]);

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2289a56644fc05786e2d5637c76d47afea7d38b9

commit 2289a56644fc05786e2d5637c76d47afea7d38b9
Author: Vidya Ranganathan <vidya@linux.vnet.ibm.com>
Date:   Fri Jun 6 07:56:07 2014 -0500

    PowerPC: Optimized strcmp for PPC64/POWER7
    
    Optimization is achieved on 8 byte aligned strings with double word
    comparison using cmpb instruction. On unaligned strings loop unrolling
    is applied for Power7 gain.
    
    It is a backport of e23d3d2690bf63207b1a47e83a94693daebbbfe5.

diff --git a/ChangeLog b/ChangeLog
index d7fd998..a8a24b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-06-11  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power7/strcmp.S: New file: Optimization.
+	* sysdeps/powerpc/powerpc64/multiarch/strcmp.c: New file:
+	multiarch strcmp for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcmp
+	multiarch optimizations.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+
 2014-06-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strncat.S [STRLEN]: Define it as
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 35020a7..05744e9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -17,7 +17,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
 		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64 \
 		   strpbrk-power7 strpbrk-ppc64 strncpy-power7 strncpy-ppc64 \
-		   stpncpy-power7 stpncpy-ppc64
+		   stpncpy-power7 stpncpy-ppc64 strcmp-power7 strcmp-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index d8578fb..b3933a5 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -294,5 +294,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, stpncpy, 1,
 			     __stpncpy_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strcmp.c.  */
+  IFUNC_IMPL (i, name, strcmp,
+	      IFUNC_IMPL_ADD (array, i, strcmp,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strcmp_power7)
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1,
+			     __strcmp_ppc))
   return i;
 }
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S
new file mode 100644
index 0000000..790ce8d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-power7.S
@@ -0,0 +1,40 @@
+/* Optimized strcmp implementation for POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strcmp_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strcmp_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strcmp_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strcmp_power7)					\
+  END_2(__strcmp_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#include <sysdeps/powerpc/powerpc64/power7/strcmp.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S
new file mode 100644
index 0000000..93d1277
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp-ppc64.S
@@ -0,0 +1,43 @@
+/* Default strcmp implementation for PowerPC64.
+   Copyright (C) 2014 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 <sysdep.h>
+
+#if defined SHARED && !defined NOT_IN_libc
+# undef EALIGN
+# define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strcmp_ppc)						\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strcmp_ppc):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strcmp_ppc)
+
+# undef END
+# define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strcmp_ppc)					\
+  END_2(__strcmp_ppc)
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)				\
+    .globl __GI_strcmp; __GI_strcmp = __strcmp_ppc
+#endif
+
+#include <sysdeps/powerpc/powerpc64/strcmp.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
new file mode 100644
index 0000000..2013301
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strcmp. PowerPC64 version.
+   Copyright (C) 2014 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/>.  */
+
+#if defined SHARED && !defined NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
+extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
+
+libc_ifunc (strcmp,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strcmp_power7
+            : __strcmp_ppc);
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strcmp.S b/sysdeps/powerpc/powerpc64/power7/strcmp.S
new file mode 100644
index 0000000..f16a9d8
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strcmp.S
@@ -0,0 +1,195 @@
+/* Optimized strcmp implementation for Power7 using 'cmpb' instruction
+   Copyright (C) 2014 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/>.  */
+
+/* The optimization is achieved here through cmpb instruction.
+   8byte aligned strings are processed with double word comparision
+   and unaligned strings are handled effectively with loop unrolling
+   technique  */
+
+#include <sysdep.h>
+
+/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4])  */
+
+EALIGN (strcmp, 4, 0)
+	CALL_MCOUNT 2
+
+	or r9, r3, r4
+	rldicl. r10, r9, 0, 61	/* are s1 and s2 8 byte aligned..?  */
+	bne cr0, L(process_unaligned_bytes)
+
+/* process input parameters on double word aligned boundary  */
+	ld r9, 0(r4)		/* load s2 at offset=0  */
+	li r10, 0		/* load mask=0  */
+	cmpb r10, r9, r10	/* compare bytes at s2 with mask  */
+	cmpdi cr7, r10, 0	/* is NULL found ..? is end of string HIT  */
+	bne cr7, L(process_unaligned_bytes)	/* process byte by byte  */
+
+	ld r10, 0(r3)		/* load s1 at offset=0  */
+	li r8, 0		/* load mask=0  */
+	cmpb r8, r10, r8	/* compare bytes at s1 with mask  */
+	cmpdi cr7, r8, 0	/* is NULL found ..? is end of string HIT  */
+	bne cr7, L(process_unaligned_bytes)	/* process byte by byte  */
+
+/*s1 and s2 does not contain NULL now , so compare all 8 bytes in a GO  */
+	cmpb r9, r10, r9	/* compare s1 and s2  */
+	cmpdi cr7, r9, -1	/* compare result with 0xFFFFFFFFFFFFFFFF  */
+	bne cr7, L(process_unaligned_bytes)	/* s1,s2 mismatch found  */
+
+	addi r5, r3, 8		/* save next offset of s2  */
+	addi r11, r4, 8		/* save next offset of s1  */
+	ld r8, 8(r4)		/* load s2 at offset=8  */
+	li r9, 0		/* load mask=0  */
+	cmpb r9, r8, r9		/* compare bytes at s2 with mask  */
+	cmpdi cr7, r9, 0	/* NULL found ..?  */
+	bne cr7, L(processBytes)/* update input and process bytes one by one  */
+
+	mr r9, r4		/* save s2  */
+	li r10, 0		/* load mask=0  */
+
+	ld r7, 8(r3)		/* load s1 at offset=8  */
+	cmpb r6, r7, r10	/* compare bytes at s1 with mask  */
+	cmpdi cr7, r6, 0	/* is NULL found  */
+	bne cr7, L(processBytes)/* mismatch, so process one by one  */
+
+L(unrollDword):
+	cmpb r8, r7, r8		/* compare s1 and s2  */
+	cmpdi cr7, r8, -1	/* compare result with 0xFFFFFFFFFFFFFFFF  */
+	bne cr7, L(processBytes)/* mismatch with s1 and s2  */
+
+	addi r5, r3, 16		/* save offset=16 of s1  */
+	addi r4, r9, 16		/* save offset=16 of s2  */
+	ld r8, 16(r9)		/* load s2 at offset=16  */
+	cmpb r7, r8, r10	/* compare bytes at s2 with mask  */
+	cmpdi cr7, r7, 0	/* NULL found  ..?  */
+	bne cr7, L(update2processBytes)
+
+	ld r7, 16(r3)		/* load s1 at offset=16  */
+	cmpb r6, r7, r10	/* check s1 for end of string  */
+	cmpdi cr7, r6, 0	/* end of s1 ?,then handle byte by byte  */
+	bne 7,L(update2processBytes)
+
+	cmpb r8, r7, r8		/* compare s1 and s2 double words  */
+	cmpdi cr7, r8, -1	/* compare results with 0xFFFFFFFFFFFFFFFF  */
+	bne cr7,L(update2processBytes)
+
+	addi r5, r3, 24		/* update s1 to offset=24  */
+	addi r4, r9, 24		/* update s2 to offset=24  */
+
+	ld r8, 24(r9)		/* load s2  */
+	cmpb r7, r8, r10	/* compare s2 for NULL  */
+	cmpdi cr7, r7, 0	/* verify if s2 is ending now  */
+	bne cr7,L(update2processBytes)
+
+	ld r7, 24(r3)		/* load s1 at offset=24  */
+	cmpb r6, r7, r10	/* verify for NULL  */
+	cmpdi cr7, r6, 0	/* is NULL found  */
+	bne cr7, L(update2processBytes)
+
+	cmpb r8, r7, r8		/* compare s1 and s2  */
+	cmpdi cr7, r8, -1	/* are s1 and s2 same ..?  */
+	bne cr7, L(update2processBytes)
+
+	addi r7, r9, 32		/* update s2 to next double word  */
+	addi r3, r3, 32		/* update s1 to next double word  */
+
+	ld r8, 32(r9)		/* load s2  */
+	mr r4, r7		/* save s2  */
+	cmpb r6, r8, r10	/* compare s2 with NULL  */
+	cmpdi cr7, r6, 0	/* end of s2 ..? */
+	bne cr7, L(process_unaligned_bytes)
+
+	ld r6, 0(r3)		/* load and compare s1 for NULL  */
+	cmpb r5, r6, r10
+	cmpdi cr7, r5, 0
+	bne cr7, L(process_unaligned_bytes)
+
+	cmpb r8, r6, r8		/* compare s1 and s2  */
+	cmpdi cr7, r8, -1
+	bne cr7, L(process_unaligned_bytes)
+
+	addi r5, r3, 8		/* increment s1 and d2 here  */
+	addi r11, r9, 40
+
+	ld r8, 40(r9)		/* process s2 now  */
+	cmpb r9, r8, r10
+	cmpdi cr7, r9, 0
+	bne cr7, L(processBytes)
+
+	mr r9, r7
+	ld r7, 8(r3)		/* process s1 now  */
+	cmpb r6, r7, r10
+	cmpdi cr7, r6, 0
+	beq cr7, L(unrollDword)	/* unroll to compare s1 and s2  */
+
+L(processBytes):
+	mr r4, r11		/* update input params  */
+	mr r3, r5
+
+	.p2align 4
+L(process_unaligned_bytes):
+	lbz r9, 0(r3)		/* load byte from s1  */
+	lbz r10, 0(r4)		/* load byte from s2  */
+	cmpdi cr7, r9, 0	/* compare *s1 with NULL  */
+	beq cr7, L(diffOfNULL)	/* if *s1 is NULL , return *s1 - *s2  */
+	cmplw cr7, r9, r10	/* compare *s1 and *s2  */
+	bne cr7, L(ComputeDiff)	/* branch to compute difference and return  */
+
+	lbz r9, 1(r3)		/* load next byte from s1  */
+	lbz r10, 1(r4)		/* load next byte from s2  */
+	cmpdi cr7, r9, 0	/* compare *s1 with NULL  */
+	beq cr7, L(diffOfNULL)	/* if *s1 is NULL , return *s1 - *s2  */
+	cmplw cr7, r9, r10	/* compare *s1 and *s2  */
+	bne cr7, L(ComputeDiff)	/* branch to compute difference and return  */
+
+	lbz r9, 2(r3)		/* unroll 3rd byte here  */
+	lbz r10, 2(r4)
+	cmpdi cr7, r9, 0
+	beq cr7, L(diffOfNULL)
+	cmplw cr7, r9, r10
+	bne 7, L(ComputeDiff)
+
+	lbz r9, 3(r3)		/* unroll 4th byte now  */
+	lbz r10, 3(r4)
+	addi r3, r3, 4		/* increment s1 by unroll factor  */
+	cmpdi cr7, r9, 0
+	cmplw cr6, 9, r10
+	beq cr7, L(diffOfNULL)
+	addi r4, r4, 4		/* increment s2 by unroll factor  */
+	beq cr6, L(process_unaligned_bytes)	/* unroll byte processing  */
+
+	.p2align 4
+L(ComputeDiff):
+	extsw r9, r9
+	subf r10, r10, r9	/* compute s1 - s2  */
+	extsw r3, r10
+	blr			/* return  */
+
+	.p2align 4
+L(diffOfNULL):
+	li r9, 0
+	subf r10, r10, r9	/* compute s1 - s2  */
+	extsw r3, r10		/* sign extend result  */
+	blr			/* return  */
+
+	.p2align 4
+L(update2processBytes):
+	mr r3, r5		/* update and proceed  */
+	b L(process_unaligned_bytes)
+
+END (strcmp)
+libc_hidden_builtin_def (strcmp)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=010c023685495f4cd907b7bf7d15375edcbe1ead

commit 010c023685495f4cd907b7bf7d15375edcbe1ead
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Jun 6 09:37:07 2014 -0500

    PowerPC: Fix optimized strncat strlen call
    
    This patch fixes the optimized ppc64/power7 strncat strlen call for
    static build without ifunc enabled.  The strlen symbol to call in such
    situation is just strlen, instead of __GI_strlen (since the __GI_
    alias is just created for shared objects).
    
    It is a backport of ed36bfa18faf9be457575568e64b8409e46caa22.

diff --git a/ChangeLog b/ChangeLog
index 2b48b1f..d7fd998 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2014-06-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/power7/strncat.S [STRLEN]: Define it as
+	strlen for non SHARED builds.
+
 	* sysdeps/powerpc/powerpc32/power6x/fpu/Implies: New file.
 	* sysdeps/powerpc/powerpc64/power6x/fpu/Implies: new file.
 	* sysdeps/powerpc/powerpc64/power6x/multiarch/Implies: New file.
diff --git a/sysdeps/powerpc/powerpc64/power7/strncat.S b/sysdeps/powerpc/powerpc64/power7/strncat.S
index e7e36a4..f5ea52d 100644
--- a/sysdeps/powerpc/powerpc64/power7/strncat.S
+++ b/sysdeps/powerpc/powerpc64/power7/strncat.S
@@ -40,7 +40,11 @@
 #ifndef STRLEN
 /* For builds with no IFUNC support, local calls should be made to internal
    GLIBC symbol (created by libc_hidden_builtin_def).  */
-# define STRLEN   __GI_strlen
+# ifdef SHARED
+#  define STRLEN   __GI_strlen
+# else
+#  define STRLEN   strlen
+# endif
 #endif
 
 #define	FRAMESIZE	(FRAME_MIN_SIZE+32)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=6f0aba1acab171bd853905b66c551336aa0adcf9

commit 6f0aba1acab171bd853905b66c551336aa0adcf9
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Apr 8 17:25:14 2014 -0500

    PowerPC: Fix --disable-multi-arch builds
    
    This patch fixes some powerpc32 and powerpc64 builds with
    --disable-multi-arch option along with different --with-cpu=powerN.
    It cleanups the Implies directories by removing the multiarch
    folder for non multiarch config and also fixing two assembly
    implementations: powerpc64/power7/strncat.S that is calling the
    wrong strlen; and power8/fpu/s_isnan.S that misses the hidden_def and
    weak_alias directives.
    
    It is a backport of de21c33c068c8e39afb5711613a7c083c11ce6a1.

diff --git a/ChangeLog b/ChangeLog
index 0013bcb..2b48b1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-06-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power6x/fpu/Implies: New file.
+	* sysdeps/powerpc/powerpc64/power6x/fpu/Implies: new file.
+	* sysdeps/powerpc/powerpc64/power6x/multiarch/Implies: New file.
+	* sysdeps/powerpc/powerpc64/power5+/fpu/Implies: Remove multiarch
+	imply folder.
+	* sysdeps/powerpc/powerpc64/power5/fpu/Implies: Likewise.
+	* sysdeps/powerpc/powerpc64/power7/fpu/Implies: Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/Implies: Likewise.
+	* sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies: Adjust
+	correct imply path.
+	* sysdeps/powerpc/powerpc64/power7/strncat.S (STRLEN): Define correct
+	strlen symbol for non multi-arch builds.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S (__isnan): Add
+	missing hidden_def and weak_alias.
+
 2014-05-26  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc32/power4/memset.S (memset): Replace insrdi
diff --git a/sysdeps/powerpc/powerpc32/power6x/fpu/Implies b/sysdeps/powerpc/powerpc32/power6x/fpu/Implies
new file mode 100644
index 0000000..d53ce25
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6x/fpu/Implies
@@ -0,0 +1 @@
+powerpc/powerpc32/power6/fpu
diff --git a/sysdeps/powerpc/powerpc64/power5+/fpu/Implies b/sysdeps/powerpc/powerpc64/power5+/fpu/Implies
index c0e6784..f00c50f 100644
--- a/sysdeps/powerpc/powerpc64/power5+/fpu/Implies
+++ b/sysdeps/powerpc/powerpc64/power5+/fpu/Implies
@@ -1 +1 @@
-powerpc/powerpc64/power5/fpu/multiarch
+powerpc/powerpc64/power5/fpu
diff --git a/sysdeps/powerpc/powerpc64/power5/fpu/Implies b/sysdeps/powerpc/powerpc64/power5/fpu/Implies
index 3740d05..6b8c23e 100644
--- a/sysdeps/powerpc/powerpc64/power5/fpu/Implies
+++ b/sysdeps/powerpc/powerpc64/power5/fpu/Implies
@@ -1 +1 @@
-powerpc/powerpc64/power4/fpu/multiarch
+powerpc/powerpc64/power4/fpu/
diff --git a/sysdeps/powerpc/powerpc64/power6x/fpu/Implies b/sysdeps/powerpc/powerpc64/power6x/fpu/Implies
new file mode 100644
index 0000000..30fa176
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6x/fpu/Implies
@@ -0,0 +1 @@
+powerpc/powerpc64/power6/fpu
diff --git a/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies b/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
index f54ff23..410d289 100644
--- a/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
+++ b/sysdeps/powerpc/powerpc64/power6x/fpu/multiarch/Implies
@@ -1 +1 @@
-sysdeps/powerpc/powerpc64/power6/fpu/multiarch
+powerpc/powerpc64/power6/fpu/multiarch
diff --git a/sysdeps/powerpc/powerpc64/power6x/multiarch/Implies b/sysdeps/powerpc/powerpc64/power6x/multiarch/Implies
new file mode 100644
index 0000000..bf5d617
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6x/multiarch/Implies
@@ -0,0 +1 @@
+powerpc/powerpc64/power6/multiarch
diff --git a/sysdeps/powerpc/powerpc64/power7/fpu/Implies b/sysdeps/powerpc/powerpc64/power7/fpu/Implies
index 410d289..30fa176 100644
--- a/sysdeps/powerpc/powerpc64/power7/fpu/Implies
+++ b/sysdeps/powerpc/powerpc64/power7/fpu/Implies
@@ -1 +1 @@
-powerpc/powerpc64/power6/fpu/multiarch
+powerpc/powerpc64/power6/fpu
diff --git a/sysdeps/powerpc/powerpc64/power7/strncat.S b/sysdeps/powerpc/powerpc64/power7/strncat.S
index 1a1a95e..e7e36a4 100644
--- a/sysdeps/powerpc/powerpc64/power7/strncat.S
+++ b/sysdeps/powerpc/powerpc64/power7/strncat.S
@@ -38,7 +38,9 @@
 #endif
 
 #ifndef STRLEN
-# define STRLEN   __strlen_ppc
+/* For builds with no IFUNC support, local calls should be made to internal
+   GLIBC symbol (created by libc_hidden_builtin_def).  */
+# define STRLEN   __GI_strlen
 #endif
 
 #define	FRAMESIZE	(FRAME_MIN_SIZE+32)
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/Implies b/sysdeps/powerpc/powerpc64/power8/fpu/Implies
index 7fd86fd..1187cdf 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/Implies
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/Implies
@@ -1 +1 @@
-powerpc/powerpc64/power7/fpu/multiarch
+powerpc/powerpc64/power7/fpu/
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
index b03c896..cf119e5 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
@@ -39,6 +39,9 @@ EALIGN (__isnan, 4, 0)
 	blr
 END (__isnan)
 
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
 /* It turns out that the 'double' version will also always work for
    single-precision.  */
 strong_alias (__isnan, __isnanf)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e40df8c4677611afc48601472675593dfd087e4b

commit e40df8c4677611afc48601472675593dfd087e4b
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu May 22 14:48:38 2014 -0500

    PowerPC: Remove 64 bits instructions in PPC32 code
    
    This patch replaces the insrdi by insrwi in powerpc32 assembly.
    
    It is a backport of d298c41635ce7f2dc7c3eccc842fe3aa754c0c8e.

diff --git a/ChangeLog b/ChangeLog
index 04228c1..0013bcb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-05-26  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power4/memset.S (memset): Replace insrdi
+	by insrwi.
+	* sysdeps/powerpc/powerpc32/power6/memset.S (memset): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/memset.S (memset): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/memchr.S (memchr): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/memrchr.S (memrchr): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/rawmemchr.S (rawmemchr): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/strchr.S (strchr): Likewise.
+	* sysdeps/powerpc/powerpc32/power7/strchrnul.S (strchrnul): Likewise.
+
 2014-05-22  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c (memchr): Remove
diff --git a/sysdeps/powerpc/powerpc32/power4/memset.S b/sysdeps/powerpc/powerpc32/power4/memset.S
index 88110e3..8b746a6 100644
--- a/sysdeps/powerpc/powerpc32/power4/memset.S
+++ b/sysdeps/powerpc/powerpc32/power4/memset.S
@@ -50,7 +50,7 @@ L(_memset):
 
 /* Align to word boundary.  */
 	cmplwi	cr5, rLEN, 31
-	insrdi	rCHR, rCHR, 8, 48     /* Replicate byte to halfword.  */
+	insrwi	rCHR, rCHR, 8, 16     /* Replicate byte to halfword.  */
 	beq+	L(aligned)
 	mtcrf	0x01, rMEMP0
 	subfic	rALIGN, rALIGN, 4
@@ -65,7 +65,7 @@ L(g0):
 /* Handle the case of size < 31.  */
 L(aligned):
 	mtcrf	0x01, rLEN
-	insrdi	rCHR, rCHR, 16, 32    /* Replicate halfword to word.  */
+	insrwi	rCHR, rCHR, 16, 0    /* Replicate halfword to word.  */
 	ble	cr5, L(medium)
 /* Align to 32-byte boundary.  */
 	andi.	rALIGN, rMEMP, 0x1C
diff --git a/sysdeps/powerpc/powerpc32/power6/memset.S b/sysdeps/powerpc/powerpc32/power6/memset.S
index 4b18fa7..445fa44 100644
--- a/sysdeps/powerpc/powerpc32/power6/memset.S
+++ b/sysdeps/powerpc/powerpc32/power6/memset.S
@@ -48,7 +48,7 @@ L(_memset):
 	ble-	cr1, L(small)
 /* Align to word boundary.  */
 	cmplwi	cr5, rLEN, 31
-	insrdi	rCHR, rCHR, 8, 48	/* Replicate byte to halfword.  */
+	insrwi	rCHR, rCHR, 8, 16	/* Replicate byte to halfword.  */
 	beq+	L(aligned)
 	mtcrf	0x01, rMEMP0
 	subfic	rALIGN, rALIGN, 4
@@ -64,7 +64,7 @@ L(g0):
 /* Handle the case of size < 31.  */
 L(aligned):
 	mtcrf	0x01, rLEN
-	insrdi	rCHR, rCHR, 16, 32	/* Replicate halfword to word.  */
+	insrwi	rCHR, rCHR, 16, 0	/* Replicate halfword to word.  */
 	ble	cr5, L(medium)
 /* Align to 32-byte boundary.  */
 	andi.	rALIGN, rMEMP, 0x1C
diff --git a/sysdeps/powerpc/powerpc32/power7/memchr.S b/sysdeps/powerpc/powerpc32/power7/memchr.S
index 1d6a0d6..ccdd7cf 100644
--- a/sysdeps/powerpc/powerpc32/power7/memchr.S
+++ b/sysdeps/powerpc/powerpc32/power7/memchr.S
@@ -25,9 +25,9 @@ ENTRY (__memchr)
 	CALL_MCOUNT
 	dcbt	0,r3
 	clrrwi  r8,r3,2
-	insrdi	r4,r4,8,48
+	insrwi	r4,r4,8,16    /* Replicate byte to word.  */
 	add	r7,r3,r5      /* Calculate the last acceptable address.  */
-	insrdi	r4,r4,16,32
+	insrwi	r4,r4,16,0
 	cmplwi	r5,16
 	li	r9, -1
 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
diff --git a/sysdeps/powerpc/powerpc32/power7/memrchr.S b/sysdeps/powerpc/powerpc32/power7/memrchr.S
index ebfd540..b05bf32 100644
--- a/sysdeps/powerpc/powerpc32/power7/memrchr.S
+++ b/sysdeps/powerpc/powerpc32/power7/memrchr.S
@@ -32,8 +32,8 @@ ENTRY (__memrchr)
 	dcbt	r9,r6,16      /* Stream hint, decreasing addresses.  */
 
 	/* Replicate BYTE to word.  */
-	rldimi	r4,r4,8,48
-	rldimi	r4,r4,16,32
+	insrwi	r4,r4,8,16
+	insrwi	r4,r4,16,0
 	li	r6,-4
 	li	r9,-1
 	rlwinm	r0,r0,3,27,28 /* Calculate padding.  */
diff --git a/sysdeps/powerpc/powerpc32/power7/memset.S b/sysdeps/powerpc/powerpc32/power7/memset.S
index ae18761..34fc1ad 100644
--- a/sysdeps/powerpc/powerpc32/power7/memset.S
+++ b/sysdeps/powerpc/powerpc32/power7/memset.S
@@ -35,8 +35,8 @@ L(_memset):
 	cfi_offset(31,-8)
 
 	/* Replicate byte to word.  */
-	insrdi	4,4,8,48
-	insrdi	4,4,16,32
+	insrwi	4,4,8,16
+	insrwi	4,4,16,0
 
 	ble	cr6,L(small)	/* If length <= 8, use short copy code.  */
 
diff --git a/sysdeps/powerpc/powerpc32/power7/rawmemchr.S b/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
index dec4db0..8ccf186 100644
--- a/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
+++ b/sysdeps/powerpc/powerpc32/power7/rawmemchr.S
@@ -27,8 +27,8 @@ ENTRY (__rawmemchr)
 	clrrwi	r8,r3,2	      /* Align the address to word boundary.  */
 
 	/* Replicate byte to word.  */
-	rldimi	r4,r4,8,48
-	rldimi	r4,r4,16,32
+	insrwi	r4,r4,8,16
+	insrwi	r4,r4,16,0
 
 	/* Now r4 has a word of c bytes.  */
 
diff --git a/sysdeps/powerpc/powerpc32/power7/strchr.S b/sysdeps/powerpc/powerpc32/power7/strchr.S
index f7ecb72..d795833 100644
--- a/sysdeps/powerpc/powerpc32/power7/strchr.S
+++ b/sysdeps/powerpc/powerpc32/power7/strchr.S
@@ -35,8 +35,8 @@ ENTRY (strchr)
 	beq	cr7,L(null_match)
 
 	/* Replicate byte to word.  */
-	insrdi	r4,r4,8,48
-	insrdi	r4,r4,16,32
+	insrwi	r4,r4,8,16
+	insrwi	r4,r4,16,0
 
 	/* Now r4 has a word of c bytes and r0 has
 	   a word of null bytes.  */
diff --git a/sysdeps/powerpc/powerpc32/power7/strchrnul.S b/sysdeps/powerpc/powerpc32/power7/strchrnul.S
index ece8237..dcc7620 100644
--- a/sysdeps/powerpc/powerpc32/power7/strchrnul.S
+++ b/sysdeps/powerpc/powerpc32/power7/strchrnul.S
@@ -27,8 +27,8 @@ ENTRY (__strchrnul)
 	clrrwi	r8,r3,2	      /* Align the address to word boundary.  */
 
 	/* Replicate byte to word.  */
-	insrdi	r4,r4,8,48
-	insrdi	r4,r4,16,32
+	insrwi  r4,r4,8,16
+	insrwi  r4,r4,16,0
 
 	rlwinm	r6,r3,3,27,28 /* Calculate padding.  */
 	lwz	r12,0(r8)     /* Load word from memory.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a448439dfffc0878121e0941be9717e05786b1fe

commit a448439dfffc0878121e0941be9717e05786b1fe
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu May 22 07:53:44 2014 -0500

    PowerPC: Fix memchr ifunc hidden symbol for PPC32
    
    This patch fixes a similar issue to
    736c304a1ab4cee36a2f3343f1698bc0abae4608, where for PPC32 if the symbol
    is defined as hidden (memchr) then compiler will create a local branc
    (symbol@local) and the linker will not create a required PLT call to
    make the ifunc work.  It changes the default hidden symbol (__GI_memchr)
    to default memchr symbol for powerpc32 (__memchr_ppc32).
    
    Backport of 3d2badacf185fac740a2992240a817fb2ca325af.

diff --git a/ChangeLog b/ChangeLog
index bed6c4c..04228c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-05-22  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c (memchr): Remove
+	libc_hidden_builtin_def to ifunc.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+	[libc_hidden_builtin_def]: Define hidden definition to __memchr_ppc32.
+
 2014-05-19  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypof.c: Moved ...
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
index 4bd6bb9..f5db4a8 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
@@ -25,7 +25,8 @@
 
 #ifdef SHARED
 # undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1(__memchr_ppc, __GI_memchr, __memchr_ppc);
 #endif
 
 extern __typeof (memchr) __memchr_ppc attribute_hidden;
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c
index ca0f714..94c22ef 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr.c
@@ -17,22 +17,25 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifndef NOT_IN_libc
+# undef memcpy
+/* Redefine memchr so that the compiler won't make the weak_alias point
+   to internal hidden definition (__GI_memchr), since PPC32 does not
+   support local IFUNC calls.  */
+# define memchr __redirect_memchr
 # include <string.h>
-# include <shlib-compat.h>
 # include "init-arch.h"
 
-extern __typeof (__memchr) __memchr_ppc attribute_hidden;
-extern __typeof (__memchr) __memchr_power7 attribute_hidden;
+extern __typeof (__redirect_memchr) __memchr_ppc attribute_hidden;
+extern __typeof (__redirect_memchr) __memchr_power7 attribute_hidden;
 
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
-   ifunc symbol properly.  */
-libc_ifunc (__memchr,
+extern __typeof (__redirect_memchr) __libc_memchr;
+
+libc_ifunc (__libc_memchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memchr_power7
             : __memchr_ppc);
-
-weak_alias (__memchr, memchr)
-libc_hidden_builtin_def (memchr)
+#undef memchr
+weak_alias (__libc_memchr, memchr)
 #else
 #include <string/memchr.c>
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c725f80591aa98c5c0270feb80e857c5943c861a

commit c725f80591aa98c5c0270feb80e857c5943c861a
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Mon May 19 17:56:55 2014 -0500

    PowerPC: Fix multiarch hypotf PPC64 path
    
    This patch moves the hypotf multiarch implementation to correct path.

diff --git a/ChangeLog b/ChangeLog
index 334d0f3..bed6c4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-05-19  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypof.c: Moved ...
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c: ... here.
+
 2014-05-06  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strncpy.S: New file: Optimization.
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypof.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c
similarity index 100%
rename from sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypof.c
rename to sysdeps/powerpc/powerpc64/fpu/multiarch/e_hypotf.c

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1db8c8c873e6112ee4ecddf1eff54f4abaab91a7

commit 1db8c8c873e6112ee4ecddf1eff54f4abaab91a7
Author: Vidya Ranganathan <vidya@linux.vnet.ibm.com>
Date:   Mon May 5 19:10:45 2014 -0500

    PowerPC: strncpy/stpncpy optimization for PPC64/POWER7
    
    The optimization is achieved by following techniques:
      > data alignment [gain from aligned memory access on read/write]
      > POWER7 gains performance with loop unrolling/unwinding
        [gain by reduction of branch penalty].
      > zero padding done by calling optimized memset

diff --git a/ChangeLog b/ChangeLog
index b728c33..334d0f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-05-06  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power7/strncpy.S: New file: Optimization.
+	* sysdeps/powerpc/powerpc64/multiarch/strncpy.c: New file:
+	multiarch strncpy for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c: New file
+	* sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S: New file
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strpcpy, stpncpy
+	multiarch optimizations.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+	* sysdeps/powerpc/powerpc64/power7/stpncpy.S: New file: Optimization.
+	* sysdeps/powerpc/powerpc64/multiarch/stpncpy.c: New file:
+	multiarch stpncpy for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c: New file
+	* sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S: New file
+
 2014-05-04  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 8d367aa..35020a7 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -16,7 +16,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
 		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
 		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64 \
-		   strpbrk-power7 strpbrk-ppc64
+		   strpbrk-power7 strpbrk-ppc64 strncpy-power7 strncpy-ppc64 \
+		   stpncpy-power7 stpncpy-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 91fabb0..d8578fb 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -278,5 +278,21 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strpbrk, 1,
 			     __strpbrk_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strncpy.c.  */
+  IFUNC_IMPL (i, name, strncpy,
+	      IFUNC_IMPL_ADD (array, i, strncpy,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strncpy_power7)
+	      IFUNC_IMPL_ADD (array, i, strncpy, 1,
+			     __strncpy_ppc))
+
+  /* Support sysdeps/powerpc/powerpc64/multiarch/stpncpy.c.  */
+  IFUNC_IMPL (i, name, stpncpy,
+	      IFUNC_IMPL_ADD (array, i, stpncpy,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __stpncpy_power7)
+	      IFUNC_IMPL_ADD (array, i, stpncpy, 1,
+			     __stpncpy_ppc))
+
   return i;
 }
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S
new file mode 100644
index 0000000..e29674f
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-power7.S
@@ -0,0 +1,44 @@
+/* Optimized stpncpy implementation for POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+#define USE_AS_STPNCPY
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__stpncpy_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__stpncpy_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__stpncpy_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__stpncpy_power7)					\
+  END_2(__stpncpy_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#define MEMSET __memset_power7
+
+#include <sysdeps/powerpc/powerpc64/power7/stpncpy.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c
new file mode 100644
index 0000000..74f47a7
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy-ppc64.c
@@ -0,0 +1,26 @@
+/* Default stpncpy implementation for PowerPC64.
+   Copyright (C) 2014 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/>.  */
+
+#define STPNCPY __stpncpy_ppc
+#ifdef SHARED
+#undef libc_hidden_def
+#define libc_hidden_def(name) \
+  __hidden_ver1 (__stpncpy_ppc, __GI___stpncpy, __stpncpy_ppc);
+#endif
+
+#include <string/stpncpy.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
new file mode 100644
index 0000000..dbf8521
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
@@ -0,0 +1,33 @@
+/* Multiple versions of stpncpy. PowerPC64 version.
+   Copyright (C) 2014 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/>.  */
+
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
+extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
+
+libc_ifunc (__stpncpy,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __stpncpy_power7
+            : __stpncpy_ppc);
+
+weak_alias (__stpncpy, stpncpy)
+#endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S
new file mode 100644
index 0000000..be349f9
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-power7.S
@@ -0,0 +1,42 @@
+/* Optimized strncpy implementation for POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strncpy_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strncpy_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strncpy_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strncpy_power7)					\
+  END_2(__strncpy_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#define MEMSET __memset_power7
+
+#include <sysdeps/powerpc/powerpc64/power7/strncpy.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c
new file mode 100644
index 0000000..e3111d2
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2014 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 <string.h>
+
+#define STRNCPY __strncpy_ppc
+#undef weak_alias
+#define weak_alias(name, aliasname) \
+  extern __typeof (__strncpy_ppc) aliasname \
+    __attribute__ ((weak, alias ("__strncpy_ppc")));
+#if !defined(NOT_IN_libc) && defined(SHARED)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1(__strncpy_ppc, __GI_strncpy, __strncpy_ppc);
+#endif
+
+extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
+
+#include <string/strncpy.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
new file mode 100644
index 0000000..8fd5e4b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
@@ -0,0 +1,35 @@
+/* Multiple versions of strncpy.
+   Copyright (C) 2014 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/ >.  */
+
+/* Define multiple versions only for definition in libc. */
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
+extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+libc_ifunc (strncpy,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strncpy_power7
+            : __strncpy_ppc);
+
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/stpncpy.S b/sysdeps/powerpc/powerpc64/power7/stpncpy.S
new file mode 100644
index 0000000..a539093
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/stpncpy.S
@@ -0,0 +1,24 @@
+/* Optimized stpncpy implementation for PowerPC64/POWER7.
+   Copyright (C) 2014 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/>.  */
+
+#define USE_AS_STPNCPY
+#include <sysdeps/powerpc/powerpc64/power7/strncpy.S>
+
+weak_alias (__stpncpy, stpncpy)
+libc_hidden_def (__stpncpy)
+libc_hidden_builtin_def (stpncpy)
diff --git a/sysdeps/powerpc/powerpc64/power7/strncpy.S b/sysdeps/powerpc/powerpc64/power7/strncpy.S
new file mode 100644
index 0000000..51860df
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strncpy.S
@@ -0,0 +1,338 @@
+/* Copyright (C) 2014 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 <sysdep.h>
+
+/* Implements the functions
+
+   char * [r3] strncpy (char *dst [r3], const char *src [r4], size_t n [r5])
+
+   AND
+
+   char * [r3] stpncpy (char *dst [r3], const char *src [r4], size_t n [r5])
+
+   The algorithm is as follows:
+   > if src and dest are 8 byte aligned, perform double word copy
+     else
+   > copy byte by byte on unaligned addresses.
+
+   The aligned comparison are made using cmpb instructions.  */
+
+/* The focus on optimization for performance improvements are as follows:
+   1. data alignment [gain from aligned memory access on read/write]
+   2. POWER7 gains performance with loop unrolling/unwinding
+      [gain by reduction of branch penalty].
+   3. The final pad with null bytes is done by calling an optimized
+      memset.  */
+
+#ifdef USE_AS_STPNCPY
+# define FUNC_NAME __stpncpy
+#else
+# define FUNC_NAME strncpy
+#endif
+
+#define		FRAMESIZE	(FRAME_MIN_SIZE+32)
+
+#ifndef MEMSET
+/* For builds with no IFUNC support, local calls should be made to internal
+   GLIBC symbol (created by libc_hidden_builtin_def).  */
+# ifdef SHARED
+#  define MEMSET   __GI_memset
+# else
+#  define MEMSET   memset
+# endif
+#endif
+
+	.machine  power7
+EALIGN(FUNC_NAME, 4, 0)
+	CALL_MCOUNT 3
+
+	mflr r0			/* load link register LR to r0  */
+	or r10, r3, r4		/* to verify source and destination  */
+	rldicl. r8, r10, 0, 61	/* is double word aligned .. ?  */
+
+	std r19, -8(r1)		/* save callers register , r19  */
+	std r18, -16(r1)	/* save callers register , r18  */
+	std r0, 16(r1)		/* store the link register  */
+	stdu r1, -FRAMESIZE(r1)	/* create the stack frame  */
+
+	mr r9, r3		/* save r3 into r9 for use  */
+	mr r18, r3		/* save r3 for retCode of strncpy  */
+	bne 0, L(byte_by_byte)
+
+
+	srdi r11, r5, 3		/* compute count for CTR ; count = n/8  */
+	cmpldi cr7, r11, 3	/* if count > 4 ; perform unrolling 4 times  */
+	ble 7, L(update1)
+
+	ld r10, 0(r4)		/* load doubleWord from src  */
+	cmpb r8, r10, r8	/* compare src with NULL ,we read just now  */
+	cmpdi cr7, r8, 0	/* if cmpb returned NULL ; we continue  */
+	bne cr7, L(update3)
+
+	std r10, 0(r3)		/* copy doubleword at offset=0  */
+	ld r10, 8(r4)		/* load next doubleword from offset=8  */
+	cmpb r8, r10, r8	/* compare src with NULL , we read just now  */
+	cmpdi cr7, r8, 0	/* if cmpb returned NULL ; we continue  */
+	bne 7,L(HopBy8)
+
+	addi r8, r11, -4
+	mr r7, r3
+	srdi r8, r8, 2
+	mr r6, r4
+	addi r8, r8, 1
+	li r12, 0
+	mtctr r8
+	b L(dwordCopy)
+
+	.p2align 4
+L(dWordUnroll):
+	std r8, 16(r9)
+	ld r8, 24(r4)		/* load dword,perform loop unrolling again  */
+	cmpb r10, r8, r10
+	cmpdi cr7, r10, 0
+	bne cr7, L(HopBy24)
+
+	std r8, 24(r7)		/* copy dword at offset=24  */
+	addi r9, r9, 32
+	addi r4, r4, 32
+	bdz  L(leftDwords)	/* continue with loop on counter  */
+
+	ld r3, 32(r6)
+	cmpb r8, r3, r10
+	cmpdi cr7, r8, 0
+	bne cr7, L(update2)
+
+	std r3, 32(r7)
+	ld r10, 40(r6)
+	cmpb r8, r10, r8
+	cmpdi cr7, r8, 0
+	bne cr7, L(HopBy40)
+
+	mr r6, r4		/* update values  */
+	mr r7, r9
+	mr r11, r0
+	mr r5, r19
+
+L(dwordCopy):
+	std r10, 8(r9)		/* copy dword at offset=8  */
+	addi r19, r5, -32
+	addi r0, r11, -4
+	ld r8, 16(r4)
+	cmpb r10, r8, r12
+	cmpdi cr7, r10, 0
+	beq cr7, L(dWordUnroll)
+
+	addi r9, r9, 16		/* increment dst by 16  */
+	addi r4, r4, 16		/* increment src by 16  */
+	addi r5, r5, -16	/* decrement length 'n' by 16  */
+	addi r0, r11, -2	/* decrement loop counter  */
+
+L(dWordUnrollOFF):
+	ld r10, 0(r4)		/* load first dword  */
+	li r8, 0		/* load mask  */
+	cmpb r8, r10, r8
+	cmpdi cr7, r8, 0
+	bne cr7, L(byte_by_byte)
+	mtctr r0
+	li r7, 0
+	b L(CopyDword)
+
+	.p2align 4
+L(loadDWordandCompare):
+	ld r10, 0(r4)
+	cmpb r8, r10, r7
+	cmpdi cr7, r8, 0
+	bne cr7, L(byte_by_byte)
+
+L(CopyDword):
+	addi r9, r9, 8
+	std r10, -8(r9)
+	addi r4, r4, 8
+	addi r5, r5, -8
+	bdnz L(loadDWordandCompare)
+
+L(byte_by_byte):
+	cmpldi cr7, r5, 3
+	ble cr7, L(verifyByte)
+	srdi r10, r5, 2
+	mr r19, r9
+	mtctr r10
+	b L(firstByteUnroll)
+
+	.p2align 4
+L(bytes_unroll):
+	lbz r10, 1(r4)		/* load byte from src  */
+	cmpdi cr7, r10, 0	/* compare for NULL  */
+	stb r10, 1(r19)		/* store byte to dst  */
+	beq cr7, L(updtDestComputeN2ndByte)
+
+	addi r4, r4, 4		/* advance src  */
+
+	lbz r10, -2(r4)		/* perform loop unrolling for byte r/w  */
+	cmpdi cr7, r10, 0
+	stb r10, 2(r19)
+	beq cr7, L(updtDestComputeN3rdByte)
+
+	lbz r10, -1(r4)		/* perform loop unrolling for byte r/w  */
+	addi r19, r19, 4
+	cmpdi cr7, r10, 0
+	stb r10, -1(r19)
+	beq cr7, L(ComputeNByte)
+
+	bdz L(update0)
+
+L(firstByteUnroll):
+	lbz r10, 0(r4)		/* perform loop unrolling for byte r/w  */
+	cmpdi cr7, 10, 0
+	stb r10, 0(r19)
+	bne cr7, L(bytes_unroll)
+	addi r19, r19, 1
+
+L(ComputeNByte):
+	subf r9, r19, r9	/* compute 'n'n bytes to fill  */
+	add r8, r9, r5
+
+L(zeroFill):
+	cmpdi cr7, r8, 0	/* compare if length is zero  */
+	beq cr7, L(update3return)
+
+	mr r3, r19		/* fill buffer with  */
+	li r4, 0		/* zero fill buffer  */
+	mr r5, r8		/* how many bytes to fill buffer with  */
+	bl MEMSET		/* call optimized memset  */
+	nop
+
+L(update3return):
+#ifdef USE_AS_STPNCPY
+	addi r3, r19, -1	/* update return value  */
+#endif
+
+L(hop2return):
+#ifndef USE_AS_STPNCPY
+	mr r3, r18		/* set return value  */
+#endif
+	addi r1, r1, FRAMESIZE	/* restore stack pointer  */
+	ld r0, 16(r1)		/* read the saved link register  */
+	ld r18, -16(r1)		/* restore callers save register, r18  */
+	ld r19, -8(r1)		/* restore callers save register, r19  */
+	mtlr r0			/* branch to link register  */
+	blr			/* return  */
+
+	.p2align 4
+L(update0):
+	mr r9, r19
+
+	.p2align 4
+L(verifyByte):
+	rldicl. r8, r5, 0, 62
+#ifdef USE_AS_STPNCPY
+	mr r3, r9
+#endif
+	beq cr0, L(hop2return)
+	mtctr r8
+	addi r4, r4, -1
+	mr r19, r9
+	b L(oneBYone)
+
+	.p2align 4
+L(proceed):
+	bdz L(done)
+
+L(oneBYone):
+	lbzu r10, 1(r4)		/* copy byte  */
+	addi r19, r19, 1
+	addi r8, r8, -1
+	cmpdi cr7, r10, 0
+	stb r10, -1(r19)
+	bne cr7, L(proceed)
+	b L(zeroFill)
+
+	.p2align 4
+L(done):
+	addi r1, r1, FRAMESIZE	/* restore stack pointer  */
+#ifdef USE_AS_STPNCPY
+	mr r3, r19		/* set the return value  */
+#else
+	mr r3, r18		/* set the return value  */
+#endif
+	ld r0, 16(r1)		/* read the saved link register  */
+	ld r18, -16(r1)		/* restore callers save register, r18  */
+	ld r19, -8(r1)		/* restore callers save register, r19  */
+	mtlr r0			/* branch to link register  */
+	blr			/* return  */
+
+L(update1):
+	mr r0, r11
+	mr r19, r5
+
+	.p2align 4
+L(leftDwords):
+	cmpdi cr7, r0, 0
+	mr r5, r19
+	bne cr7, L(dWordUnrollOFF)
+	b L(byte_by_byte)
+
+	.p2align 4
+L(updtDestComputeN2ndByte):
+	addi r19, r19, 2	/* update dst by 2  */
+	subf r9, r19, r9	/* compute distance covered  */
+	add r8, r9, r5
+	b L(zeroFill)
+
+	.p2align 4
+L(updtDestComputeN3rdByte):
+	addi r19, r19, 3	/* update dst by 3  */
+	subf r9, r19, r9	/* compute distance covered  */
+	add r8, r9, r5
+	b L(zeroFill)
+
+	.p2align 4
+L(HopBy24):
+	addi r9, r9, 24		/* increment dst by 24  */
+	addi r4, r4, 24		/* increment src by 24  */
+	addi r5, r5, -24	/* decrement length 'n' by 24  */
+	addi r0, r11, -3	/* decrement loop counter  */
+	b L(dWordUnrollOFF)
+
+	.p2align 4
+L(update2):
+	mr r5, r19
+	b L(dWordUnrollOFF)
+
+	.p2align 4
+L(HopBy40):
+	addi r9, r7, 40		/* increment dst by 40  */
+	addi r4, r6, 40		/* increment src by 40  */
+	addi r5, r5, -40	/* decrement length 'n' by 40  */
+	addi r0, r11, -5	/* decrement loop counter  */
+	b L(dWordUnrollOFF)
+
+L(update3):
+	mr r0, r11
+	b L(dWordUnrollOFF)
+
+L(HopBy8):
+	addi r9, r3, 8		/* increment dst by 8  */
+	addi r4, r4, 8		/* increment src by 8  */
+	addi r5, r5, -8		/* decrement length 'n' by 8  */
+	addi r0, r11, -1	/* decrement loop counter  */
+	b L(dWordUnrollOFF)
+END(FUNC_NAME)
+#ifndef USE_AS_STPNCPY
+libc_hidden_builtin_def (strncpy)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=08111251bbd7275024d9c945f442f61b06d98910

commit 08111251bbd7275024d9c945f442f61b06d98910
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri May 2 12:00:36 2014 -0500

    PowerPC: ifunc improvement for internal calls
    
    This patch changes de default symbol redirection for internal call of
    memcpy, memset, memchr, and strlen to the IFUNC resolved ones.  The
    performance improvement is noticeable in algorithms that uses these
    symbols extensible, like the regex functions.
    
    This is a backport of 19c4bec0f43599eecc2f32de96ae179cd7d64053.

diff --git a/ChangeLog b/ChangeLog
index e25ed1a..b728c33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2014-05-04  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+	[libc_hidden_builtin_def]: Define to empty value.
+	* sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S:
+	[libc_hidden_builtin_def]: Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S:
+	[libc_hidden_builtin_def]: Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S:
+	[libc_hidden_builtin_def]: Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/memcpy.c (memcpy): Redefined to
+	__redirect_memcpy and define ifunc as default hidden symbol.
+	* sysdeps/powerpc/powerpc64/multiarch/memset.c (memset): Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/strlen.c (strlen): Likewise.
+
 2014-04-16  Alan Modra  <amodra@gmail.com>
 
 	[BZ #16740]
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
index 43c5652..4bd6bb9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memchr-ppc32.c
@@ -25,8 +25,7 @@
 
 #ifdef SHARED
 # undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)  \
-  __hidden_ver1 (__memchr_ppc, __GI_memchr, __memchr_ppc);
+# define libc_hidden_builtin_def(name)
 #endif
 
 extern __typeof (memchr) __memchr_ppc attribute_hidden;
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
index a09d760..c630654 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy-ppc64.S
@@ -36,8 +36,7 @@
    END_2(__memcpy_ppc)
 
 # undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)				\
-   .globl __GI_memcpy; __GI_memcpy = __memcpy_ppc
+# define libc_hidden_builtin_def(name)
 #endif
 
 #include <sysdeps/powerpc/powerpc64/memcpy.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
index 6a91630..305e963 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcpy.c
@@ -20,20 +20,23 @@
    DSO.  In static binaries we need memcpy before the initialization
    happened.  */
 #if defined SHARED && !defined NOT_IN_libc
+/* Redefine memcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memcpy
+# define memcpy __redirect_memcpy
 # include <string.h>
-# include <shlib-compat.h>
 # include "init-arch.h"
 
-extern __typeof (memcpy) __memcpy_ppc attribute_hidden;
-extern __typeof (memcpy) __memcpy_power4 attribute_hidden;
-extern __typeof (memcpy) __memcpy_cell attribute_hidden;
-extern __typeof (memcpy) __memcpy_power6 attribute_hidden;
-extern __typeof (memcpy) __memcpy_a2 attribute_hidden;
-extern __typeof (memcpy) __memcpy_power7 attribute_hidden;
+extern __typeof (__redirect_memcpy) __libc_memcpy;
 
-/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
-   ifunc symbol properly.  */
-libc_ifunc (memcpy,
+extern __typeof (__redirect_memcpy) __memcpy_ppc attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_power4 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_cell attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_power6 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_a2 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_power7 attribute_hidden;
+
+libc_ifunc (__libc_memcpy,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcpy_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
@@ -45,4 +48,8 @@ libc_ifunc (memcpy,
 		    (hwcap & PPC_FEATURE_POWER4)
 		    ? __memcpy_power4
             : __memcpy_ppc);
+
+#undef memcpy
+strong_alias (__libc_memcpy, memcpy);
+libc_hidden_ver (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
index 65b3afe..3601a77 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
@@ -47,8 +47,7 @@ END_GEN_TB (__bzero_ppc,TB_TOCLESS)
   END_2(__memset_ppc)
 
 # undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)				\
-  .globl __GI_memset; __GI_memset = __memset_ppc
+# define libc_hidden_builtin_def(name)
 #endif
 
 /* Do not implement __bzero at powerpc64/memset.S.  */
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c
index 829d127..aa2ae70 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memset.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c
@@ -18,18 +18,24 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && !defined NOT_IN_libc
+/* Redefine memset so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memset
+# define memset __redirect_memset
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
-extern __typeof (memset) __memset_ppc attribute_hidden;
-extern __typeof (memset) __memset_power4 attribute_hidden;
-extern __typeof (memset) __memset_power6 attribute_hidden;
-extern __typeof (memset) __memset_power7 attribute_hidden;
+extern __typeof (__redirect_memset) __libc_memset;
+
+extern __typeof (__redirect_memset) __memset_ppc attribute_hidden;
+extern __typeof (__redirect_memset) __memset_power4 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_power6 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_power7 attribute_hidden;
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memset,
+libc_ifunc (__libc_memset,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memset_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_05)
@@ -37,4 +43,8 @@ libc_ifunc (memset,
 		  (hwcap & PPC_FEATURE_POWER4)
 		? __memset_power4
             : __memset_ppc);
+
+#undef memset
+strong_alias (__libc_memset, memset);
+libc_hidden_ver (__libc_memset, memset);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
index efcc212..a195e9a 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
+++ b/sysdeps/powerpc/powerpc64/multiarch/strlen-ppc64.S
@@ -35,8 +35,7 @@
   END_2(__strlen_ppc)
 
 # undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)				\
-    .globl __GI_strlen; __GI_strlen = __strlen_ppc
+# define libc_hidden_builtin_def(name)
 #endif
 
 #include <sysdeps/powerpc/powerpc64/strlen.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strlen.c b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
index 6574696..d2c26e9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strlen.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strlen.c
@@ -17,15 +17,25 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && !defined NOT_IN_libc
+/* Redefine strlen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strlen
+# define strlen __redirect_strlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
-extern __typeof (strlen) __strlen_ppc attribute_hidden;
-extern __typeof (strlen) __strlen_power7 attribute_hidden;
+extern __typeof (__redirect_strlen) __libc_strlen;
 
-libc_ifunc (strlen,
+extern __typeof (__redirect_strlen) __strlen_ppc attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_power7 attribute_hidden;
+
+libc_ifunc (__libc_strlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strlen_power7
             : __strlen_ppc);
+
+#undef strlen
+strong_alias (__libc_strlen, strlen)
+libc_hidden_ver (__libc_strlen, strlen)
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a8050d789589b73e7908b806d5c929facf76cc6b

commit a8050d789589b73e7908b806d5c929facf76cc6b
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Apr 16 19:33:32 2014 +0930

    Correct IBM long double frexpl.
    
    Besides fixing the bugzilla, this also fixes corner-cases where the high
    and low double differ greatly in magnitude, and handles a denormal
    input without resorting to a fp rescale.
    
    	[BZ #16740]
    	[BZ #16619]
    	* sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Rewrite.
    	* math/libm-test.inc (frexp_test_data): Add tests.
    
    Backport of aa5f0ff11ad2cc85277c64cf65c723a9664e1149 and
    9860b0450275ad2b69cb9360fd01d5c122a65fc5.

diff --git a/ChangeLog b/ChangeLog
index c28708f..e25ed1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-04-16  Alan Modra  <amodra@gmail.com>
+
+	[BZ #16740]
+	[BZ #16619]
+	* sysdeps/ieee754/ldbl-128ibm/s_frexpl.c (__frexpl): Rewrite.
+	* math/libm-test.inc (frexp_test_data): Add tests.
+
 2014-04-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #16815]
diff --git a/NEWS b/NEWS
index a496294..99bda3c 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815.
+  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index cf07069..1c5c022 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -8723,6 +8723,15 @@ static const struct test_f_f1_data frexp_test_data[] =
 
     TEST_fI_f1 (frexp, 12.8L, 0.8L, 4, NO_INEXACT_EXCEPTION),
     TEST_fI_f1 (frexp, -27.34L, -0.854375L, 5, NO_INEXACT_EXCEPTION),
+
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+    TEST_fI_f1 (frexp, 1.0L-0x1p-106L, 1.0L-0x1p-106L, 0, NO_INEXACT_EXCEPTION),
+    TEST_fI_f1 (frexp, 1.0L, 0.5L, 1, NO_INEXACT_EXCEPTION),
+    TEST_fI_f1 (frexp, 1.0L+0x1p-105L, 0.5L+0x1p-106L, 1, NO_INEXACT_EXCEPTION),
+    TEST_fI_f1 (frexp, -1.0L+0x1p-106L, -1.0L+0x1p-106L, 0, NO_INEXACT_EXCEPTION),
+    TEST_fI_f1 (frexp, -1.0L, -0.5L, 1, NO_INEXACT_EXCEPTION),
+    TEST_fI_f1 (frexp, -1.0L-0x1p-105L, -0.5L-0x1p-106L, 1, NO_INEXACT_EXCEPTION),
+#endif
   };
 
 static void
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
index 7e40663..a644f92 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_frexpl.c
@@ -31,57 +31,115 @@ static char rcsid[] = "$NetBSD: $";
 #include <math_private.h>
 #include <math_ldbl_opt.h>
 
-static const long double
-two107 = 162259276829213363391578010288128.0; /* 0x4670000000000000, 0 */
-
 long double __frexpl(long double x, int *eptr)
 {
-	uint64_t hx, lx, ix, ixl;
-	int64_t explo;
-	double xhi, xlo;
+  uint64_t hx, lx, ix, ixl;
+  int64_t explo, expon;
+  double xhi, xlo;
+
+  ldbl_unpack (x, &xhi, &xlo);
+  EXTRACT_WORDS64 (hx, xhi);
+  EXTRACT_WORDS64 (lx, xlo);
+  ixl = 0x7fffffffffffffffULL & lx;
+  ix  = 0x7fffffffffffffffULL & hx;
+  expon = 0;
+  if (ix >= 0x7ff0000000000000ULL || ix == 0)
+    {
+      /* 0,inf,nan.  */
+      *eptr = expon;
+      return x;
+    }
+  expon = ix >> 52;
+  if (expon == 0)
+    {
+      /* Denormal high double, the low double must be 0.0.  */
+      int cnt;
+
+      /* Normalize.  */
+      if (sizeof (ix) == sizeof (long))
+	cnt = __builtin_clzl (ix);
+      else if ((ix >> 32) != 0)
+	cnt = __builtin_clzl ((long) (ix >> 32));
+      else
+	cnt = __builtin_clzl ((long) ix) + 32;
+      cnt = cnt - 12;
+      expon -= cnt;
+      ix <<= cnt + 1;
+    }
+  expon -= 1022;
+  ix &= 0x000fffffffffffffULL;
+  hx &= 0x8000000000000000ULL;
+  hx |= (1022LL << 52) | ix;
 
-	ldbl_unpack (x, &xhi, &xlo);
-	EXTRACT_WORDS64 (hx, xhi);
-	EXTRACT_WORDS64 (lx, xlo);
-	ixl = 0x7fffffffffffffffULL&lx;
-	ix =  0x7fffffffffffffffULL&hx;
-	*eptr = 0;
-	if(ix>=0x7ff0000000000000ULL||ix==0) return x;	/* 0,inf,nan */
-	if (ix<0x0010000000000000ULL) {		/* subnormal */
-	    x *= two107;
-	    xhi = ldbl_high (x);
-	    EXTRACT_WORDS64 (hx, xhi);
-	    ix = hx&0x7fffffffffffffffULL;
-	    *eptr = -107;
+  if (ixl != 0)
+    {
+      /* If the high double is an exact power of two and the low
+	 double has the opposite sign, then the exponent calculated
+	 from the high double is one too big.  */
+      if (ix == 0
+	  && (int64_t) (hx ^ lx) < 0)
+	{
+	  hx += 1L << 52;
+	  expon -= 1;
 	}
-	*eptr += (ix>>52)-1022;
 
-	if (ixl != 0ULL) {
-	  explo = (ixl>>52) - (ix>>52) + 0x3fe;
-	  if ((ixl&0x7ff0000000000000ULL) == 0LL) {
-	    /* the lower double is a denormal so we need to correct its
-	       mantissa and perhaps its exponent.  */
-	    int cnt;
+      explo = ixl >> 52;
+      if (explo == 0)
+	{
+	  /* The low double started out as a denormal.  Normalize its
+	     mantissa and adjust the exponent.  */
+	  int cnt;
 
-	    if (sizeof (ixl) == sizeof (long))
-	      cnt = __builtin_clzl (ixl);
-	    else if ((ixl >> 32) != 0)
-	      cnt = __builtin_clzl ((long) (ixl >> 32));
-	    else
-	      cnt = __builtin_clzl ((long) ixl) + 32;
-	    cnt = cnt - 12;
-	    lx = (lx&0x8000000000000000ULL) | ((explo-cnt)<<52)
-	       | ((ixl<<(cnt+1))&0x000fffffffffffffULL);
-	  } else
-	    lx = (lx&0x800fffffffffffffULL) | (explo<<52);
-	} else
-	  lx = 0ULL;
+	  if (sizeof (ixl) == sizeof (long))
+	    cnt = __builtin_clzl (ixl);
+	  else if ((ixl >> 32) != 0)
+	    cnt = __builtin_clzl ((long) (ixl >> 32));
+	  else
+	    cnt = __builtin_clzl ((long) ixl) + 32;
+	  cnt = cnt - 12;
+	  explo -= cnt;
+	  ixl <<= cnt + 1;
+	}
+
+      /* With variable precision we can't assume much about the
+	 magnitude of the returned low double.  It may even be a
+	 denormal.  */
+      explo -= expon;
+      ixl &= 0x000fffffffffffffULL;
+      lx  &= 0x8000000000000000ULL;
+      if (explo <= 0)
+	{
+	  /* Handle denormal low double.  */
+	  if (explo > -52)
+	    {
+	      ixl |= 1LL << 52;
+	      ixl >>= 1 - explo;
+	    }
+	  else
+	    {
+	      ixl = 0;
+	      lx = 0;
+	      if ((hx & 0x7ff0000000000000ULL) == (1023LL << 52))
+		{
+		  /* Oops, the adjustment we made above for values a
+		     little smaller than powers of two turned out to
+		     be wrong since the returned low double will be
+		     zero.  This can happen if the input was
+		     something weird like 0x1p1000 - 0x1p-1000.  */
+		  hx -= 1L << 52;
+		  expon += 1;
+		}
+	    }
+	  explo = 0;
+	}
+      lx |= (explo << 52) | ixl;
+    }
 
-	hx = (hx&0x800fffffffffffffULL) | 0x3fe0000000000000ULL;
-	INSERT_WORDS64 (xhi, hx);
-	INSERT_WORDS64 (xlo, lx);
-	x = ldbl_pack (xhi, xlo);
-	return x;
+  INSERT_WORDS64 (xhi, hx);
+  INSERT_WORDS64 (xlo, lx);
+  x = ldbl_pack (xhi, xlo);
+  *eptr = expon;
+  return x;
 }
 #ifdef IS_IN_libm
 long_double_symbol (libm, __frexpl, frexpl);

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=154d4d95f48061d5ab890c85b6015221c1accc6e

commit 154d4d95f48061d5ab890c85b6015221c1accc6e
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Sun Apr 6 14:50:11 2014 -0500

    PowerPC: Fix nearbyint/nearbyintf result for FE_DOWNWARD
    
    This patch fixes the powerpc32 optimized nearbyint/nearbyintf bogus
    results for FE_DOWNWARD rounding mode.  This is due wrong instructions
    sequence used in the rounding calculation (two subtractions instead of
    adition and a subtraction).
    
    Fixes BZ#16815.
    
    Backport of 8bd70862e11023e7f827f240a5a214f847ae982d.

diff --git a/ChangeLog b/ChangeLog
index 5bf3e26..c28708f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2014-04-06  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	[BZ #16815]
+	* sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S (__nearbyint): Fix
+	result for FE_DOWNWARD rounding mode.
+	* sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S (__nearbyintf):
+	Likewise.
+	* sysdeps/powerpc/fpu/libm-test-ulps: Update.
+
 2014-04-02  Alan Modra  <amodra@gmail.com>
 
 	[BZ #16739]
diff --git a/NEWS b/NEWS
index 71f6fb6..a496294 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707, 16739.
+  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815.
 
 Version 2.19
 
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
index 2734738..05ab40e 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S
@@ -53,17 +53,17 @@ ENTRY (__nearbyint)
 	fcmpu	cr7,fp1,fp12	/* if (x > 0.0 */
 	ble	cr7,L(lessthanzero)
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
-	fadd	fp0,fp1,fp13	/* x += TWO52 */
-	fsub	fp1,fp0,fp13	/* x -= TWO52 */
+	fadd	fp1,fp1,fp13	/* x += TWO52 */
+	fsub	fp1,fp1,fp13	/* x -= TWO52 */
 	fabs	fp1,fp1		/* if (x == 0.0 */
 	mtfsb0	4*cr1+eq	/* Clear any FE_INEXACT exception */
 	blr
 L(lessthanzero):
 	bgelr	cr7
 	mtfsb0	4*cr7+lt	/* Disable FE_INEXACT exception */
-	fsub	fp0,fp13,fp1	/* x -= TWO52 */
-	fsub	fp0,fp0,fp13	/* x += TWO52 */
-	fneg	fp1,fp0		/* if (x == 0.0) */
+	fsub	fp1,fp1,fp13	/* x -= TWO52 */
+	fadd	fp1,fp1,fp13	/* x += TWO52 */
+	fnabs	fp1,fp1		/* if (x == 0.0) */
 	mtfsb0	4*cr1+eq	/* Clear any FE_INEXACT exception */
 	blr
 END (__nearbyint)
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
index 11bdc77..7449a5f 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S
@@ -52,16 +52,17 @@ ENTRY (__nearbyintf)
 	fcmpu	cr7,fp1,fp12		/* if (x > 0.0 */
 	ble	cr7,L(lessthanzero)
 	mtfsb0	4*cr7+lt		/* Disable FE_INEXACT exception */
-	fadds	fp0,fp1,fp13		/* x += TWO23 */
-	fsubs	fp1,fp0,fp13		/* x -= TWO23 */
+	fadds	fp1,fp1,fp13		/* x += TWO23 */
+	fsubs	fp1,fp1,fp13		/* x -= TWO23 */
+	fabs	fp1,fp1			/* if (x == 0.0) */
 	mtfsb0	4*cr1+eq		/* Clear any FE_INEXACT exception */
 	blr
 L(lessthanzero):
 	bgelr	cr7
 	mtfsb0	4*cr7+lt		/* Disable FE_INEXACT exception */
-	fsubs	fp0,fp13,fp1		/* x -= TWO23 */
-	fsubs	fp0,fp0,fp13		/* x += TWO23 */
-	fneg	fp1,fp0			/* if (x == 0.0) */
+	fsubs	fp1,fp1,fp13		/* x -= TWO23 */
+	fadds	fp1,fp1,fp13		/* x += TWO23 */
+	fnabs	fp1,fp1			/* if (x == 0.0) */
 	mtfsb0	4*cr1+eq		/* Clear any FE_INEXACT exception */
 	blr
 END (__nearbyintf)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e266b71770050a4d0cb276f4afea1c5b05215184

commit e266b71770050a4d0cb276f4afea1c5b05215184
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Apr 2 13:46:19 2014 +1030

    Correct IBM long double nextafterl.
    
    Fix for values near a power of two, and some tidies.
    
    	[BZ #16739]
    	* sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Correct
    	output when value is near a power of two.  Use int64_t for lx and
    	remove casts.  Use decimal rather than hex exponent constants.
    	Don't use long double multiplication when double will suffice.
    	* math/libm-test.inc (nextafter_test_data): Add tests.
    	* NEWS: Add 16739 and 16786 to bug list.
    
    Backport of b0abbc21034f0e5edc49023d8fda0616173faf17.

diff --git a/ChangeLog b/ChangeLog
index fe00e0c..5bf3e26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2014-04-02  Alan Modra  <amodra@gmail.com>
 
+	[BZ #16739]
+	* sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (__nextafterl): Correct
+	output when value is near a power of two.  Use int64_t for lx and
+	remove casts.  Use decimal rather than hex exponent constants.
+	Don't use long double multiplication when double will suffice.
+	* math/libm-test.inc (nextafter_test_data): Add tests.
+	* NEWS: Add 16739 and 16786 to bug list.
+
+2014-04-02  Alan Modra  <amodra@gmail.com>
+
 	* sysdeps/powerpc/powerpc64/power7/memrchr.S: Correct stream hint.
 
 2014-04-02  Alan Modra  <amodra@gmail.com>
diff --git a/NEWS b/NEWS
index a647e5d..71f6fb6 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707.
+  16545, 16683, 16689, 16701, 16706, 16707, 16739.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 1c9b97a..cf07069 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -10547,6 +10547,14 @@ static const struct test_ff_f_data nextafter_test_data[] =
     // XXX Enable once gcc is fixed.
     //TEST_ff_f (nextafter, 0x0.00000040000000000000p-16385L, -0.1L, 0x0.0000003ffffffff00000p-16385L),
 #endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106
+    TEST_ff_f (nextafter, 1.0L, -10.0L, 1.0L-0x1p-106L, NO_EXCEPTION),
+    TEST_ff_f (nextafter, 1.0L, 10.0L, 1.0L+0x1p-105L, NO_EXCEPTION),
+    TEST_ff_f (nextafter, 1.0L-0x1p-106L, 10.0L, 1.0L, NO_EXCEPTION),
+    TEST_ff_f (nextafter, -1.0L, -10.0L, -1.0L-0x1p-105L, NO_EXCEPTION),
+    TEST_ff_f (nextafter, -1.0L, 10.0L, -1.0L+0x1p-106L, NO_EXCEPTION),
+    TEST_ff_f (nextafter, -1.0L+0x1p-106L, -10.0L, -1.0L, NO_EXCEPTION),
+#endif
 
     /* XXX We need the hexadecimal FP number representation here for further
        tests.  */
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
index c050944..7b09927 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
@@ -30,8 +30,7 @@ static char rcsid[] = "$NetBSD: $";
 
 long double __nextafterl(long double x, long double y)
 {
-	int64_t hx,hy,ihx,ihy;
-	uint64_t lx;
+	int64_t hx, hy, ihx, ihy, lx;
 	double xhi, xlo, yhi;
 
 	ldbl_unpack (x, &xhi, &xlo);
@@ -76,19 +75,28 @@ long double __nextafterl(long double x, long double y)
 	      u = math_opt_barrier (x);
 	      x -= __LDBL_DENORM_MIN__;
 	      if (ihx < 0x0360000000000000LL
-		  || (hx > 0 && (int64_t) lx <= 0)
-		  || (hx < 0 && (int64_t) lx > 1)) {
+		  || (hx > 0 && lx <= 0)
+		  || (hx < 0 && lx > 1)) {
 		u = u * u;
 		math_force_eval (u);		/* raise underflow flag */
 	      }
 	      return x;
 	    }
-	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
-	      INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
-	      u = yhi;
-	      u *= 0x1.0000000000000p-105L;
+	    /* If the high double is an exact power of two and the low
+	       double is the opposite sign, then 1ulp is one less than
+	       what we might determine from the high double.  Similarly
+	       if X is an exact power of two, and positive, because
+	       making it a little smaller will result in the exponent
+	       decreasing by one and normalisation of the mantissa.   */
+	    if ((hx & 0x000fffffffffffffLL) == 0
+		&& ((lx != 0 && (hx ^ lx) < 0)
+		    || (lx == 0 && hx >= 0)))
+	      ihx -= 1LL << 52;
+	    if (ihx < (106LL << 52)) { /* ulp will denormal */
+	      INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52));
+	      u = yhi * 0x1p-105;
 	    } else {
-	      INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
+	      INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52));
 	      u = yhi;
 	    }
 	    return x - u;
@@ -103,8 +111,8 @@ long double __nextafterl(long double x, long double y)
 	      u = math_opt_barrier (x);
 	      x += __LDBL_DENORM_MIN__;
 	      if (ihx < 0x0360000000000000LL
-		  || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL)
-		  || (hx < 0 && (int64_t) lx >= 0)) {
+		  || (hx > 0 && lx < 0 && lx != 0x8000000000000001LL)
+		  || (hx < 0 && lx >= 0)) {
 		u = u * u;
 		math_force_eval (u);		/* raise underflow flag */
 	      }
@@ -112,12 +120,21 @@ long double __nextafterl(long double x, long double y)
 		x = -0.0L;
 	      return x;
 	    }
-	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
-	      INSERT_WORDS64 (yhi, hx & (0x7ffLL<<52));
-	      u = yhi;
-	      u *= 0x1.0000000000000p-105L;
+	    /* If the high double is an exact power of two and the low
+	       double is the opposite sign, then 1ulp is one less than
+	       what we might determine from the high double.  Similarly
+	       if X is an exact power of two, and negative, because
+	       making it a little larger will result in the exponent
+	       decreasing by one and normalisation of the mantissa.   */
+	    if ((hx & 0x000fffffffffffffLL) == 0
+		&& ((lx != 0 && (hx ^ lx) < 0)
+		    || (lx == 0 && hx < 0)))
+	      ihx -= 1LL << 52;
+	    if (ihx < (106LL << 52)) { /* ulp will denormal */
+	      INSERT_WORDS64 (yhi, ihx & (0x7ffLL<<52));
+	      u = yhi * 0x1p-105;
 	    } else {
-	      INSERT_WORDS64 (yhi, (hx & (0x7ffLL<<52))-(0x069LL<<52));
+	      INSERT_WORDS64 (yhi, (ihx & (0x7ffLL<<52))-(105LL<<52));
 	      u = yhi;
 	    }
 	    return x + u;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b23fc92895aff0ce3d3134a91adaa253bffd187a

commit b23fc92895aff0ce3d3134a91adaa253bffd187a
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Apr 2 13:42:27 2014 +1030

    Correct prefetch hint in power7 memrchr.
    
    Typo fix.
    
    	* sysdeps/powerpc/powerpc64/power7/memrchr.S: Correct stream hint.
    
    Backport of af6b17973cbc07ac06cfb40eeab5cc2391fb489a.

diff --git a/ChangeLog b/ChangeLog
index 1768334..fe00e0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2014-04-02  Alan Modra  <amodra@gmail.com>
 
+	* sysdeps/powerpc/powerpc64/power7/memrchr.S: Correct stream hint.
+
+2014-04-02  Alan Modra  <amodra@gmail.com>
+
 	* sysdeps/powerpc/powerpc64/start.S: Add @toc to toc symbol reference.
 
 2014-04-01  Alan Modra  <amodra@gmail.com>
diff --git a/sysdeps/powerpc/powerpc64/power7/memrchr.S b/sysdeps/powerpc/powerpc64/power7/memrchr.S
index 40e436f..0c01ca2 100644
--- a/sysdeps/powerpc/powerpc64/power7/memrchr.S
+++ b/sysdeps/powerpc/powerpc64/power7/memrchr.S
@@ -29,7 +29,7 @@ ENTRY (__memrchr)
 	mr	r10,r3
 	clrrdi	r6,r7,7
 	li	r9,3<<5
-	dcbt	r9,r6,16      /* Stream hint, decreasing addresses.  */
+	dcbt	r9,r6,8       /* Stream hint, decreasing addresses.  */
 
 	/* Replicate BYTE to doubleword.  */
 	insrdi	r4,r4,8,48

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=acd56f757b4e5ab8737b9564bd7a4ad1009acd8d

commit acd56f757b4e5ab8737b9564bd7a4ad1009acd8d
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Apr 2 13:40:21 2014 +1030

    Fix reference to toc symbol.
    
    https://sourceware.org/ml/binutils/2014-03/msg00033.html removes the
    "magic" treatment of symbols defined in a .toc section.
    
    	* sysdeps/powerpc/powerpc64/start.S: Add @toc to toc symbol reference.
    
    Backport of 483818d768ed99a5edf4114298a75ebedaee8d5c.

diff --git a/ChangeLog b/ChangeLog
index a54240d..1768334 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-02  Alan Modra  <amodra@gmail.com>
+
+	* sysdeps/powerpc/powerpc64/start.S: Add @toc to toc symbol reference.
+
 2014-04-01  Alan Modra  <amodra@gmail.com>
 
 	[BZ #16786]
diff --git a/sysdeps/powerpc/powerpc64/start.S b/sysdeps/powerpc/powerpc64/start.S
index 15e29d9..934c558 100644
--- a/sysdeps/powerpc/powerpc64/start.S
+++ b/sysdeps/powerpc/powerpc64/start.S
@@ -74,7 +74,7 @@ ENTRY(_start)
 
  /* put the address of start_addresses in r8...  **
 ** PPC64 ABI uses R13 for thread local, so we leave it alone */
-	ld	r8,.L01(r2)
+	ld	r8,.L01@toc(r2)
 
  /* and continue in libc-start, in glibc.  */
 	b	JUMPTARGET(__libc_start_main)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fd5100c480beef3d36c4bf74b6a23529695d036c

commit fd5100c480beef3d36c4bf74b6a23529695d036c
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Apr 1 14:07:42 2014 +1030

    Fix s_copysign stack temp for PowerPC64 ELFv2
    
    	[BZ #16786]
    	* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack.
    
    Backport of c859b32e9d76afe8a3f20bb9528961a573c06937.

diff --git a/ChangeLog b/ChangeLog
index 5c508a9..a54240d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-01  Alan Modra  <amodra@gmail.com>
+
+	[BZ #16786]
+	* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Don't trash stack.
+
 2014-03-31  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S (MFVSRD_R3_V1):
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
index 51681aa..49c793d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
+++ b/sysdeps/powerpc/powerpc64/fpu/s_copysign.S
@@ -27,11 +27,11 @@ ENTRY(__copysign)
 /* double [f1] copysign (double [f1] x, double [f2] y);
    copysign(x,y) returns a value with the magnitude of x and
    with the sign bit of y.  */
-	stfd	fp2,56(r1)
+	stfd	fp2,-8(r1)
 	nop
 	nop
 	nop
-	ld	r3,56(r1)
+	ld	r3,-8(r1)
 	cmpdi   r3,0
 	blt     L(0)
 	fabs    fp1,fp1

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a51aafa398ed7dd2a0a846c1b2ed8a37909609eb

commit a51aafa398ed7dd2a0a846c1b2ed8a37909609eb
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Mon Mar 31 08:07:55 2014 -0500

    PowerPC: Fix little endian enconding for mfvsrd
    
    This patch fixes the MFVSRD_R3_V1 macro that encodes 'mfvsrd  r3,vs1'
    (to support old binutils) for little endian.
    
    Backport of 757d9dd5c3efa56fac75965abc014faaae7b7895.

diff --git a/ChangeLog b/ChangeLog
index fc8e23d..5c508a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-03-31  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S (MFVSRD_R3_V1):
+	Encode instruction correctly in little endian.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S (MFVSRD_R3_V1):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S (MFVSRD_R3_V1):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S (MFVSRD_R3_V1):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S (MFVSRD_R3_V1):
+	Likewise.
+
 2014-03-20  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 	    Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
index 8e5de27..2b27e7b 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
@@ -17,9 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <endian.h>
 #include <math_ldbl_opt.h>
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MFVSRD_R3_V1  .byte 0x66,0x00,0x23,0x7c     /* mfvsrd  r3,vs1  */
+#else
 #define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+#endif
 
 /* int [r3] __finite ([fp1] x)  */
 
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
index 0e92af8..d09b7fc 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
@@ -17,9 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <endian.h>
 #include <math_ldbl_opt.h>
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MFVSRD_R3_V1  .byte 0x66,0x00,0x23,0x7c     /* mfvsrd  r3,vs1  */
+#else
 #define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+#endif
 
 /* int [r3] __isinf([fp1] x)  */
 
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
index c1ca9a5..b03c896 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
@@ -17,9 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <endian.h>
 #include <math_ldbl_opt.h>
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MFVSRD_R3_V1  .byte 0x66,0x00,0x23,0x7c     /* mfvsrd  r3,vs1  */
+#else
 #define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+#endif
 
 /* int [r3] __isnan([f1] x)  */
 
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
index 476d76b..9a55d93 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
@@ -17,9 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <endian.h>
 #include <math_ldbl_opt.h>
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MFVSRD_R3_V1  .byte 0x66,0x00,0x23,0x7c     /* mfvsrd  r3,vs1  */
+#else
 #define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+#endif
 
 /* long long int[r3] __llrint (double x[fp1])  */
 ENTRY (__llrint)
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
index b00d4d6..f10c06a 100644
--- a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
@@ -17,9 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include <endian.h>
 #include <math_ldbl_opt.h>
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MFVSRD_R3_V1  .byte 0x66,0x00,0x23,0x7c     /* mfvsrd  r3,vs1  */
+#else
 #define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+#endif
 
 /* long long [r3] llround (float x [fp1])  */
 

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=62caa3eed2a154a61a01df3a5f3dde3ff400f4d4

commit 62caa3eed2a154a61a01df3a5f3dde3ff400f4d4
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu Mar 20 15:28:07 2014 -0500

    PowerPC: optimized strpbrk for POWER7
    
    This patch add an optimized strpbrk for POWER7 by using a different
    algorithm than default implementation: it constructs a table based on
    the 'accept' argument and use this table to check for any occurance on
    the input string. The idea is similar as x86_64 uses.
    For PowerPC some tunings were added, such as unroll loops and memory
    clear using VSX instructions.
    
    Backport of 6f23d0939e9651d8ac3c77a835fb6464b35a1dc4

diff --git a/ChangeLog b/ChangeLog
index 35d4aee..fc8e23d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,21 @@
 2014-03-20  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+	    Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+
+	* string/strpbrk.c (strpbrk): Using macro to redefine symbol name.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strpbrk-power7
+	and strpbrk-ppc64 objects.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+	(__libc_ifunc_impl_list): Add new strpbrk optimized symbols.
+	* sysdeps/powerpc/powerpc64/multiarch/strpbrk-power7.S: New file:
+	multiarch strpbrk for POWER7.
+	* sysdeps/powerpc/powerpc64/multiarch/strpbrk-ppc64.c: New file:
+	multiarch strpbrk for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strpbrk.c: New file: strpbrk
+	ifunc selector.
+	* sysdeps/powerpc/powerpc64/power7/strpbrk.S: New file: optimited
+	strpbrk for POWER7.
+
+2014-03-20  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* string/strcspn.c (strcspn): Using macro to redefine symbol name.
 	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcspn-power7
diff --git a/string/strpbrk.c b/string/strpbrk.c
index ce33b68..a694242 100644
--- a/string/strpbrk.c
+++ b/string/strpbrk.c
@@ -15,21 +15,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || defined HAVE_CONFIG_H
-# include <string.h>
-#endif
+#include <string.h>
 
 #undef strpbrk
 
+#ifndef STRPBRK
+#define STRPBRK strpbrk
+#endif
+
 /* Find the first occurrence in S of any character in ACCEPT.  */
 char *
-strpbrk (s, accept)
-     const char *s;
-     const char *accept;
+STRPBRK (const char *s, const char *accept)
 {
   while (*s != '\0')
     {
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index c314e6f..8d367aa 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -15,7 +15,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   wordcopy-power7 wordcopy-power6 wordcopy-ppc64 \
 		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
 		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
-		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64
+		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64 \
+		   strpbrk-power7 strpbrk-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 328b87e..91fabb0 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -270,5 +270,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcspn, 1,
 			     __strcspn_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strpbrk.c.  */
+  IFUNC_IMPL (i, name, strpbrk,
+	      IFUNC_IMPL_ADD (array, i, strpbrk,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strpbrk_power7)
+	      IFUNC_IMPL_ADD (array, i, strpbrk, 1,
+			     __strpbrk_ppc))
+
   return i;
 }
diff --git a/string/strpbrk.c b/sysdeps/powerpc/powerpc64/multiarch/strpbrk-power7.S
similarity index 53%
copy from string/strpbrk.c
copy to sysdeps/powerpc/powerpc64/multiarch/strpbrk-power7.S
index ce33b68..663ca36 100644
--- a/string/strpbrk.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strpbrk-power7.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Optimized strpbrk implementation for POWER7.
+   Copyright (C) 2014 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
@@ -15,31 +16,25 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || defined HAVE_CONFIG_H
-# include <string.h>
-#endif
-
-#undef strpbrk
-
-/* Find the first occurrence in S of any character in ACCEPT.  */
-char *
-strpbrk (s, accept)
-     const char *s;
-     const char *accept;
-{
-  while (*s != '\0')
-    {
-      const char *a = accept;
-      while (*a != '\0')
-	if (*a++ == *s)
-	  return (char *) s;
-      ++s;
-    }
-
-  return NULL;
-}
-libc_hidden_builtin_def (strpbrk)
+#include <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strpbrk_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strpbrk_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strpbrk_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strpbrk_power7)					\
+  END_2(__strpbrk_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#include <sysdeps/powerpc/powerpc64/power7/strpbrk.S>
diff --git a/string/strpbrk.c b/sysdeps/powerpc/powerpc64/multiarch/strpbrk-ppc64.c
similarity index 53%
copy from string/strpbrk.c
copy to sysdeps/powerpc/powerpc64/multiarch/strpbrk-ppc64.c
index ce33b68..8dea70e 100644
--- a/string/strpbrk.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strpbrk-ppc64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -8,38 +8,23 @@
 
    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
+   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/>.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <string.h>
+
+#define STRPBRK __strpbrk_ppc
+#ifdef SHARED
 
-#if defined _LIBC || defined HAVE_CONFIG_H
-# include <string.h>
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1 (__strpbrk_ppc, __GI_strpbrk, __strpbrk_ppc);
 #endif
 
-#undef strpbrk
-
-/* Find the first occurrence in S of any character in ACCEPT.  */
-char *
-strpbrk (s, accept)
-     const char *s;
-     const char *accept;
-{
-  while (*s != '\0')
-    {
-      const char *a = accept;
-      while (*a != '\0')
-	if (*a++ == *s)
-	  return (char *) s;
-      ++s;
-    }
-
-  return NULL;
-}
-libc_hidden_builtin_def (strpbrk)
+extern __typeof (strpbrk) __strpbrk_ppc attribute_hidden;
+
+#include <string/strpbrk.c>
diff --git a/string/strpbrk.c b/sysdeps/powerpc/powerpc64/multiarch/strpbrk.c
similarity index 60%
copy from string/strpbrk.c
copy to sysdeps/powerpc/powerpc64/multiarch/strpbrk.c
index ce33b68..8b05536 100644
--- a/string/strpbrk.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strpbrk.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Multiple versions of strpbrk. PowerPC64 version.
+   Copyright (C) 2014 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
@@ -15,31 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || defined HAVE_CONFIG_H
+#ifndef NOT_IN_libc
 # include <string.h>
-#endif
+# include <shlib-compat.h>
+# include "init-arch.h"
 
-#undef strpbrk
+extern __typeof (strpbrk) __strpbrk_ppc attribute_hidden;
+extern __typeof (strpbrk) __strpbrk_power7 attribute_hidden;
 
-/* Find the first occurrence in S of any character in ACCEPT.  */
-char *
-strpbrk (s, accept)
-     const char *s;
-     const char *accept;
-{
-  while (*s != '\0')
-    {
-      const char *a = accept;
-      while (*a != '\0')
-	if (*a++ == *s)
-	  return (char *) s;
-      ++s;
-    }
-
-  return NULL;
-}
-libc_hidden_builtin_def (strpbrk)
+libc_ifunc (strpbrk,
+	    (hwcap & PPC_FEATURE_HAS_VSX)
+	    ? __strpbrk_power7
+	    : __strpbrk_ppc);
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strpbrk.S b/sysdeps/powerpc/powerpc64/power7/strpbrk.S
new file mode 100644
index 0000000..d6204a7
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strpbrk.S
@@ -0,0 +1,148 @@
+/* Optimized strpbrk implementation for PowerPC64/POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+/* char [r3] *strpbrk(const char [r4] *s, const char [r5] *accept)  */
+
+	.machine power7
+EALIGN (strpbrk, 4, 0)
+	CALL_MCOUNT 3
+
+	lbz	r10,0(r4)
+	cmpdi	cr7,r10,0	/* accept[0] == '\0' ?  */
+	beq	cr7,L(nullfound)
+
+	/* The idea to speed up the algorithm is to create a lookup table
+	   for fast check if input character should be considered.  For ASCII
+	   or ISO-8859-X character sets it has 256 positions.  */
+
+	/* First the table should be cleared and to avoid unaligned accesses
+	   when using the VSX stores the table address is aligned to 16
+	   bytes.  */
+	xxlxor	v0,v0,v0
+
+	/* PPC64 ELF ABI stack is aligned to 16 bytes  */
+	addi 	r9,r1,-256
+
+	li	r5,16
+	li	r6,32
+	li	r8,48
+	addi	r12,r9,64
+	/* Clear the table with 0 values  */
+	stxvw4x v0,r0,r9
+	addi	r11,r9,128
+	addi	r7,r9,192
+	stxvw4x	v0,r9,r5
+	li	r0,1
+	stxvw4x v0,r9,r6
+	stxvw4x v0,r9,r8
+	stxvw4x v0,r0,r12
+	stxvw4x v0,r12,r5
+	stxvw4x v0,r12,r6
+	stxvw4x v0,r12,r8
+	stxvw4x v0,r0,r11
+	stxvw4x v0,r11,r5
+	stxvw4x v0,r11,r6
+	stxvw4x v0,r11,r8
+	stxvw4x v0,r0,r7
+	stxvw4x v0,r7,r5
+	stxvw4x v0,r7,r6
+	stxvw4x v0,r7,r8
+
+	/* Initialize the table as:
+	   for (i=0; accept[i]; i++
+	     table[accept[i]]] = 1  */
+	.p2align 4,,15
+L(init_table):
+	stbx	r0,r9,r10
+	lbzu	r10,1(r4)
+	cmpdi	r0,r10,0
+	bne	cr0,L(init_table)
+L(finish_table):
+	/* set table[0] = 1  */
+	li	r4,1
+	stb	r4,0(r9)
+	b	L(mainloop)
+
+	/* Unrool the loop 4 times and check using the table as:
+	   i = 0;
+	   while (1)
+	     {
+	       if (table[input[i++]] == 1)
+	         return (s[i -1] ? s + i - 1: NULL);
+	       if (table[input[i++]] == 1)
+	         return (s[i -1] ? s + i - 1: NULL);
+	       if (table[input[i++]] == 1)
+	         return (s[i -1] ? s + i - 1: NULL);
+	       if (table[input[i++]] == 1)
+	         return (s[i -1] ? s + i - 1: NULL);
+	     }  */
+	.p2align 4
+L(unroll):
+	lbz	r0,1(r3)
+	lbzx	r8,r9,r0
+	cmpwi	cr6,r8,1
+	beq	cr6,L(checkend2)
+	lbz	r10,2(r3)
+	lbzx	r4,r9,r10
+	cmpwi	cr7,r4,1
+	beq	cr7,L(checkend3)
+	lbz	r12,3(r3)
+	addi	r3,r3,4
+	lbzx	r11,r9,r12
+	cmpwi	cr0,r11,1
+	beq	cr0,L(checkend)
+L(mainloop):
+	lbz	r12,0(r3)
+	addi	r11,r3,1
+	addi	r5,r3,2
+	addi	r7,r3,3
+	lbzx	r6,r9,r12
+	cmpwi	cr1,r6,1
+	bne	cr1,L(unroll)
+	cmpdi	cr0,r12,0
+	beq	cr0,L(nullfound)
+L(end):
+	blr
+
+	.p2align 4
+L(checkend):
+	cmpdi	cr1,r12,0
+	mr	r3,r7
+	bne	cr1,L(end)
+L(nullfound):
+	/* return NULL  */
+	li 3,0
+	blr
+
+	.p2align 4
+L(checkend2):
+	cmpdi	cr7,r0,0
+	mr	r3,r11
+	beq	cr7,L(nullfound)
+	blr
+
+	.p2align 4
+L(checkend3):
+	cmpdi	cr6,r10,0
+	mr	r3,r5
+	beq	cr6,L(nullfound)
+	blr
+END (strpbrk)
+libc_hidden_builtin_def (strpbrk)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c0afc58657f482f4c31ccade06e7b059e761186c

commit c0afc58657f482f4c31ccade06e7b059e761186c
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu Mar 20 11:24:52 2014 -0500

    PowerPC: optimized strcspn for PPC64/POWER7
    
    This patch add a optimized strcspn for POWER7 by using a different
    algorithm than default implementation: it constructs a table based on
    the 'accept' argument and use this table to check for any occurance
    on the input string. The idea is similar as x86_64 uses.
    For PowerPC some tunings were added, such as unroll loops and align
    stack memory to table to 16 bytes (so VSX clean can ran without
    alignment issues).
    
    Backport of 6eaf95cbfa0031ea267682dc2c9c17ed3e3dc167

diff --git a/ChangeLog b/ChangeLog
index fdfff77..35d4aee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2014-03-20  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* string/strcspn.c (strcspn): Using macro to redefine symbol name.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcspn-power7
+	and strcspn-ppc64 objects.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+	(__libc_ifunc_impl_list): Add new strcspn optimized symbols.
+	* sysdeps/powerpc/powerpc64/multiarch/strcspn-power7.S: New file:
+	multiarch strcspn for POWER7.
+	* sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c: New file:
+	multiarch strcspn for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strcspn.c: New file: strcspn
+	ifunc selector.
+	* sysdeps/powerpc/powerpc64/power7/strcspn.S: New file: optimited
+	strcspn for POWER7.
+
 2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #16707]
diff --git a/string/strcspn.c b/string/strcspn.c
index 7c39f79..4316205 100644
--- a/string/strcspn.c
+++ b/string/strcspn.c
@@ -15,27 +15,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-# ifndef strchr
-#  define strchr index
-# endif
-#endif
+#include <string.h>
 
 #undef strcspn
 
+#ifndef STRCSPN
+# define STRCSPN strcspn
+#endif
+
 /* Return the length of the maximum initial segment of S
    which contains no characters from REJECT.  */
 size_t
-strcspn (s, reject)
-     const char *s;
-     const char *reject;
+STRCSPN (const char *s, const char *reject)
 {
   size_t count = 0;
 
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 3e8010c..c314e6f 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -15,7 +15,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   wordcopy-power7 wordcopy-power6 wordcopy-ppc64 \
 		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
 		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
-		   strspn-power7 strspn-ppc64
+		   strspn-power7 strspn-ppc64 strcspn-power7 strcspn-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 20d7918..328b87e 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -262,5 +262,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strspn, 1,
 			      __strspn_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strcspn.c.  */
+  IFUNC_IMPL (i, name, strcspn,
+	      IFUNC_IMPL_ADD (array, i, strcspn,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strcspn_power7)
+	      IFUNC_IMPL_ADD (array, i, strcspn, 1,
+			     __strcspn_ppc))
+
   return i;
 }
diff --git a/string/strcspn.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn-power7.S
similarity index 53%
copy from string/strcspn.c
copy to sysdeps/powerpc/powerpc64/multiarch/strcspn-power7.S
index 7c39f79..02ffcc8 100644
--- a/string/strcspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn-power7.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Optimized strcspn implementation for POWER7.
+   Copyright (C) 2014 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
@@ -15,36 +16,25 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-# ifndef strchr
-#  define strchr index
-# endif
-#endif
-
-#undef strcspn
-
-/* Return the length of the maximum initial segment of S
-   which contains no characters from REJECT.  */
-size_t
-strcspn (s, reject)
-     const char *s;
-     const char *reject;
-{
-  size_t count = 0;
-
-  while (*s != '\0')
-    if (strchr (reject, *s++) == NULL)
-      ++count;
-    else
-      return count;
-
-  return count;
-}
-libc_hidden_builtin_def (strcspn)
+#include <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strcspn_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strcspn_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strcspn_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strcspn_power7)					\
+  END_2(__strcspn_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#include <sysdeps/powerpc/powerpc64/power7/strcspn.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c
new file mode 100644
index 0000000..5f8b610
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn-ppc64.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2014 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 <string.h>
+
+#define STRCSPN __strcspn_ppc
+#ifdef SHARED
+
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1 (__strcspn_ppc, __GI_strcspn, __strcspn_ppc);
+#endif
+
+extern __typeof (strcspn) __strcspn_ppc attribute_hidden;
+
+#include <string/strcspn.c>
diff --git a/string/strcspn.c b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c
similarity index 56%
copy from string/strcspn.c
copy to sysdeps/powerpc/powerpc64/multiarch/strcspn.c
index 7c39f79..3609d93 100644
--- a/string/strcspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcspn.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Multiple versions of strcspn. PowerPC64 version.
+   Copyright (C) 2014 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
@@ -15,36 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined _LIBC || HAVE_STRING_H
+#ifndef NOT_IN_libc
 # include <string.h>
-#else
-# include <strings.h>
-# ifndef strchr
-#  define strchr index
-# endif
-#endif
+# include <shlib-compat.h>
+# include "init-arch.h"
 
-#undef strcspn
+extern __typeof (strcspn) __strcspn_ppc attribute_hidden;
+extern __typeof (strcspn) __strcspn_power7 attribute_hidden;
 
-/* Return the length of the maximum initial segment of S
-   which contains no characters from REJECT.  */
-size_t
-strcspn (s, reject)
-     const char *s;
-     const char *reject;
-{
-  size_t count = 0;
-
-  while (*s != '\0')
-    if (strchr (reject, *s++) == NULL)
-      ++count;
-    else
-      return count;
-
-  return count;
-}
-libc_hidden_builtin_def (strcspn)
+libc_ifunc (strcspn,
+	    (hwcap & PPC_FEATURE_HAS_VSX)
+	    ? __strcspn_power7
+	    : __strcspn_ppc);
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strcspn.S b/sysdeps/powerpc/powerpc64/power7/strcspn.S
new file mode 100644
index 0000000..3f6aa0a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strcspn.S
@@ -0,0 +1,139 @@
+/* Optimized strcspn implementation for PowerPC64.
+   Copyright (C) 2014 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 <sysdep.h>
+
+/* size_t [r3] strcspn (const char [r4] *s, const char [r5] *reject)  */
+
+	.machine power7
+EALIGN (strcspn, 4, 0)
+	CALL_MCOUNT 3
+
+	/* The idea to speed up the algorithm is to create a lookup table
+	   for fast check if input character should be considered.  For ASCII
+	   or ISO-8859-X character sets it has 256 positions.  */
+	lbz	r10,0(r4)
+
+	/* First the table should be cleared and to avoid unaligned accesses
+	   when using the VSX stores the table address is aligned to 16
+	   bytes.  */
+	xxlxor	v0,v0,v0
+
+	/* PPC64 ELF ABI stack is aligned to 16 bytes.  */
+	addi 	r9,r1,-256
+
+	li	r8,48
+	li	r5,16
+	li	r6,32
+	cmpdi	cr7,r10,0	/* reject[0] == '\0' ?  */
+	addi	r12,r9,64
+	/* Clear the table with 0 values  */
+	stxvw4x	v0,r0,r9
+	addi	r11,r9,128
+	addi	r7,r9,192
+	stxvw4x v0,r9,r5
+	stxvw4x v0,r9,r6
+	stxvw4x v0,r9,r8
+	stxvw4x v0,r0,r12
+	stxvw4x v0,r12,r5
+	stxvw4x v0,r12,r6
+	stxvw4x v0,r12,r8
+	stxvw4x v0,r0,r11
+	stxvw4x v0,r11,r5
+	stxvw4x v0,r11,r6
+	stxvw4x v0,r11,r8
+	stxvw4x v0,r0,r7
+	stxvw4x v0,r7,r5
+	stxvw4x v0,r7,r6
+	stxvw4x v0,r7,r8
+	li	r8,1
+	beq     cr7,L(finish_table)  /* If reject[0] == '\0' skip  */
+
+	/* Initialize the table as:
+	   for (i=0; reject[i]; i++
+	     table[reject[i]]] = 1  */
+	.p2align 4,,15
+L(init_table):
+	stbx	r8,r9,r10
+	lbzu	r10,1(r4)
+	cmpdi	cr7,r10,0           /* If reject[0] == '\0' finish  */
+	bne	cr7,L(init_table)
+L(finish_table):
+	/* set table[0] = 1  */
+	li 	r10,1
+	stb	r10,0(r9)
+	li	r10,0
+	b	L(mainloop)
+
+	/* Unrool the loop 4 times and check using the table as:
+	   i = 0;
+	   while (1)
+	     {
+	       if (table[input[i++]] == 1)
+	         return i - 1;
+	       if (table[input[i++]] == 1)
+	         return i - 1;
+	       if (table[input[i++]] == 1)
+	         return i - 1;
+	       if (table[input[i++]] == 1)
+	         return i - 1;
+	     }  */
+	.p2align 4,,15
+L(unroll):
+	lbz	r8,1(r3)
+	addi	r10,r10,4
+	lbzx	r8,r9,r8
+	cmpwi	r7,r8,1
+	beq	cr7,L(end)
+	lbz	r8,2(r3)
+	addi	r3,r3,4
+	lbzx	r8,r9,r8
+	cmpwi	cr7,r8,1
+	beq	cr7,L(end2)
+	lbz	r8,3(r7)
+	lbzx	r8,r9,r8
+	cmpwi	cr7,r8,1
+	beq	cr7,L(end3)
+L(mainloop):
+	lbz	r8,0(r3)
+	mr	r7,r3
+	addi	r6,r10,1
+	addi	r4,r10,2
+	addi	r5,r10,3
+	lbzx	r8,r9,8
+	cmpwi	cr7,r8,1
+	bne	cr7,L(unroll)
+	mr	r3,r10
+	blr
+
+	.p2align 4,,15
+L(end):
+	mr	r3,r6
+	blr
+
+	.p2align 4,,15
+L(end2):
+	mr	r3,r4
+	blr
+
+	.p2align 4,,15
+L(end3):
+	mr	r3,r5
+	blr
+END (strcspn)
+libc_hidden_builtin_def (strcspn)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ac6d8452be2d582e4a2b14525c839c71b9351991

commit ac6d8452be2d582e4a2b14525c839c71b9351991
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Mar 14 12:49:45 2014 -0500

    PowerPC: remove wrong roundl implementation for PowerPC64
    
    The roundl assembly implementation
    (sysdeps/powerpc/powerpc64/fpu/s_roundl.S)
    returns wrong results for some inputs where first double is a exact
    integer and the precision is determined by second long double.
    
    Checking on implementation comments and history, I am very confident the
    assembly implementation was based on a version before commit
    5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in
    long double (ldbl-128ibm) rounding functions in glibc-2.4).
    
    By just removing the implementation and make the build select
    sysdeps/ieee754/ldbl-128ibm/s_roundl.c instead fixes the failing math.
    
    This fixes 16707.
    
    Backport of c7de50250367167d8c9f35594b264f6a0af8dd0c

diff --git a/ChangeLog b/ChangeLog
index 04b3366..fdfff77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	[BZ #16707]
+	* sysdeps/powerpc/powerpc64/fpu/s_roundl.S: Remove wrong
+	implementation.
+	* math/libm-test.inc (round_test_data): Add more tests.
+
+2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	[BZ #16706]
 	* sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S: Remove wrong
 	implementation.
diff --git a/NEWS b/NEWS
index 96a2285..a647e5d 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706.
+  16545, 16683, 16689, 16701, 16706, 16707.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index eb28373..1c9b97a 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -11803,6 +11803,15 @@ static const struct test_f_f_data round_test_data[] =
     TEST_f_f (round, -72057594037927936.75L, -72057594037927937.0L),
     TEST_f_f (round, -72057594037927937.5L, -72057594037927938.0L),
 
+    /* Check cases where first double is a exact integer higher than 2^52 and
+       the precision is determined by second long double for IBM long double.  */
+    TEST_f_f (round,  34503599627370498.515625L, 34503599627370499.0L),
+    TEST_f_f (round, -34503599627370498.515625L, -34503599627370499.0L),
+# if LDBL_MANT_DIG >= 106
+    TEST_f_f (round,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
+    TEST_f_f (round, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+
     TEST_f_f (round, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L),
     TEST_f_f (round, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L),
     TEST_f_f (round, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L),
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_roundl.S b/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
deleted file mode 100644
index 5362da8..0000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_roundl.S
+++ /dev/null
@@ -1,132 +0,0 @@
-/* long double round function.
-   IBM extended format long double version.
-   Copyright (C) 2004-2014 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 <sysdep.h>
-#include <math_ldbl_opt.h>
-
-	.section	".toc","aw"
-.LC0:	/* 2**52 */
-	.tc FD_43300000_0[TC],0x4330000000000000
-.LC1:	/* 0.5 */
-	.tc FD_3fe00000_0[TC],0x3fe0000000000000
-	.section	".text"
-
-/* long double [fp1,fp2] roundl (long double x [fp1,fp2])
-   IEEE 1003.1 round function.  IEEE specifies "round to the nearest
-   integer value, rounding halfway cases away from zero, regardless of
-   the current rounding mode."  However PowerPC Architecture defines
-   "Round to Nearest" as "Choose the best approximation. In case of a
-   tie, choose the one that is even (least significant bit o).".
-   So we can't use the PowerPC "Round to Nearest" mode. Instead we set
-   "Round toward Zero" mode and round by adding +-0.5 before rounding
-   to the integer value.  */
-
-ENTRY (__roundl)
-	mffs	fp11		/* Save current FPU rounding mode.  */
-	lfd	fp13,.LC0@toc(2)
-	fabs	fp0,fp1
-	fabs	fp9,fp2
-	fsub	fp12,fp13,fp13	/* generate 0.0  */
-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
-	bnl-	cr7,.L2
-	mtfsfi	7,1		/* Set rounding mode toward 0.  */
-	lfd	fp10,.LC1@toc(2)
-	ble-	cr6,.L1
-	fneg	fp2,fp12
-	fadd	fp1,fp1,fp10	/* x+= 0.5;  */
-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	fabs	fp1,fp1		/* if (x == 0.0) x = 0.0;  */
-.L0:
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	blr
-.L1:
-	fsub	fp9,fp1,fp10	/* x-= 0.5;  */
-	fneg	fp2,fp12
-	bge-	cr6,.L0		/* if (x < 0.0)  */
-	fsub	fp1,fp9,fp13	/* x-= TWO52;  */
-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fnabs	fp1,fp1		/* if (x == 0.0) x = -0.0;  */
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	blr
-
-/* The high double is > TWO52 so we need to round the low double and
-   perhaps the high double.  In this case we have to round the low
-   double and handle any adjustment to the high double that may be
-   caused by rounding (up).  This is complicated by the fact that the
-   high double may already be rounded and the low double may have the
-   opposite sign to compensate.This gets a bit tricky so we use the
-   following algorithm:
-
-   tau = floor(x_high/TWO52);
-   x0 = x_high - tau;
-   x1 = x_low + tau;
-   r1 = rint(x1);
-   y_high = x0 + r1;
-   y_low = x0 - y_high + r1;
-   return y;  */
-.L2:
-	fcmpu	cr7,fp9,fp13	/* if (|x_low| > TWO52)  */
-	fcmpu	cr0,fp9,fp12	/* || (|x_low| == 0.0)  */
-	fcmpu	cr5,fp2,fp12	/* if (x_low > 0.0)  */
-	lfd	fp10,.LC1@toc(2)
-	bgelr-	cr7		/*   return x;	*/
-	beqlr-  cr0
-	mtfsfi	7,1		/* Set rounding mode toward 0.  */
-	fdiv	fp8,fp1,fp13	/* x_high/TWO52  */
-
-	bng-	cr6,.L6		/* if (x > 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	bng	cr5,.L4		/* if (x_low > 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L5
-.L4:				/* if (x_low < 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L5:
-	fadd	fp5,fp4,fp10	/* r1 = x1 + 0.5;  */
-	fadd	fp5,fp5,fp13	/* r1 = r1 + TWO52;  */
-	fsub	fp5,fp5,fp13	/* r1 = r1 - TWO52;  */
-	b	.L9
-.L6:				/* if (x < 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	bnl	cr5,.L7		/* if (x_low < 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L8
-.L7:				/* if (x_low > 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L8:
-	fsub	fp5,fp4,fp10	/* r1 = x1 - 0.5;  */
-	fsub	fp5,fp5,fp13	/* r1-= TWO52;  */
-	fadd	fp5,fp5,fp13	/* r1+= TWO52;  */
-.L9:
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	fadd	fp1,fp3,fp5	/* y_high = x0 + r1;  */
-	fsub	fp2,fp3,fp1	/* y_low = x0 - y_high + r1;  */
-	fadd	fp2,fp2,fp5
-	blr
-END (__roundl)
-
-long_double_symbol (libm, __roundl, roundl)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c5ac422010eb6b384c3b4e45ab0049172f0ad688

commit c5ac422010eb6b384c3b4e45ab0049172f0ad688
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Mar 14 12:27:52 2014 -0500

    PowerPC: remove wrong nearbyintl implementation for PPC64
    
    The nearbyintl assembly implementation
    (sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S)
    returns wrong results for some inputs where first double is a exact
    integer and the precision is determined by second long double.
    
    Checking on implementation comments and history, I am very confident the
    assembly implementation was based on a version before commit
    5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in
    long double (ldbl-128ibm) rounding functions in glibc-2.4).
    
    By just removing the implementation and make the build select
    sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c instead fixes the failing
    math.
    
    Fixes BZ#16706.
    
    Backport of 98fb27a373f37554232e0060eef1a5bb00a07eb0

diff --git a/ChangeLog b/ChangeLog
index 1f526cd..04b3366 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	[BZ #16706]
+	* sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S: Remove wrong
+	implementation.
+	* math/libm-test.inc (nearbyint_test_data): Add more tests.
+
+2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	[BZ #16701]
 	* sysdeps/powerpc/powerpc64/fpu/s_ceill.S: Remove wrong
 	implementation.
diff --git a/NEWS b/NEWS
index a62e2a8..96a2285 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701.
+  16545, 16683, 16689, 16701, 16706.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 1ee1f3b..eb28373 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -10504,6 +10504,16 @@ static const struct test_f_f_data nearbyint_test_data[] =
     TEST_f_f (nearbyint, -562949953421312.75, -562949953421313.0, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint, -1125899906842624.75, -1125899906842625.0, NO_INEXACT_EXCEPTION),
 #endif
+#ifdef TEST_LDOUBLE
+    /* Check cases where first double is a exact integer higher than 2^52 and
+       the precision is determined by second long double for IBM long double.  */
+    TEST_f_f (nearbyint,  34503599627370498.515625L, 34503599627370499.0L),
+    TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L),
+# if LDBL_MANT_DIG >= 106
+    TEST_f_f (nearbyint,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
+    TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+#endif
   };
 
 static void
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S b/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
deleted file mode 100644
index acd95da..0000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_nearbyintl.S
+++ /dev/null
@@ -1,113 +0,0 @@
-/* nearbyint long double.
-   IBM extended format long double version.
-   Copyright (C) 2004-2014 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 <sysdep.h>
-#include <math_ldbl_opt.h>
-
-	.section	".toc","aw"
-.LC0:	/* 2**52 */
-	.tc FD_43300000_0[TC],0x4330000000000000
-	.section	".text"
-
-/* long double [fp1,fp2] nearbyintl (long double x [fp1,fp2])
-   IEEE 1003.1 nearbyintl function.  nearbyintl is similar to the rintl
-   but does raise the "inexact" exception.  This implementation is
-   based on rintl but explicitly masks the inexact exception on entry
-   and clears any pending inexact before restoring the exception mask
-   on exit.
-
-   PowerPC64 long double uses the IBM extended format which is
-   represented two 64-floating point double values. The values are
-   non-overlapping giving an effective precision of 106 bits. The first
-   double contains the high order bits of mantissa and is always rounded
-   to represent a normal rounding of long double to double. Since the
-   long double value is sum of the high and low values, the low double
-   normally has the opposite sign to compensate for the this rounding.
-
-   For long double there are two cases:
-   1) |x| < 2**52, all the integer bits are in the high double.
-      floor the high double and set the low double to -0.0.
-   2) |x| >= 2**52, Rounding involves both doubles.
-      See the comment before label .L2 for details.
-   */
-ENTRY (__nearbyintl)
-	mffs	fp11		/* Save current FPSCR.  */
-	lfd	fp13,.LC0@toc(2)
-	fabs	fp0,fp1
-	mtfsb0  28		/* Disable "inexact" exceptions.  */
-	fsub	fp12,fp13,fp13	/* generate 0.0  */
-	fabs	fp9,fp2
-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
-	bnl-	cr7,.L2
-	fmr	fp2,fp12
-	bng-	cr6,.L4
-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	b	.L9
-.L4:
-	bnl-	cr6,.L9		/* if (x < 0.0)  */
-	fsub	fp1,fp13,fp1	/* x = TWO52 - x;  */
-	fsub	fp0,fp1,fp13	/* x = - (x - TWO52);  */
-	fneg	fp1,fp0
-.L9:
-	mtfsb0	6		/* Clear any pending "inexact" exceptions.  */
-	mtfsf	0x01,fp11	/* restore exception mask.  */
-	blr
-
-/* The high double is > TWO52 so we need to round the low double and
-   perhaps the high double.  This gets a bit tricky so we use the
-   following algorithm:
-
-   tau = floor(x_high/TWO52);
-   x0 = x_high - tau;
-   x1 = x_low + tau;
-   r1 = nearbyint(x1);
-   y_high = x0 + r1;
-   y_low = r1 - tau;
-   return y;  */
-.L2:
-	fcmpu	cr7,fp9,fp13	/* if (|x_low| > TWO52)  */
-	fcmpu	cr0,fp9,fp12	/* || (|x_low| == 0.0)  */
-	bge-	cr7,.L9		/*   return x;	*/
-	beq-  cr0,.L9
-	fdiv	fp8,fp1,fp13	/* x_high/TWO52  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-
-	fcmpu	cr6,fp4,fp12	/* if (x1 > 0.0)  */
-	bng-	cr6,.L8
-	fadd	fp5,fp4,fp13	/* r1 = x1 + TWO52;  */
-	fsub	fp5,fp5,fp13	/* r1 = r1 - TWO52;  */
-	b	.L6
-.L8:
-	fmr	fp5,fp4
-	bge-	cr6,.L6		/* if (x1 < 0.0)  */
-	fsub	fp5,fp13,fp4	/* r1 = TWO52 - x1;  */
-	fsub	fp0,fp5,fp13	/* r1 = - (r1 - TWO52);  */
-	fneg	fp5,fp0
-.L6:
-	fadd	fp1,fp3,fp5	/* y_high = x0 + r1;  */
-	fsub	fp2,fp5,fp8	/* y_low = r1 - tau;  */
-	b	.L9
-END (__nearbyintl)
-
-long_double_symbol (libm, __nearbyintl, nearbyintl)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=7986a2d12b7ea0653f0366200c703a3905edffd9

commit 7986a2d12b7ea0653f0366200c703a3905edffd9
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Mar 14 07:35:43 2014 -0500

    PowerPC: remove wrong ceill implementation for PowerPC64
    
    The ceill assembly implementation (sysdeps/powerpc/powerpc64/fpu/s_ceill.S)
    returns wrong results for some inputs where first double is a exact
    integer and the precision is determined by second long double.
    
    Checking on implementation comments and history, I am very confident the
    assembly implementation was based on a version before commit
    5c68d401698a58cf7da150d9cce769fa6679ba5f that fixes BZ#2423 (Errors in
    long double (ldbl-128ibm) rounding functions in glibc-2.4).
    
    By just removing the implementation and make the build select
    sysdeps/ieee754/ldbl-128ibm/s_ceill.c instead fixes the failing math.
    
    Fixes BZ#16701.
    
    Backport of 374f7f61214967bb4e2257695aeeeecc2a77f369

diff --git a/ChangeLog b/ChangeLog
index 4919f18..1f526cd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	[BZ #16701]
+	* sysdeps/powerpc/powerpc64/fpu/s_ceill.S: Remove wrong
+	implementation.
+	* math/libm-test.inc (ceil_test_data): Add more tests.
+
+2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* math/libm-test.inc (trunc_test_data): Add more tests related to
 	BZ#16414.
 
diff --git a/NEWS b/NEWS
index 886624a..a62e2a8 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689.
+  16545, 16683, 16689, 16701.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index f8aca46..1ee1f3b 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -6000,6 +6000,15 @@ static const struct test_f_f_data ceil_test_data[] =
     TEST_f_f (ceil, -72057594037927936.75L, -72057594037927936.0L),
     TEST_f_f (ceil, -72057594037927937.5L, -72057594037927937.0L),
 
+    /* Check cases where first double is a exact integer higher than 2^52 and
+       the precision is determined by second long double for IBM long double.  */
+    TEST_f_f (ceil,  34503599627370498.515625L, 34503599627370499.0L),
+    TEST_f_f (ceil, -34503599627370498.515625L, -34503599627370498.0L),
+# if LDBL_MANT_DIG >= 106
+    TEST_f_f (ceil,  1192568192774434123539907640624.484375L, 1192568192774434123539907640625.0L),
+    TEST_f_f (ceil, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+
     TEST_f_f (ceil, 10141204801825835211973625643007.5L, 10141204801825835211973625643008.0L),
     TEST_f_f (ceil, 10141204801825835211973625643008.25L, 10141204801825835211973625643009.0L),
     TEST_f_f (ceil, 10141204801825835211973625643008.5L, 10141204801825835211973625643009.0L),
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_ceill.S b/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
deleted file mode 100644
index 42a73af..0000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_ceill.S
+++ /dev/null
@@ -1,132 +0,0 @@
-/* s_ceill.S IBM extended format long double version.
-   Copyright (C) 2004-2014 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 <sysdep.h>
-#include <math_ldbl_opt.h>
-
-	.section	".toc","aw"
-.LC0:	/* 2**52 */
-	.tc FD_43300000_0[TC],0x4330000000000000
-
-	.section	".text"
-
-/* long double [fp1,fp2] ceill (long double x [fp1,fp2])
-   IEEE 1003.1 ceil function.
-
-   PowerPC64 long double uses the IBM extended format which is
-   represented two 64-floating point double values. The values are
-   non-overlapping giving an effective precision of 106 bits. The first
-   double contains the high order bits of mantissa and is always ceiled
-   to represent a normal ceiling of long double to double. Since the
-   long double value is sum of the high and low values, the low double
-   normally has the opposite sign to compensate for the this ceiling.
-
-   For long double there are two cases:
-   1) |x| < 2**52, all the integer bits are in the high double.
-      ceil the high double and set the low double to -0.0.
-   2) |x| >= 2**52, ceiling involves both doubles.
-      See the comment before label .L2 for details.
-   */
-
-ENTRY (__ceill)
-	mffs	fp11		/* Save current FPU rounding mode.  */
-	lfd	fp13,.LC0@toc(2)
-	fabs	fp0,fp1
-	fabs	fp9,fp2
-	fsub	fp12,fp13,fp13	/* generate 0.0  */
-	fcmpu	cr7,fp0,fp13	/* if (fabs(x) > TWO52)  */
-	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
-	bnl-	cr7,.L2
-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
-	fneg	fp2,fp12
-	ble-	cr6,.L1
-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	fabs	fp1,fp1		/* if (x == 0.0)  */
-.L0:
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	blr			/* x = 0.0; */
-.L1:
-	bge-	cr6,.L0		/* if (x < 0.0)  */
-	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	fnabs	fp1,fp1		/* if (x == 0.0)  */
-	blr			/* x = -0.0; */
-
-/* The high double is > TWO52 so we need to round the low double and
-   perhaps the high double.  In this case we have to round the low
-   double and handle any adjustment to the high double that may be
-   caused by rounding (up).  This is complicated by the fact that the
-   high double may already be rounded and the low double may have the
-   opposite sign to compensate.This gets a bit tricky so we use the
-   following algorithm:
-
-   tau = floor(x_high/TWO52);
-   x0 = x_high - tau;
-   x1 = x_low + tau;
-   r1 = rint(x1);
-   y_high = x0 + r1;
-   y_low = x0 - y_high + r1;
-   return y;  */
-.L2:
-	fcmpu	cr7,fp9,fp13	/* if (|x_low| > TWO52)  */
-	fcmpu	cr0,fp9,fp12	/* || (|x_low| == 0.0)  */
-	fcmpu	cr5,fp2,fp12	/* if (x_low > 0.0)  */
-	bgelr-	cr7		/*   return x;	*/
-	beqlr-  cr0
-	mtfsfi	7,2		/* Set rounding mode toward +inf.  */
-	fdiv	fp8,fp1,fp13	/* x_high/TWO52  */
-
-	bng-	cr6,.L6		/* if (x > 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	bng	cr5,.L4		/* if (x_low > 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L5
-.L4:				/* if (x_low < 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L5:
-	fadd	fp5,fp4,fp13	/* r1 = r1 + TWO52;  */
-	fsub	fp5,fp5,fp13	/* r1 = r1 - TWO52;  */
-	b	.L9
-.L6:				/* if (x < 0.0)  */
-	fctidz	fp0,fp8
-	fcfid	fp8,fp0		/* tau = floor(x_high/TWO52);  */
-	bnl	cr5,.L7		/* if (x_low < 0.0)  */
-	fmr	fp3,fp1
-	fmr	fp4,fp2
-	b	.L8
-.L7:				/* if (x_low > 0.0)  */
-	fsub	fp3,fp1,fp8	/* x0 = x_high - tau;  */
-	fadd	fp4,fp2,fp8	/* x1 = x_low + tau;  */
-.L8:
-	fsub	fp5,fp4,fp13	/* r1-= TWO52;  */
-	fadd	fp5,fp5,fp13	/* r1+= TWO52;  */
-.L9:
-	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	fadd	fp1,fp3,fp5	/* y_high = x0 + r1;  */
-	fsub	fp2,fp3,fp1	/* y_low = x0 - y_high + r1;  */
-	fadd	fp2,fp2,fp5
-	blr
-END (__ceill)
-
-long_double_symbol (libm, __ceill, ceill)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a56198dbb21767bde0003d3062d5ec7a8e1279f1

commit a56198dbb21767bde0003d3062d5ec7a8e1279f1
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Mar 14 12:15:40 2014 -0500

    Add truncl tests related to BZ#16414
    
    Backport of 4655c291d1808c35b7c54236ae62be7a3aaa0a2d

diff --git a/ChangeLog b/ChangeLog
index 61b22d6..4919f18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-03-14  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* math/libm-test.inc (trunc_test_data): Add more tests related to
+	BZ#16414.
+
 2014-03-12  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #16689]
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 027dfb9..f8aca46 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -12461,6 +12461,15 @@ static const struct test_f_f_data trunc_test_data[] =
     TEST_f_f (trunc, -72057594037927936.75L, -72057594037927936.0L),
     TEST_f_f (trunc, -72057594037927937.5L, -72057594037927937.0L),
 
+    /* Check cases where first double is a exact integer higher than 2^52 and
+       the precision is determined by second long double for IBM long double.  */
+    TEST_f_f (trunc,  34503599627370498.515625L, 34503599627370498.0L),
+    TEST_f_f (trunc, -34503599627370498.515625L, -34503599627370498.0L),
+# if LDBL_MANT_DIG >= 106
+    TEST_f_f (trunc,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
+    TEST_f_f (trunc, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
+# endif
+
     TEST_f_f (trunc, 10141204801825835211973625643007.5L, 10141204801825835211973625643007.0L),
     TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L),
     TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L),

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=a52b3f7e4c4de8705370adda4b390293780dc768

commit a52b3f7e4c4de8705370adda4b390293780dc768
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Wed Mar 12 08:55:50 2014 -0500

    PowerPC: Fix bzero definition for static libc for PPC32
    
    This patch fixes an issue for powerpc32-fpu static build which fails
    with an 'bzero' undefined reference. This patch adds bzero ifunc selector
    for static builds and fixes the '__bzero_ppc' reference to default
    memset symbol (since static memset build does not provide ifunc
    selector).
    
    Fixes BZ#16689.
    
    Backport of dd3946c615184e1957a0cb09352cac72be5d6d5b.

diff --git a/ChangeLog b/ChangeLog
index 93a4ddf..61b22d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2014-03-12  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	[BZ #16689]
+	* sysdeps/powerpc/powerpc32/power4/multiarch/bzero-ppc32.S
+	(__bzero_ppc): Call memset@local instead of __memset_ppc@local for
+	static build.
+	* sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c: Build IFUNC
+	selector for static builds.
+
+2014-03-12  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* sysdeps/powerpc/powerpc64/multiarch/strspn.c (strspn): Build IFUNC
 	selector for static builds.
 
diff --git a/NEWS b/NEWS
index fbd56f6..886624a 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683.
+  16545, 16683, 16689.
 
 Version 2.19
 
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/bzero-ppc32.S b/sysdeps/powerpc/powerpc32/power4/multiarch/bzero-ppc32.S
index 7a7cca9..80a2dc5 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/bzero-ppc32.S
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/bzero-ppc32.S
@@ -19,8 +19,17 @@
 
 #include <sysdep.h>
 
+/* memset ifunc selector is not built for static and memset@local
+   for shared builds makes the linker point the call to the ifunc
+   selector.  */
+#ifdef SHARED
+# define MEMSET __memset_ppc
+#else
+# define MEMSET memset
+#endif
+
 ENTRY (__bzero_ppc)
         mr      r5,r4
         li      r4,0
-        b       __memset_ppc@local
+        b       MEMSET@local
 END (__bzero_ppc)
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c b/sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c
index 2a6298a..baaa6b4 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/bzero.c
@@ -17,7 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 /* Define multiple versions only for definition in libc.  */
-#if defined SHARED && !defined NOT_IN_libc
+#ifndef NOT_IN_libc
 # include <string.h>
 # include <strings.h>
 # include "init-arch.h"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=09e09c2872ab52c8a42b907105343520019ca1d1

commit 09e09c2872ab52c8a42b907105343520019ca1d1
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Mar 11 16:17:50 2014 -0500

    PowerPC: Fix strspn for static build
    
    This patch makes the strspn ifunc selector build for static builds.
    
    This is a backport of 27c7220a483bda576533aa9a0a9b42175644b1a1

diff --git a/ChangeLog b/ChangeLog
index f971a03..93a4ddf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-03-12  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/multiarch/strspn.c (strspn): Build IFUNC
+	selector for static builds.
+
 2014-03-11  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	[BZ #16683]
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
index 44945f3..bf8c877 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
@@ -16,7 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#if defined SHARED && !defined NOT_IN_libc
+#ifndef NOT_IN_libc
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f510d35c58d16c32ce988d053c9a525b8e38fe47

commit f510d35c58d16c32ce988d053c9a525b8e38fe47
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Mon Mar 10 15:26:20 2014 -0500

    PowerPC: Fix bzero definition for static libc for PPC64
    
    This patch fixes an issue for powerpc64[le] static build where __bzero
    is definied in multiple places (memset-ppc64.o and bzero.o). It is now
    defined only in bzero.o and memset-ppc64.o only defined __bzero_ppc for
    both dynamic and static library.
    
    Fixes BZ#16683.
    
    Backport of 4facea473059914983b7da8dd654c06b8e3dcc41

diff --git a/ChangeLog b/ChangeLog
index ce9bd4c..f971a03 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-11  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	[BZ #16683]
+	* sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S (__bzero_ppc):
+	Define it for static builds as well.
+	(NO_BZERO_IMPL): Likewise.
+
 2014-03-11  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strspn.S: New file: Optimization.
diff --git a/NEWS b/NEWS
index 7b52f1f..fbd56f6 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,7 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545.
+  16545, 16683.
 
 Version 2.19
 
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
index 5b234d9..65b3afe 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
+++ b/sysdeps/powerpc/powerpc64/multiarch/memset-ppc64.S
@@ -18,10 +18,9 @@
 
 #include <sysdep.h>
 
-#if defined SHARED && !defined NOT_IN_libc
-
 /* Copied from bzero.S to prevent the linker from inserting a stub
-   between bzero and memset.  */
+   between bzero and memset.  NOTE: this code should be positioned
+   before ENTRY/END_GEN_TB redefinition.  */
 ENTRY (__bzero_ppc)
         CALL_MCOUNT 3
         mr      r5,r4
@@ -29,6 +28,8 @@ ENTRY (__bzero_ppc)
         b       L(_memset)
 END_GEN_TB (__bzero_ppc,TB_TOCLESS)
 
+
+#if defined SHARED && !defined NOT_IN_libc
 # undef EALIGN
 # define EALIGN(name, alignt, words)				\
   .section ".text";						\
@@ -48,9 +49,9 @@ END_GEN_TB (__bzero_ppc,TB_TOCLESS)
 # undef libc_hidden_builtin_def
 # define libc_hidden_builtin_def(name)				\
   .globl __GI_memset; __GI_memset = __memset_ppc
+#endif
 
 /* Do not implement __bzero at powerpc64/memset.S.  */
-# define NO_BZERO_IMPL
-#endif
+#define NO_BZERO_IMPL
 
 #include <sysdeps/powerpc/powerpc64/memset.S>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=afd75351c2f3cae4a2daf88c50faad889e3a0f2b

commit afd75351c2f3cae4a2daf88c50faad889e3a0f2b
Author: Vidya Ranganathan <vidya@linux.vnet.ibm.com>
Date:   Mon Mar 10 12:20:36 2014 -0400

    PowerPC: strspn optimization for PPC64/POWER7
    
    The optimization is achieved by following techniques:
      > hashing of needle.
      > hashing avoids scanning of duplicate entries in needle across the string.
      > initializing the hash table with Vector instructions (VSX) by quadword access.
      > unrolling when scanning for character in string across hash table.

diff --git a/ChangeLog b/ChangeLog
index fbca13e..ce9bd4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-03-11  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power7/strspn.S: New file: Optimization.
+	* sysdeps/powerpc/powerpc64/multiarch/strspn.c: New file:
+	multiarch strspn for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c: New file
+	* sysdeps/powerpc/powerpc64/multiarch/strspn-power7.S: New file
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strspn
+	multiarch optimizations
+	* string/strspn.c (strspn): Using macro to redefine symbol name.
+
 2014-03-10  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 	    Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
diff --git a/string/strspn.c b/string/strspn.c
index 37e8161..c2d6364 100644
--- a/string/strspn.c
+++ b/string/strspn.c
@@ -18,13 +18,14 @@
 #include <string.h>
 
 #undef strspn
+#ifndef STRSPN
+#define STRSPN strspn
+#endif
 
 /* Return the length of the maximum initial segment
    of S which contains only characters in ACCEPT.  */
 size_t
-strspn (s, accept)
-     const char *s;
-     const char *accept;
+STRSPN (const char *s, const char *accept)
 {
   const char *p;
   const char *a;
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index a03569e..3e8010c 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -14,7 +14,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \
 		   wordcopy-power7 wordcopy-power6 wordcopy-ppc64 \
 		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
-		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64
+		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64 \
+		   strspn-power7 strspn-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 11a3bed..20d7918 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -254,5 +254,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strncat, 1,
 			      __strncat_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strspn.c.  */
+  IFUNC_IMPL (i, name, strspn,
+	      IFUNC_IMPL_ADD (array, i, strspn,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strspn_power7)
+	      IFUNC_IMPL_ADD (array, i, strspn, 1,
+			      __strspn_ppc))
+
   return i;
 }
diff --git a/string/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn-power7.S
similarity index 53%
copy from string/strspn.c
copy to sysdeps/powerpc/powerpc64/multiarch/strspn-power7.S
index 37e8161..889dfee 100644
--- a/string/strspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strspn-power7.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Optimized strspn implementation for POWER7.
+   Copyright (C) 2014 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
@@ -15,32 +16,25 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
-
-#undef strspn
-
-/* Return the length of the maximum initial segment
-   of S which contains only characters in ACCEPT.  */
-size_t
-strspn (s, accept)
-     const char *s;
-     const char *accept;
-{
-  const char *p;
-  const char *a;
-  size_t count = 0;
-
-  for (p = s; *p != '\0'; ++p)
-    {
-      for (a = accept; *a != '\0'; ++a)
-	if (*p == *a)
-	  break;
-      if (*a == '\0')
-	return count;
-      else
-	++count;
-    }
-
-  return count;
-}
-libc_hidden_builtin_def (strspn)
+#include <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strspn_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strspn_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strspn_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strspn_power7)					\
+  END_2(__strspn_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#include <sysdeps/powerpc/powerpc64/power7/strspn.S>
diff --git a/string/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c
similarity index 59%
copy from string/strspn.c
copy to sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c
index 37e8161..d543772 100644
--- a/string/strspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strspn-ppc64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -17,30 +17,17 @@
 
 #include <string.h>
 
-#undef strspn
+#define STRSPN __strspn_ppc
+#undef weak_alias
+#define weak_alias(name, aliasname) \
+  extern __typeof (__strspn_ppc) aliasname \
+    __attribute__ ((weak, alias ("__strspn_ppc")));
+#if !defined(NOT_IN_libc) && defined(SHARED)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1(__strspn_ppc, __GI_strspn, __strspn_ppc);
+#endif
 
-/* Return the length of the maximum initial segment
-   of S which contains only characters in ACCEPT.  */
-size_t
-strspn (s, accept)
-     const char *s;
-     const char *accept;
-{
-  const char *p;
-  const char *a;
-  size_t count = 0;
+extern __typeof (strspn) __strspn_ppc attribute_hidden;
 
-  for (p = s; *p != '\0'; ++p)
-    {
-      for (a = accept; *a != '\0'; ++a)
-	if (*p == *a)
-	  break;
-      if (*a == '\0')
-	return count;
-      else
-	++count;
-    }
-
-  return count;
-}
-libc_hidden_builtin_def (strspn)
+#include <string/strspn.c>
diff --git a/string/strspn.c b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
similarity index 57%
copy from string/strspn.c
copy to sysdeps/powerpc/powerpc64/multiarch/strspn.c
index 37e8161..44945f3 100644
--- a/string/strspn.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strspn.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Multiple versions of strspn. PowerPC64 version.
+   Copyright (C) 2014 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
@@ -15,32 +16,16 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
+#if defined SHARED && !defined NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
 
-#undef strspn
+extern __typeof (strspn) __strspn_ppc attribute_hidden;
+extern __typeof (strspn) __strspn_power7 attribute_hidden;
 
-/* Return the length of the maximum initial segment
-   of S which contains only characters in ACCEPT.  */
-size_t
-strspn (s, accept)
-     const char *s;
-     const char *accept;
-{
-  const char *p;
-  const char *a;
-  size_t count = 0;
-
-  for (p = s; *p != '\0'; ++p)
-    {
-      for (a = accept; *a != '\0'; ++a)
-	if (*p == *a)
-	  break;
-      if (*a == '\0')
-	return count;
-      else
-	++count;
-    }
-
-  return count;
-}
-libc_hidden_builtin_def (strspn)
+libc_ifunc (strspn,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strspn_power7
+            : __strspn_ppc);
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strspn.S b/sysdeps/powerpc/powerpc64/power7/strspn.S
new file mode 100644
index 0000000..d587a67
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strspn.S
@@ -0,0 +1,165 @@
+/* Optimized strspn implementation for PowerPC64/POWER7.
+
+   Copyright (C) 2014 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/>.  */
+
+/* size_t [r3] strspn (const char *string [r3],
+                       const char *needleAccept [r4]  */
+
+/* Performance gains are grabbed through following techniques:
+
+   > hashing of needle.
+   > hashing avoids scanning of duplicate entries in needle
+     across the string.
+   > initializing the hash table with Vector instructions
+     by quadword access.
+   > unrolling when scanning for character in string
+     across hash table.  */
+
+/* Algorithm is as below:
+   1. A empty hash table/dictionary is created comprising of
+      256 ascii character set
+   2. When hash entry is found in needle , the hash index
+      is initialized to 1
+   3. The string is scanned until end and for every character,
+      its corresponding hash index is compared.
+   4. initial length of string (count) until first hit of
+      accept needle to be found is set to 0
+   4. If hash index is set to 1 for the index of string,
+      count is returned.
+   5. Otherwise count is incremented and scanning continues
+      until end of string.  */
+
+#include <sysdep.h>
+
+#undef strspn
+
+	.machine  power7
+EALIGN(strspn, 4, 0)
+	CALL_MCOUNT 2
+
+	lbz r10, 0(r4)		/* load r10 with needle (r4)  */
+	addi r9, r1, -256	/* r9 is a hash of 256 bytes  */
+
+	li r5, 16		/* set r5 = 16 as offset  */
+	li r6, 32		/* set r6 = 32 as offset  */
+	li r8, 48		/* set r8 = 48 as offset  */
+
+/*Iniatliaze hash table with Zeroes in double indexed quadword accesses  */
+	xxlxor v0, v0, v0	/* prepare for initializing hash  */
+
+	stxvd2x v0, r0, r9	/* initialize 1st quadword  */
+	stxvd2x v0, r9, r5
+	stxvd2x v0, r9, r6
+	stxvd2x v0, r9, r8	/* initialize 4th quadword  */
+
+	addi r11, r9, 64	/* r11 is index to hash  */
+
+	stxvd2x v0, r0, r11	/* initialize 5th quadword  */
+	stxvd2x v0, r11, r5
+	stxvd2x v0, r11, r6
+	stxvd2x v0, r11, r8	/* initialize 8th quadword  */
+
+	addi r11, r9, 128	/* r11 is index to hash  */
+
+	stxvd2x v0, r0, r11	/* initialize 9th quadword  */
+	stxvd2x v0, r11, r5
+	stxvd2x v0, r11, r6
+	stxvd2x v0, r11, r8	/* initialize 12th quadword  */
+
+	addi r11, r9, 192	/* r11 is index to hash  */
+
+	stxvd2x v0, r0, r11	/* initialize 13th quadword  */
+	stxvd2x v0, r11, r5
+	stxvd2x v0, r11, r6
+	stxvd2x v0, r11, r8	/* initialize 16th quadword  */
+
+	li r8, 1		/* r8=1, marker into hash if found in
+				   needle  */
+
+	cmpdi cr7, r10, 0	/* accept needle is NULL  */
+	beq cr7, L(skipHashing)	/* if needle is NULL, skip hashing  */
+
+	.p2align 4		/* align section to 16 byte boundary  */
+L(hashing):
+	stbx r8, r9, r10	/* update hash with marker for the pivot of
+				   the needle  */
+	lbzu r10, 1(r4)		/* load needle into r10 and update to next  */
+	cmpdi cr7, r10, 0	/* if needle is has reached NULL, continue  */
+	bne cr7, L(hashing)	/* loop to hash the needle  */
+
+L(skipHashing):
+	li r10, 0		/* load counter = 0  */
+	b L(beginScan)
+
+	.p2align 4		/* align section to 16 byte boundary  */
+L(scanUnroll):
+	lbzx r8, r9, r8		/* load r8 with hash value at index  */
+	cmpwi cr7, r8, 0	/* if we hit marker in hash, we have found
+				   accept needle  */
+	beq cr7, L(ret1stIndex)	/* we have hit accept needle, return the
+				   count  */
+
+	lbz r8, 1(r3)		/* load string[1] into r8  */
+	addi r10, r10, 4	/* increment counter  */
+	lbzx r8, r9, r8		/* load r8 with hash value at index  */
+	cmpwi cr7, r8, 0	/* if we hit marker in hash, we have found
+				   accept needle  */
+	beq cr7, L(ret2ndIndex)	/* we have hit accept needle, return the
+				   count  */
+
+	lbz r8, 2(r3)		/* load string[2] into r8  */
+	lbzx r8, r9, r8		/* load r8 with hash value at index  */
+	cmpwi cr7, r8, 0	/* if we hit marker in hash, we have found
+				   accept needle  */
+	beq cr7, L(ret3rdIndex)	/* we have hit accept needle, return the
+				   count  */
+
+	lbz r8, 3(r3)		/* load string[3] into r8  */
+	lbzx r8, r9, r8		/* load r8 with hash value at index  */
+	addi r3, r3, 4		/* unroll factor , increment string by 4  */
+	cmpwi cr7, r8, 0	/* if we hit marker in hash, we have found
+				   accept needle  */
+	beq cr7,L(ret4thIndex)	/* we have hit accept needle, return the
+				   count  */
+
+L(beginScan):
+	lbz r8, 0(r3)		/* load string[0] into r8  */
+	addi r6, r10, 1		/* place holder for counter + 1  */
+	addi r5, r10, 2		/* place holder for counter + 2  */
+	addi r4, r10, 3		/* place holder for counter + 3  */
+	cmpdi cr7, r8, 0	/* if we hit marker in hash, we have found
+				   accept needle  */
+	bne cr7, L(scanUnroll)	/* continue scanning  */
+
+L(ret1stIndex):
+	mr r3, r10		/* update r3 for return  */
+	blr			/* return  */
+
+L(ret2ndIndex):
+	mr r3, r6		/* update r3 for return  */
+	blr			/* return  */
+
+L(ret3rdIndex):
+	mr r3, r5		/* update r3 for return  */
+	blr			/* return  */
+
+L(ret4thIndex):
+	mr r3, r4		/* update r3 for return  */
+	blr			/* done  */
+END(strspn)
+libc_hidden_builtin_def (strspn)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e5829d82c88117c9f4752cedfefc8516cb9ffdf7

commit e5829d82c88117c9f4752cedfefc8516cb9ffdf7
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Fri Mar 7 06:09:47 2014 -0600

    PowerPC: strncat optimization for PPC64
    
    The optimization is achieved by following techniques:
    1. Doubleword aligned memory access and compares using
       cmpb instruction.
    2. Loop unrolling for byte load/store.
    3. CPU pre-fetch to avoid cache miss.
    
    Backport of ba9cc0714e58a9e8fa73cf6b0e205cbf1e6b71f2

diff --git a/ChangeLog b/ChangeLog
index f344283..fbca13e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2014-03-10  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
+	    Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power7/strncat.S: New file: Optimization.
+	* sysdeps/powerpc/powerpc64/multiarch/strncat.c: New file:
+	multiarch strncat for PPC64.
+	* sysdeps/powerpc/powerpc64/multiarch/strncat-ppc64.c: New file
+	* sysdeps/powerpc/powerpc64/multiarch/strncat-power7.S: New file
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strncat
+	multiarch optimizations
+
 2014-03-03  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strrchr.S: New file.
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index d09f2e3..a03569e 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -14,7 +14,7 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \
 		   wordcopy-power7 wordcopy-power6 wordcopy-ppc64 \
 		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
-		   strrchr-power7 strrchr-ppc64
+		   strrchr-power7 strrchr-ppc64 strncat-power7 strncat-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 8789483..11a3bed 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -246,5 +246,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strrchr, 1,
 			      __strrchr_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strncat.c.  */
+  IFUNC_IMPL (i, name, strncat,
+	      IFUNC_IMPL_ADD (array, i, strncat,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strncat_power7)
+	      IFUNC_IMPL_ADD (array, i, strncat, 1,
+			      __strncat_ppc))
+
   return i;
 }
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.S b/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.S
new file mode 100644
index 0000000..ead4a9a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncat-power7.S
@@ -0,0 +1,42 @@
+/* Optimized strncat implementation for POWER7.
+   Copyright (C) 2014 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 <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words)				\
+  .section ".text";						\
+  ENTRY_2(__strncat_power7)					\
+  .align ALIGNARG(alignt);					\
+  EALIGN_W_##words;						\
+  BODY_LABEL(__strncat_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strncat_power7)
+
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strncat_power7)					\
+  END_2(__strncat_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#define STRLEN __strlen_power7
+
+#include <sysdeps/powerpc/powerpc64/power7/strncat.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat-ppc64.c b/sysdeps/powerpc/powerpc64/multiarch/strncat-ppc64.c
new file mode 100644
index 0000000..3058c0a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncat-ppc64.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2014 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 <string.h>
+
+#define STRNCAT __strncat_ppc
+#ifdef SHARED
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1 (__strncat_ppc, __GI_strncat, __strncat_ppc);
+#endif
+
+extern __typeof (strncat) __strncat_ppc attribute_hidden;
+
+#include <string/strncat.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncat.c b/sysdeps/powerpc/powerpc64/multiarch/strncat.c
new file mode 100644
index 0000000..db98ec1
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncat.c
@@ -0,0 +1,31 @@
+/* Multiple versions of strncat. PowerPC64 version.
+   Copyright (C) 2014 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/>.  */
+
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (strncat) __strncat_ppc attribute_hidden;
+extern __typeof (strncat) __strncat_power7 attribute_hidden;
+
+libc_ifunc (strncat,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strncat_power7
+            : __strncat_ppc);
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strncat.S b/sysdeps/powerpc/powerpc64/power7/strncat.S
new file mode 100644
index 0000000..1a1a95e
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strncat.S
@@ -0,0 +1,222 @@
+/* Optimized strncat implementation for PowerPC64/POWER7.
+
+   Copyright (C) 2014 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/>.  */
+
+/* The algorithm is as follows for aligned memory access :
+
+   if address of s2 is divisible by 0x7UL,
+       perform aligned doubleword catenation
+   else
+       perform unaligned catenation
+
+   The aligned comparison are made using cmpb instructions.  */
+
+/* char* [r3] strncat (const char *s1 [r3],
+                       const char *s2 [r4],
+                       size_t size [r5])  */
+
+#include <sysdep.h>
+
+#ifndef STRNCAT
+# undef strncat
+# define STRNCAT  strncat
+#endif
+
+#ifndef STRLEN
+# define STRLEN   __strlen_ppc
+#endif
+
+#define	FRAMESIZE	(FRAME_MIN_SIZE+32)
+
+	.machine  power7
+EALIGN(STRNCAT, 4, 0)
+	CALL_MCOUNT 3
+
+	mflr r0				/* Load link register LR to r0.  */
+
+/* We shall use r29, r30 and r31 non volatile register for retention.
+   Save all the callee registers in the GPR save area.  */
+	std r29, -24(r1)		/* Save callers register r29.  */
+	std r30, -16(r1)		/* Save callers register r30.  */
+	std r31, -8(r1)			/* Save callers register r31.  */
+
+	std r0, 16(r1)			/* Store the link register.  */
+	stdu r1, -FRAMESIZE(r1)		/* Create the stack frame.  */
+
+/* Improve performance with CPU pre-fetch.  */
+	dcbt 0, r3			/* Pre-fetch str to avoid cache
+					   miss.  */
+	dcbt 0, r4			/* Pre-fetch accept to avoid cache
+					   miss.  */
+
+	mr. r29, r5			/* Save "n" in r29.  */
+	mr r30, r3			/* Save "s1" in r30 from r3.  */
+	beq cr0,L(done)
+
+	mr r31, r4			/* Save "s2" in r31 from r4.  */
+	bl STRLEN			/* Call optimized strlen on s1; goto
+					   end of s1.  */
+	nop
+	cmpldi cr7, r29, 7		/* If s2 is <=7 process
+					    byte-by-byte.  */
+	add r3, r30, r3			/* Grab the last character of s1.  */
+	bgt cr7,L(alignment)		/* Process by aligned strings.  */
+
+	cmpldi cr7, r29, 3		/* If n is >= 4, we can
+					   byte-unroll.  */
+	addi r9, r3, -1			/* Make "s1" point before next
+					   character, increment when read.  */
+	bgt cr7, L(bytes_unroll)	/* Process each byte.  */
+
+L(byte_by_byte):
+	lbz r10, 0(r31)
+	addi r8, r9, 1
+	cmpdi cr7, r10, 0		/* Check for NULL in "s2".  */
+	stb r10, 1(r9)
+	beq cr7, L(done)
+	add r9, r9, r29
+	subf r9, r8, r9
+	addi r9, r9, 1
+	mtctr r9
+	b L(branch2)
+	.p2align 4
+L(branch1):
+	lbzu r10, 1(r31)
+	cmpdi cr7, r10, 0
+	stbu r10, 1(r8)
+	beq cr7,L(done)
+L(branch2):
+	mr r9, r8
+	bdnz L(branch1)
+	beq cr7,L(done)
+L(nullTerminate):
+	li r10, 0			/* Load NULL for termination.  */
+	stb r10, 1(r9)			/* Append or terminate s1 with
+					   NULL.  */
+	.p2align 4			/* A small section here.  */
+L(done):				/* We return now.   */
+	addi r1, r1, FRAMESIZE		/* Restore stack pointer.  */
+	mr r3, r30			/* Set the return value length of
+					   string.  */
+	ld r0, 16(r1)			/* Read the saved link register.  */
+	ld r29, -24(r1)			/* Restore save register r29.  */
+	ld r30, -16(r1)			/* Restore save register r30.  */
+	ld r31, -8(r1)			/* Restore save register r31.  */
+	mtlr r0				/* Restore link register.  */
+	blr				/* Branch to link register.  */
+
+	.p2align 4
+L(alignment):
+	rldicl. r9, r31, 0, 61		/* Check if s2 is 8byte aligned  */
+	beq cr0,L(dwordAligned)
+
+	.p2align 4
+/* Unaligned bytes in string, so process byte by byte.
+   POWER7 has performance gains over loop unroll.  */
+L(bytes_unroll):
+	addi r9, r3, -1
+	srdi r10, r29, 2
+	mtctr r10
+	b L(L10)
+	.p2align 4
+L(L44):
+	lbz r10, 1(r31)			/* Load byte.  */
+	cmpdi cr7, r10, 0		/* Compare ; if byte not zero,
+					   continue.  */
+	stb r10, 2(r9)			/* Store byte  */
+	beq cr7, L(done)
+	addi r31, r31, 4
+
+	lbz r10, -2(r31)		/* Perform loop unroll here on byte
+					   load and store.  */
+	cmpdi cr7, r10, 0
+	stb r10, 3(r9)
+	beq cr7, L(done)
+
+	lbz r10, -1(r31)		/* Loop unroll here.  */
+	cmpdi cr7, r10, 0
+	stbu r10, 4(r9)
+	beq cr7, L(done)
+
+	bdz L(leftNbytes)
+
+L(L10):
+	lbz r10, 0(r31)			/* Loop unroll here.  */
+	cmpdi cr7, r10, 0
+	stb r10, 1(r9)
+	bne cr7,L(L44)
+	b L(done)
+	.p2align 4
+/* If s2 is double word aligned, we load and store double word.  */
+L(dwordAligned):
+/* read, write 8 bytes at a time  */
+	srdi r8, r29, 3			/* Compute count for CTR to loop;
+					   count = n/8.  */
+	li r7, 0			/* Load r7 with NULL.  */
+	li r10, 0			/* Load r10 with MASK '0'.  */
+
+	mtctr r8			/* Move count to CTR.  */
+L(loop8):
+	ld r9, 0(r31)			/* Read double word from s2.  */
+	cmpb r6, r9, r10		/* Compare bytes in s2 we read
+					   just now.  */
+	cmpdi r6, 0			/* If cmpb returned NULL,
+					   we continue.  */
+	bne+ L(a8)
+	std r9, 0(r3)			/* Append double word from s2
+					   with s1.  */
+	addi r3, r3, 8			/* Increment s1.  */
+	addi r31, r31, 8		/* Increment s2.  */
+	subi r29, r29, 8		/* Decrement count by 8.  */
+	bdnz L(loop8)			/* Continue until "count" is
+					   non zero.  */
+
+L(a8):
+	cmpdi r29, 0			/* If "n" is already zero, we skip. */
+	beq+ L(align8align)
+
+	mtctr r29			/* Process left over bytes in "n".  */
+L(unaligned0):
+	lbz r9, 0(r31)			/* Read a byte from s2.  */
+	cmpw r9, r7			/* If byte is NULL, we stop here . */
+	beq+ L(align8align)		/* Skip processing further if NULL.  */
+	stb  r9, 0(r3)			/* If not NULL, store byte into s1.  */
+	addi r3, r3, 1			/* Increment s1 by 1.  */
+	addi r31, r31, 1		/* Increment s2 by 1.  */
+	bdnz L(unaligned0)		/* Decrement counter "n" and loop
+					   until non zero.  */
+L(align8align):
+	stb r7, 0(r3)			/* Terminate s1 with NULL.  */
+
+	addi r1, r1, FRAMESIZE		/* Restore stack pointer.  */
+	mr r3, r30			/* Set the return value, length of
+					   string.  */
+	ld r0, 16(r1)			/* Read the saved link register.  */
+	ld r29, -24(r1)			/* Restore save register r29.  */
+	ld r30, -16(r1)			/* Restore save register r30.  */
+	ld r31, -8(r1)			/* Restore save register r31.  */
+	mtlr r0				/* Restore link register.  */
+	blr				/* Branch to link register  */
+
+	.p2align 4
+L(leftNbytes):
+	rldicl. r29, r29, 0, 62		/* Check if n>0 and n < 4 bytes.  */
+	bne cr0,L(byte_by_byte)		/* Process bytes one by one. */
+	b L(nullTerminate)		/* Now, finish catenation with
+					   NULL termination.  */
+END(STRNCAT)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e032058ea756e396c4ed1395a44d8b321e370b2f

commit e032058ea756e396c4ed1395a44d8b321e370b2f
Author: Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
Date:   Mon Mar 3 08:06:41 2014 -0600

    PowerPC: strrchr optimization for POWER7/PPC64
    
    This patch optimizes strrchr() for ppc64. It uses aligned memory
    access along with cmpb instruction and CPU prefetch to avoid
    cache misses for speed improvement.
    
    Backport of c7debbdfacbef150aaf9113eb05ccaf2b9e7af6c

diff --git a/ChangeLog b/ChangeLog
index 9c2fa48..f344283 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-03-03  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/power7/strrchr.S: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strrchr multiarch
+	implementation.
+	* sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c:
+	(__libc_ifunc_impl_list): Likewise.
+	* sysdeps/powerpc/powerpc64/multiarch/strrchr.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/strrchr-ppc64.c: New file.
+	* sysdeps/powerpc/powerpc64/multiarch/strrchr-power7.S: New file.
+	* string/strrchr.c: Define STRRCHR.
+
 2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llround power8
diff --git a/string/strrchr.c b/string/strrchr.c
index b5b4bc6..47ff08c 100644
--- a/string/strrchr.c
+++ b/string/strrchr.c
@@ -19,9 +19,13 @@
 
 #undef strrchr
 
+#ifndef STRRCHR
+# define STRRCHR strrchr
+#endif
+
 /* Find the last occurrence of C in S.  */
 char *
-strrchr (const char *s, int c)
+STRRCHR (const char *s, int c)
 {
   const char *found, *p;
 
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 3c47316..d09f2e3 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -13,7 +13,8 @@ sysdep_routines += memcpy-power7 memcpy-a2 memcpy-power6 memcpy-cell \
 		   wcschr-power6 wcschr-ppc64 wcsrchr-power7 wcsrchr-power6 \
 		   wcsrchr-ppc64 wcscpy-power7 wcscpy-power6 wcscpy-ppc64 \
 		   wordcopy-power7 wordcopy-power6 wordcopy-ppc64 \
-		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64
+		   strcpy-power7 strcpy-ppc64 stpcpy-power7 stpcpy-ppc64 \
+		   strrchr-power7 strrchr-ppc64
 
 CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
 CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index 6bbdd4e..8789483 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -238,5 +238,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, wcscpy, 1,
 			      __wcscpy_ppc))
 
+  /* Support sysdeps/powerpc/powerpc64/multiarch/strrchr.c.  */
+  IFUNC_IMPL (i, name, strrchr,
+	      IFUNC_IMPL_ADD (array, i, strrchr,
+			      hwcap & PPC_FEATURE_HAS_VSX,
+			      __strrchr_power7)
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1,
+			      __strrchr_ppc))
+
   return i;
 }
diff --git a/string/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr-power7.S
similarity index 55%
copy from string/strrchr.c
copy to sysdeps/powerpc/powerpc64/multiarch/strrchr-power7.S
index b5b4bc6..78e15e3 100644
--- a/string/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr-power7.S
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Optimized strrchr implementation for POWER7.
+   Copyright (C) 2014 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
@@ -15,35 +16,24 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
+#include <sysdep.h>
 
-#undef strrchr
+#undef ENTRY
+#define ENTRY(name)						\
+  .section ".text";						\
+  ENTRY_2(__strrchr_power7)					\
+  .align ALIGNARG(2);						\
+  BODY_LABEL(__strrchr_power7):					\
+  cfi_startproc;						\
+  LOCALENTRY(__strrchr_power7)
 
-/* Find the last occurrence of C in S.  */
-char *
-strrchr (const char *s, int c)
-{
-  const char *found, *p;
+#undef END
+#define END(name)						\
+  cfi_endproc;							\
+  TRACEBACK(__strrchr_power7)					\
+  END_2(__strrchr_power7)
 
-  c = (unsigned char) c;
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
 
-  /* Since strchr is fast, we use it rather than the obvious loop.  */
-
-  if (c == '\0')
-    return strchr (s, '\0');
-
-  found = NULL;
-  while ((p = strchr (s, c)) != NULL)
-    {
-      found = p;
-      s = p + 1;
-    }
-
-  return (char *) found;
-}
-
-#ifdef weak_alias
-#undef rindex
-weak_alias (strrchr, rindex)
-#endif
-libc_hidden_builtin_def (strrchr)
+#include <sysdeps/powerpc/powerpc64/power7/strrchr.S>
diff --git a/string/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr-ppc64.c
similarity index 58%
copy from string/strrchr.c
copy to sysdeps/powerpc/powerpc64/multiarch/strrchr-ppc64.c
index b5b4bc6..5633a9f 100644
--- a/string/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr-ppc64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2014 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
@@ -17,33 +17,17 @@
 
 #include <string.h>
 
-#undef strrchr
-
-/* Find the last occurrence of C in S.  */
-char *
-strrchr (const char *s, int c)
-{
-  const char *found, *p;
-
-  c = (unsigned char) c;
-
-  /* Since strchr is fast, we use it rather than the obvious loop.  */
-
-  if (c == '\0')
-    return strchr (s, '\0');
-
-  found = NULL;
-  while ((p = strchr (s, c)) != NULL)
-    {
-      found = p;
-      s = p + 1;
-    }
+#define STRRCHR __strrchr_ppc
+#undef weak_alias
+#define weak_alias(name, aliasname) \
+  extern __typeof (__strrchr_ppc) aliasname \
+    __attribute__ ((weak, alias ("__strrchr_ppc")));
+#if !defined(NOT_IN_libc) && defined(SHARED)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+  __hidden_ver1(__strrchr_ppc, __GI_strrchr, __strrchr_ppc);
+#endif
 
-  return (char *) found;
-}
+extern __typeof (strrchr) __strrchr_ppc attribute_hidden;
 
-#ifdef weak_alias
-#undef rindex
-weak_alias (strrchr, rindex)
-#endif
-libc_hidden_builtin_def (strrchr)
+#include <string/strrchr.c>
diff --git a/string/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
similarity index 56%
copy from string/strrchr.c
copy to sysdeps/powerpc/powerpc64/multiarch/strrchr.c
index b5b4bc6..046162f 100644
--- a/string/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
+/* Multiple versions of strrchr. PowerPC64 version.
+   Copyright (C) 2014 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
@@ -15,35 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <string.h>
-
-#undef strrchr
-
-/* Find the last occurrence of C in S.  */
-char *
-strrchr (const char *s, int c)
-{
-  const char *found, *p;
-
-  c = (unsigned char) c;
-
-  /* Since strchr is fast, we use it rather than the obvious loop.  */
-
-  if (c == '\0')
-    return strchr (s, '\0');
-
-  found = NULL;
-  while ((p = strchr (s, c)) != NULL)
-    {
-      found = p;
-      s = p + 1;
-    }
-
-  return (char *) found;
-}
-
-#ifdef weak_alias
-#undef rindex
+/* Define multiple versions only for definition in libc.  */
+#ifndef NOT_IN_libc
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (strrchr) __strrchr_ppc attribute_hidden;
+extern __typeof (strrchr) __strrchr_power7 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+libc_ifunc (strrchr,
+            (hwcap & PPC_FEATURE_HAS_VSX)
+            ? __strrchr_power7
+            : __strrchr_ppc);
 weak_alias (strrchr, rindex)
 #endif
-libc_hidden_builtin_def (strrchr)
diff --git a/sysdeps/powerpc/powerpc64/power7/strrchr.S b/sysdeps/powerpc/powerpc64/power7/strrchr.S
new file mode 100644
index 0000000..e4a76c8
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strrchr.S
@@ -0,0 +1,255 @@
+/* Optimized strrchr implementation for PowerPC64/POWER7 using cmpb insn.
+   Copyright (C) 2014 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 <sysdep.h>
+
+/* int [r3] strrchr (char *s [r3], int c [r4])  */
+	.machine  power7
+ENTRY (strrchr)
+	CALL_MCOUNT 2
+	dcbt	0,r3
+	clrrdi	r8,r3,3	      /* Align the address to doubleword boundary.  */
+	cmpdi	cr7,r4,0
+	ld	r12,0(r8)     /* Load doubleword from memory.  */
+	li	r9,0	      /* used to store last occurence */
+	li	r0,0	      /* Doubleword with null chars to use
+				 with cmpb.  */
+
+	rlwinm	r6,r3,3,26,28 /* Calculate padding.  */
+
+	beq	cr7,L(null_match)
+
+	/* Replicate byte to doubleword.  */
+	insrdi	r4,r4,8,48
+	insrdi	r4,r4,16,32
+	insrdi	r4,r4,32,0
+
+	/* r4 is changed now ,if its passed as more chars
+	   check for null again */
+	cmpdi	cr7,r4,0
+	beq	cr7,L(null_match)
+	/* Now r4 has a doubleword of c bytes and r0 has
+	   a doubleword of null bytes.  */
+
+	cmpb	r10,r12,r4     /* Compare each byte against c byte.  */
+	cmpb	r11,r12,r0     /* Compare each byte against null byte.  */
+
+	/* Move the doublewords left and right to discard the bits that are
+	   not part of the string and bring them back as zeros.  */
+#ifdef __LITTLE_ENDIAN__
+	srd	r10,r10,r6
+	srd	r11,r11,r6
+	sld	r10,r10,r6
+	sld	r11,r11,r6
+#else
+	sld	r10,r10,r6
+	sld	r11,r11,r6
+	srd	r10,r10,r6
+	srd	r11,r11,r6
+#endif
+	or	r5,r10,r11    /* OR the results to speed things up.  */
+	cmpdi	cr7,r5,0      /* If r5 == 0, no c or null bytes
+				 have been found.  */
+	bne	cr7,L(done)
+
+L(align):
+	mtcrf	0x01,r8
+
+	/* Are we now aligned to a doubleword boundary?  If so, skip to
+	   the main loop.  Otherwise, go through the alignment code.  */
+
+	bt	28,L(loop)
+
+	/* Handle WORD2 of pair.  */
+	ldu	r12,8(r8)
+	cmpb	r10,r12,r4
+	cmpb	r11,r12,r0
+	or	r5,r10,r11
+	cmpdi	cr7,r5,0
+	bne	cr7,L(done)
+	b	L(loop)	      /* We branch here (rather than falling through)
+				 to skip the nops due to heavy alignment
+				 of the loop below.  */
+	.p2align  5
+L(loop):
+	/* Load two doublewords, compare and merge in a
+	   single register for speed.  This is an attempt
+	   to speed up the null-checking process for bigger strings.  */
+	ld	r12,8(r8)
+	ldu	r7,16(r8)
+	cmpb	r10,r12,r4
+	cmpb	r11,r12,r0
+	cmpb	r6,r7,r4
+	cmpb	r7,r7,r0
+	or	r12,r10,r11
+	or	r5,r6,r7
+	or	r5,r12,r5
+	cmpdi	cr7,r5,0
+	beq	cr7,L(loop)
+
+	/* OK, one (or both) of the doublewords contains a c/null byte.  Check
+	   the first doubleword and decrement the address in case the first
+	   doubleword really contains a c/null byte.  */
+	cmpdi	cr6,r12,0
+	addi	r8,r8,-8
+	bne	cr6,L(done)
+
+	/* The c/null byte must be in the second doubleword.  Adjust the
+	   address again and move the result of cmpb to r10 so we can calculate
+	   the pointer.  */
+
+	mr	r10,r6
+	mr	r11,r7
+	addi	r8,r8,8
+
+	/* r10/r11 have the output of the cmpb instructions, that is,
+	   0xff in the same position as the c/null byte in the original
+	   doubleword from the string.  Use that to calculate the pointer.  */
+
+L(done):
+	/* if there are more than one 0xff in r11, find the first pos of ff
+	   in r11 and fill r10 with 0 from that position */
+	cmpdi	cr7,r11,0
+	beq	cr7,L(no_null)
+#ifdef __LITTLE_ENDIAN__
+	addi	r3,r11,-1
+	andc	r3,r3,r11
+	popcntd r0,r3
+#else
+	cntlzd	r0,r11
+#endif
+	subfic	r0,r0,63
+	li	r6,-1
+#ifdef __LITTLE_ENDIAN__
+	srd	r0,r6,r0
+#else
+	sld	r0,r6,r0
+#endif
+	and	r10,r0,r10
+L(no_null):
+#ifdef __LITTLE_ENDIAN__
+	cntlzd	r0,r10		/* Count leading zeros before c matches.  */
+	addi	r3,r10,-1
+	andc	r3,r3,r10
+	addi	r10,r11,-1
+	andc	r10,r10,r11
+	cmpld	cr7,r3,r10
+	bgt	cr7,L(no_match)
+#else
+	addi	r3,r10,-1	/* Count trailing zeros before c matches.  */
+	andc	r3,r3,r10
+	popcntd	r0,r3
+	cmpld	cr7,r11,r10
+	bgt	cr7,L(no_match)
+#endif
+	srdi	r0,r0,3		/* Convert trailing zeros to bytes.  */
+	subfic	r0,r0,7
+	add	r9,r8,r0      /* Return address of the matching c byte
+				 or null in case c was not found.  */
+	li	r0,0
+	cmpdi	cr7,r11,0     /* If r11 == 0, no null's have been found.  */
+	beq	cr7,L(align)
+
+	.align	4
+L(no_match):
+	mr	r3,r9
+	blr
+
+/* We are here because strrchr was called with a null byte.  */
+	.align	4
+L(null_match):
+	/* r0 has a doubleword of null bytes.  */
+
+	cmpb	r5,r12,r0     /* Compare each byte against null bytes.  */
+
+	/* Move the doublewords left and right to discard the bits that are
+	   not part of the string and bring them back as zeros.  */
+#ifdef __LITTLE_ENDIAN__
+	srd	r5,r5,r6
+	sld	r5,r5,r6
+#else
+	sld	r5,r5,r6
+	srd	r5,r5,r6
+#endif
+	cmpdi	cr7,r5,0      /* If r10 == 0, no c or null bytes
+				 have been found.  */
+	bne	cr7,L(done_null)
+
+	mtcrf	0x01,r8
+
+	/* Are we now aligned to a quadword boundary?  If so, skip to
+	   the main loop.  Otherwise, go through the alignment code.  */
+
+	bt	28,L(loop_null)
+
+	/* Handle WORD2 of pair.  */
+	ldu	r12,8(r8)
+	cmpb	r5,r12,r0
+	cmpdi	cr7,r5,0
+	bne	cr7,L(done_null)
+	b	L(loop_null)  /* We branch here (rather than falling through)
+				 to skip the nops due to heavy alignment
+				 of the loop below.  */
+
+	/* Main loop to look for the end of the string.  Since it's a
+	   small loop (< 8 instructions), align it to 32-bytes.  */
+	.p2align  5
+L(loop_null):
+	/* Load two doublewords, compare and merge in a
+	   single register for speed.  This is an attempt
+	   to speed up the null-checking process for bigger strings.  */
+	ld	r12,8(r8)
+	ldu	r11,16(r8)
+	cmpb	r5,r12,r0
+	cmpb	r10,r11,r0
+	or	r6,r5,r10
+	cmpdi	cr7,r6,0
+	beq	cr7,L(loop_null)
+
+	/* OK, one (or both) of the doublewords contains a null byte.  Check
+	   the first doubleword and decrement the address in case the first
+	   doubleword really contains a null byte.  */
+
+	cmpdi	cr6,r5,0
+	addi	r8,r8,-8
+	bne	cr6,L(done_null)
+
+	/* The null byte must be in the second doubleword.  Adjust the address
+	   again and move the result of cmpb to r10 so we can calculate the
+	   pointer.  */
+
+	mr	r5,r10
+	addi	r8,r8,8
+
+	/* r5 has the output of the cmpb instruction, that is, it contains
+	   0xff in the same position as the null byte in the original
+	   doubleword from the string.  Use that to calculate the pointer.  */
+L(done_null):
+#ifdef __LITTLE_ENDIAN__
+	addi	r0,r5,-1
+	andc	r0,r0,r5
+	popcntd	r0,r0
+#else
+	cntlzd	r0,r5	      /* Count leading zeros before the match.  */
+#endif
+	srdi	r0,r0,3	      /* Convert trailing zeros to bytes.  */
+	add	r3,r8,r0      /* Return address of the matching null byte.  */
+	blr
+END (strrchr)
+weak_alias (strrchr, rindex)
+libc_hidden_builtin_def (strrchr)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=54dd35c59cda5f59c2f3ae783468da4b94f30dff

commit 54dd35c59cda5f59c2f3ae783468da4b94f30dff
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Mon Feb 17 10:44:08 2014 -0600

    PowerPC: llround/llroundf POWER8 optimization
    
    This patch add a optimized llround/llroundf implementation for POWER8
    using the new Move From VSR Doubleword instruction to gains some
    cycles from FP to GRP register move.
    
    Backport fe13a20c37578f08ce393ccaeb45caeb48815ca5

diff --git a/ChangeLog b/ChangeLog
index 2e7db2b..9c2fa48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llround power8
+	implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S: New file:
+	POWER8 llround ifunc implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c (__lllround): Add
+	POWER8 implementation.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S: New file:
+	POWER8 llround implementation.
+
+2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llrint power8
 	implementation.
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S: New file:
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index f882478..0e3eac7 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -24,7 +24,7 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
 			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
 			s_isnan-power8 s_isinf-power8 s_finite-power8 \
-			s_llrint-power8
+			s_llrint-power8 s_llround-power8
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S
new file mode 100644
index 0000000..41c61a1
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround-power8.S
@@ -0,0 +1,31 @@
+/* llround().  PowerPC64 default version.
+   Copyright (C) 2014 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 <sysdep.h>
+#include <math_ldbl_opt.h>
+
+#undef weak_alias
+#define weak_alias(name, alias)
+#undef strong_alias
+#define strong_alias(name, alias)
+#undef compat_symbol
+#define compat_symbol(lib, name, alias, ver)
+
+#define __llround __llround_power8
+
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
index a4d1bf3..7dba17e 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llround.c
@@ -27,12 +27,15 @@
 extern __typeof (__llround) __llround_ppc64 attribute_hidden;
 extern __typeof (__llround) __llround_power5plus attribute_hidden;
 extern __typeof (__llround) __llround_power6x attribute_hidden;
+extern __typeof (__llround) __llround_power8 attribute_hidden;
 
 libc_ifunc (__llround,
-	    (hwcap & PPC_FEATURE_POWER6_EXT)
-	    ? __llround_power6x :
-	      (hwcap & PPC_FEATURE_POWER5_PLUS)
-	      ? __llround_power5plus
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __llround_power8 :
+	      (hwcap & PPC_FEATURE_POWER6_EXT)
+	      ? __llround_power6x :
+		(hwcap & PPC_FEATURE_POWER5_PLUS)
+		? __llround_power5plus
             : __llround_ppc64);
 
 weak_alias (__llround, llround)
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
new file mode 100644
index 0000000..b00d4d6
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S
@@ -0,0 +1,47 @@
+/* llround function.  POWER8 PowerPC64 version.
+   Copyright (C) 2014 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 <sysdep.h>
+#include <math_ldbl_opt.h>
+
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+
+/* long long [r3] llround (float x [fp1])  */
+
+ENTRY (__llround)
+	CALL_MCOUNT 0
+	frin	fp1,fp1	/* Round to nearest +-0.5.  */
+	fctidz	fp1,fp1	/* Convert To Integer DW round toward 0.  */
+	MFVSRD_R3_V1
+	blr
+END (__llround)
+
+strong_alias (__llround, __lround)
+weak_alias (__llround, llround)
+weak_alias (__lround, lround)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__llround, llroundl)
+strong_alias (__llround, __llroundl)
+weak_alias (__lround, lroundl)
+strong_alias (__lround, __lroundl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llround, llroundl, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b34f8e9fcd1274e69a9a59a28c270e2cada39c95

commit b34f8e9fcd1274e69a9a59a28c270e2cada39c95
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Tue Feb 18 09:29:29 2014 -0500

    PowerPC: llrint/llrintf POWER8 optimization
    
    This patch add a optimized llrint/llrintf implementation for POWER8
    using the new Move From VSR Doubleword instruction to gains some
    cycles from FP to GRP register move.
    
    Backport of 1ad8950a3ea4056ed343d681b5146f4b4aa27e10

diff --git a/ChangeLog b/ChangeLog
index 24d1479..2e7db2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add llrint power8
+	implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S: New file:
+	POWER8 llrint ifunc implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c (__lllrint): Add
+	POWER8 implementation.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S: New file:
+	POWER8 llrint implementation.
+
+2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add finite power8
 	implementation.
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S: New file:
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index 52bbd4b..f882478 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -23,7 +23,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
 			s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
 			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
-			s_isnan-power8 s_isinf-power8 s_finite-power8
+			s_isnan-power8 s_isinf-power8 s_finite-power8 \
+			s_llrint-power8
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S
new file mode 100644
index 0000000..3962b7d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint-power8.S
@@ -0,0 +1,31 @@
+/* Round double to long int.  PowerPC64/POWER6X default version.
+   Copyright (C) 2014 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 <sysdep.h>
+#include <math_ldbl_opt.h>
+
+#undef weak_alias
+#define weak_alias(a,b)
+#undef strong_alias
+#define strong_alias(a,b)
+#undef compat_symbol
+#define compat_symbol(a,b,c,d)
+
+#define __llrint __llrint_power8
+
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
index 5818b53..cf1b2e4 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
@@ -30,10 +30,13 @@
 
 extern __typeof (__llrint) __llrint_ppc64 attribute_hidden;
 extern __typeof (__llrint) __llrint_power6x attribute_hidden;
+extern __typeof (__llrint) __llrint_power8 attribute_hidden;
 
 libc_ifunc (__llrint,
-	    (hwcap & PPC_FEATURE_POWER6_EXT)
-	    ? __llrint_power6x
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __llrint_power8 :
+	      (hwcap & PPC_FEATURE_POWER6_EXT)
+	      ? __llrint_power6x
             : __llrint_ppc64);
 
 weak_alias (__llrint, llrint)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
similarity index 55%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
copy to sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
index 5818b53..476d76b 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_llrint.c
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S
@@ -1,5 +1,5 @@
-/* Multiple versions of llrint.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* Round double to long int.  POWER8 PowerPC64 version.
+   Copyright (C) 2014 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
@@ -16,42 +16,30 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/* Redefine lrint/__lrint so that the compiler won't complain about the type
-   mismatch with the IFUNC selector in strong_alias below.  */
-#define lrint __hidden_lrint
-#define __lrint __hidden___lrint
-
-#include <math.h>
+#include <sysdep.h>
 #include <math_ldbl_opt.h>
-#undef lrint
-#undef __lrint
-#include <shlib-compat.h>
-#include "init-arch.h"
 
-extern __typeof (__llrint) __llrint_ppc64 attribute_hidden;
-extern __typeof (__llrint) __llrint_power6x attribute_hidden;
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
 
-libc_ifunc (__llrint,
-	    (hwcap & PPC_FEATURE_POWER6_EXT)
-	    ? __llrint_power6x
-            : __llrint_ppc64);
+/* long long int[r3] __llrint (double x[fp1])  */
+ENTRY (__llrint)
+	CALL_MCOUNT 0
+	fctid	fp1,fp1
+	MFVSRD_R3_V1
+	blr
+END (__llrint)
 
+strong_alias (__llrint, __lrint)
 weak_alias (__llrint, llrint)
+weak_alias (__lrint, lrint)
+
 #ifdef NO_LONG_DOUBLE
 strong_alias (__llrint, __llrintl)
 weak_alias (__llrint, llrintl)
-#endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
-#endif
-
-/* long has the same width as long long on PowerPC64.  */
-strong_alias (__llrint, __lrint)
-weak_alias (__lrint, lrint)
-#ifdef NO_LONG_DOUBLE
 strong_alias (__lrint, __lrintl)
 weak_alias (__lrint, lrintl)
 #endif
 #if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
-compat_symbol (libm, __lrint, lrintl, GLIBC_2_1);
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1)
 #endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c3241bcd73c47d2bcd2a5ffe84a21d4853c8c938

commit c3241bcd73c47d2bcd2a5ffe84a21d4853c8c938
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu Feb 27 09:46:46 2014 -0600

    PowerPC: Optimized finite/finitef for POWER8
    
    This patch add a optimized finite/finitef implementation for POWER8
    using the new Move From VSR Doubleword instruction to gains some
    cycles from FP to GRP register move.
    
    Backport of cac626d60a863e48ab75417064984769e58c5719.

diff --git a/ChangeLog b/ChangeLog
index 2dff388..24d1479 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add finite power8
+	implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S: New file:
+	POWER8 finite ifunc implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c (__finite): Add
+	POWER8 implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c (__finitef):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S: New file:
+	POWER8 finite implementation.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S: New file.
+
+2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isinf power8
 	implementation.
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S: New file:
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index abbf7d0..52bbd4b 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -5,7 +5,7 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 		   s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
 		   s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \
 		   s_modff-power5+ s_modff-ppc64 s_isnan-power8 \
-		   s_isinf-power8
+		   s_isinf-power8 s_finite-power8
 
 libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
@@ -23,7 +23,7 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
 			s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
 			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
-			s_isnan-power8 s_isinf-power8
+			s_isnan-power8 s_isinf-power8 s_finite-power8
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S
similarity index 59%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
copy to sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S
index a7243b5..3b9071f 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite-power8.S
@@ -1,5 +1,5 @@
-/* Multiple versions of finitef.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* isnan().  PowerPC64/POWER7 version.
+   Copyright (C) 2014 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
@@ -16,17 +16,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <math.h>
-#include <shlib-compat.h>
-#include "init-arch.h"
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
 
-extern __typeof (__finitef) __finitef_ppc64 attribute_hidden;
-/* The double-precision version also works for single-precision.  */
-extern __typeof (__finitef) __finite_power7 attribute_hidden;
+#undef hidden_def
+#define hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, alias)
+#undef strong_alias
+#define strong_alias(name, alias)
+#undef compat_symbol
+#define compat_symbol(lib, name, symbol, ver)
 
-libc_ifunc (__finitef,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finitef_ppc64);
+#define __finite __finite_power8
 
-weak_alias (__finitef, finitef)
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index f79a93e..b9e908d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
@@ -23,10 +23,13 @@
 
 extern __typeof (__finite) __finite_ppc64 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
+extern __typeof (__finite) __finite_power8 attribute_hidden;
 
 libc_ifunc (__finite,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __finite_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __finite_power7
             : __finite_ppc64);
 
 weak_alias (__finite, finite)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
index a7243b5..30b34bc 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
@@ -23,10 +23,13 @@
 extern __typeof (__finitef) __finitef_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
+extern __typeof (__finitef) __finite_power8 attribute_hidden;
 
 libc_ifunc (__finitef,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __finite_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __finite_power7
             : __finitef_ppc64);
 
 weak_alias (__finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
similarity index 56%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
copy to sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
index f79a93e..8e5de27 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S
@@ -1,5 +1,5 @@
-/* Multiple versions of finite.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* isfinite().  PowerPC64/POWER8 version.
+   Copyright (C) 2014 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
@@ -16,32 +16,37 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <math.h>
+#include <sysdep.h>
 #include <math_ldbl_opt.h>
-#include <shlib-compat.h>
-#include "init-arch.h"
 
-extern __typeof (__finite) __finite_ppc64 attribute_hidden;
-extern __typeof (__finite) __finite_power7 attribute_hidden;
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
 
-libc_ifunc (__finite,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finite_ppc64);
+/* int [r3] __finite ([fp1] x)  */
 
+EALIGN (__finite, 4, 0)
+	CALL_MCOUNT 0
+	MFVSRD_R3_V1
+	lis     r9,0x8010
+	clrldi  r3,r3,1       /* r3 = r3 & 0x8000000000000000  */
+	rldicr  r9,r9,32,31   /* r9 = (r9 << 32) & 0xffffffff  */
+	add     r3,r3,r9
+	rldicl  r3,r3,1,63
+	blr
+END (__finite)
+
+hidden_def (__finite)
 weak_alias (__finite, finite)
 
-#ifdef NO_LONG_DOUBLE
-strong_alias (__finite, __finitel)
-weak_alias (__finite, finitel)
-#endif
+/* It turns out that the 'double' version will also always work for
+   single-precision.  */
+strong_alias (__finite, __finitef)
+hidden_def (__finitef)
+weak_alias (__finitef, finitef)
 
 #ifdef IS_IN_libm
 # if LONG_DOUBLE_COMPAT (libm, GLIBC_2_0)
-compat_symbol (libm, finite, finitel, GLIBC_2_0);
-# endif
-# if LONG_DOUBLE_COMPAT (libm, GLIBC_2_1)
-compat_symbol (libm, __finite, __finitel, GLIBC_2_1);
+compat_symbol (libm, __finite, __finitel, GLIBC_2_0)
+compat_symbol (libm, finite, finitel, GLIBC_2_0)
 # endif
 #else
 # if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S
new file mode 100644
index 0000000..54bd941
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_finitef.S
@@ -0,0 +1 @@
+/* This function uses the same code as s_finite.S.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=1cd3b05dda2dab30cb7658193cb1af8f594f52f3

commit 1cd3b05dda2dab30cb7658193cb1af8f594f52f3
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu Feb 27 09:45:41 2014 -0600

    PowerPC: Optimized isinf/isinff for POWER8
    
    This patch add a optimized isinf/isinff implementation for POWER8
    using the new Move From VSR Doubleword instruction to gains some
    cycles from FP to GRP register move.
    
    Backport of 4393fc119c34e97519b9b7a4fc94066b283be452

diff --git a/ChangeLog b/ChangeLog
index 6b9db7b..2dff388 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isinf power8
+	implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S: New file:
+	POWER8 isinf ifunc implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c (__isinf): Add
+	POWER8 implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c (__isinff):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S: New file:
+	POWER8 isinf implementation.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S: New file.
+
+2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
 	* sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h (INIT_ARCH):
 	Add hwcap2 initialization.
 	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isnan power8
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index 124d325..abbf7d0 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -4,7 +4,8 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 		   s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \
 		   s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
 		   s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \
-		   s_modff-power5+ s_modff-ppc64 s_isnan-power8
+		   s_modff-power5+ s_modff-ppc64 s_isnan-power8 \
+		   s_isinf-power8
 
 libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
@@ -22,7 +23,7 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
 			s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
 			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
-			s_isnan-power8
+			s_isnan-power8 s_isinf-power8
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S
similarity index 60%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
copy to sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S
index 1336feb..979816e 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf-power8.S
@@ -1,5 +1,5 @@
-/* Multiple versions of isinf.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* isinf().  PowerPC64/POWER8 version.
+   Copyright (C) 2014 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
@@ -16,18 +16,18 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <math.h>
+#include <sysdep.h>
 #include <math_ldbl_opt.h>
-#include <shlib-compat.h>
-#include "init-arch.h"
 
-extern __typeof (__isinff) __isinff_ppc64 attribute_hidden;
-/* The double-precision version also works for single-precision.  */
-extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+#undef hidden_def
+#define hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, alias)
+#undef strong_alias
+#define strong_alias(name, alias)
+#undef compat_symbol
+#define compat_symbol(lib, name, alias, ver)
 
-libc_ifunc (__isinff,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinff_ppc64);
+#define __isinf __isinf_power8
 
-weak_alias (__isinff, isinff)
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 1ee230b..e349a06 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
@@ -23,10 +23,13 @@
 
 extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
+extern __typeof (__isinf) __isinf_power8 attribute_hidden;
 
 libc_ifunc (__isinf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __isinf_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __isinf_power7
             : __isinf_ppc64);
 
 weak_alias (__isinf, isinf)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
index 1336feb..71da7a3 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
@@ -24,10 +24,13 @@
 extern __typeof (__isinff) __isinff_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+extern __typeof (__isinff) __isinf_power8 attribute_hidden;
 
 libc_ifunc (__isinff,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __isinf_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __isinf_power7
             : __isinff_ppc64);
 
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
similarity index 53%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
copy to sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
index 1ee230b..0e92af8 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S
@@ -1,5 +1,5 @@
-/* Multiple versions of isinf.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* isinf().  PowerPC64/POWER8 version.
+   Copyright (C) 2014 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
@@ -16,28 +16,45 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <math.h>
+#include <sysdep.h>
 #include <math_ldbl_opt.h>
-#include <shlib-compat.h>
-#include "init-arch.h"
-
-extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
-extern __typeof (__isinf) __isinf_power7 attribute_hidden;
-
-libc_ifunc (__isinf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinf_ppc64);
 
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+
+/* int [r3] __isinf([fp1] x)  */
+
+EALIGN (__isinf, 4, 0)
+	CALL_MCOUNT 0
+	MFVSRD_R3_V1
+	lis     r9,0x7ff0     /* r9 = 0x7ff0  */
+	rldicl  r10,r3,0,1    /* r10 = r3 & (0x8000000000000000)  */
+	sldi    r9,r9,32      /* r9 = r9 << 52  */
+	cmpd    cr7,r10,r9    /* fp1 & 0x7ff0000000000000 ?  */
+	beq     cr7,L(inf)
+	li      r3,0          /* Not inf  */
+	blr
+L(inf):
+	sradi   r3,r3,63      /* r3 = r3 >> 63  */
+	ori     r3,r3,1       /* r3 = r3 | 0x1  */
+	blr
+END (__isinf)
+
+hidden_def (__isinf)
 weak_alias (__isinf, isinf)
 
+/* It turns out that the 'double' version will also always work for
+   single-precision.  */
+strong_alias (__isinf, __isinff)
+hidden_def (__isinff)
+weak_alias (__isinff, isinff)
+
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isinf, __isinfl)
 weak_alias (__isinf, isinfl)
 #endif
 
 #ifndef IS_IN_libm
-# if LONG_DOUBLE_COMPAT (libc, GLIBC_2_0)
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
 compat_symbol (libc, __isinf, __isinfl, GLIBC_2_0);
 compat_symbol (libc, isinf, isinfl, GLIBC_2_0);
 # endif
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S
new file mode 100644
index 0000000..be759e0
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isinff.S
@@ -0,0 +1 @@
+/* This function uses the same code as s_isinf.S.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=65c8daedb68b74eae860f91dca226215cd80e348

commit 65c8daedb68b74eae860f91dca226215cd80e348
Author: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
Date:   Thu Feb 27 09:43:51 2014 -0600

    PowerPC: Optimized isnan/isnanf for POWER8
    
    This patch add a optimized isnan/isnanf implementation for POWER8
    using the new Move From VSR Doubleword instruction to gains some
    cycles from FP to GRP register move.
    
    Backport of 487972aea52004f604c2878c8c9d3e77670f2c32

diff --git a/ChangeLog b/ChangeLog
index b65e16f..6b9db7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2014-02-27  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h (INIT_ARCH):
+	Add hwcap2 initialization.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile: Add isnan power8
+	implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S: New file:
+	POWER8 isnan ifunc implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c (__isnan): Add
+	POWER8 implementation.
+	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c (__isnanf):
+	Likewise.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S: New file:
+	POWER8 isnan implementation.
+	* sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S: New file.
+
 2014-02-12  Dylan Alex Simon  <dylan@dylex.net>
 
 	[BZ #16545]
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
index 51a34f2..72d720d 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
@@ -36,6 +36,7 @@
    and fills the previous ones.  */
 #define INIT_ARCH() \
   unsigned long int hwcap = __GLRO(dl_hwcap); 			\
+  unsigned long int __attribute__((unused)) hwcap2 = __GLRO(dl_hwcap2); \
   if (hwcap & PPC_FEATURE_ARCH_2_06)				\
     hwcap |= PPC_FEATURE_ARCH_2_05 |				\
 	     PPC_FEATURE_POWER5_PLUS |				\
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
index ebf957e..124d325 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/Makefile
@@ -4,7 +4,7 @@ sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 		   s_copysign-ppc64 s_finite-power7 s_finite-ppc64 \
 		   s_finitef-ppc64 s_isinff-ppc64 s_isinf-power7 \
 		   s_isinf-ppc64 s_modf-power5+ s_modf-ppc64 \
-		   s_modff-power5+ s_modff-ppc64
+		   s_modff-power5+ s_modff-ppc64 s_isnan-power8
 
 libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_isnan-power5 s_isnan-ppc64 s_llround-power6x \
@@ -21,7 +21,8 @@ libm-sysdep_routines += s_isnan-power7 s_isnan-power6x s_isnan-power6 \
 			s_logbl-power7 s_logb-ppc64 s_logbf-ppc64 \
 			s_logbl-ppc64 s_modf-power5+ s_modf-ppc64 \
 			s_modff-power5+ s_modff-ppc64 e_hypot-ppc64 \
-			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7
+			e_hypot-power7 e_hypotf-ppc64 e_hypotf-power7 \
+			s_isnan-power8
 
 CFLAGS-s_logbf-power7.c = -mcpu=power7
 CFLAGS-s_logbl-power7.c = -mcpu=power7
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S
new file mode 100644
index 0000000..c176d5a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan-power8.S
@@ -0,0 +1,33 @@
+/* isnan().  PowerPC64/POWER7 version.
+   Copyright (C) 2014 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 <sysdep.h>
+#include <math_ldbl_opt.h>
+
+#undef hidden_def
+#define hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, alias)
+#undef strong_alias
+#define strong_alias(name, alias)
+#undef compat_symbol
+#define compat_symbol(lib, name, symbol, ver)
+
+#define __isnan __isnan_power8
+
+#include <sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S>
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index 0de833e..65a5ca0 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
@@ -26,16 +26,19 @@ extern __typeof (__isnan) __isnan_power5 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6x attribute_hidden;
 extern __typeof (__isnan) __isnan_power7 attribute_hidden;
+extern __typeof (__isnan) __isnan_power8 attribute_hidden;
 
 libc_ifunc (__isnan,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_POWER6_EXT)
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __isnan_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __isnan_power7 :
+		(hwcap & PPC_FEATURE_POWER6_EXT)
 		? __isnan_power6x :
-		(hwcap & PPC_FEATURE_ARCH_2_05)
-		  ? __isnan_power6 :
-		  (hwcap & PPC_FEATURE_POWER5)
-		    ? __isnan_power5
+		  (hwcap & PPC_FEATURE_ARCH_2_05)
+		    ? __isnan_power6 :
+		    (hwcap & PPC_FEATURE_POWER5)
+		      ? __isnan_power5
             : __isnan_ppc64);
 
 weak_alias (__isnan, isnan)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
index b237455..eb68a50 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -25,16 +25,19 @@ extern __typeof (__isnanf) __isnan_power5 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power6 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power6x attribute_hidden;
 extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
+extern __typeof (__isnanf) __isnan_power8 attribute_hidden;
 
 libc_ifunc (__isnanf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_POWER6_EXT)
-		? __isnan_power6x :
-		(hwcap & PPC_FEATURE_ARCH_2_05)
-		  ? __isnan_power6 :
-		  (hwcap & PPC_FEATURE_POWER5)
-		    ? __isnan_power5
+	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+	    ? __isnan_power8 :
+	      (hwcap & PPC_FEATURE_ARCH_2_06)
+	      ? __isnan_power7 :
+		(hwcap & PPC_FEATURE_POWER6_EXT)
+		  ? __isnan_power6x :
+		  (hwcap & PPC_FEATURE_ARCH_2_05)
+		    ? __isnan_power6 :
+		    (hwcap & PPC_FEATURE_POWER5)
+		      ? __isnan_power5
             : __isnan_ppc64);
 
 weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
similarity index 57%
copy from sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
copy to sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
index 0de833e..c1ca9a5 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S
@@ -1,5 +1,5 @@
-/* Multiple versions of isnan.
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* isnan().  PowerPC64/POWER8 version.
+   Copyright (C) 2014 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
@@ -16,29 +16,29 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <math.h>
+#include <sysdep.h>
 #include <math_ldbl_opt.h>
-#include <shlib-compat.h>
-#include "init-arch.h"
-
-extern __typeof (__isnan) __isnan_ppc64 attribute_hidden;
-extern __typeof (__isnan) __isnan_power5 attribute_hidden;
-extern __typeof (__isnan) __isnan_power6 attribute_hidden;
-extern __typeof (__isnan) __isnan_power6x attribute_hidden;
-extern __typeof (__isnan) __isnan_power7 attribute_hidden;
-
-libc_ifunc (__isnan,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_POWER6_EXT)
-		? __isnan_power6x :
-		(hwcap & PPC_FEATURE_ARCH_2_05)
-		  ? __isnan_power6 :
-		  (hwcap & PPC_FEATURE_POWER5)
-		    ? __isnan_power5
-            : __isnan_ppc64);
-
-weak_alias (__isnan, isnan)
+
+#define MFVSRD_R3_V1  .byte 0x7c,0x23,0x00,0x66     /* mfvsrd  r3,vs1  */
+
+/* int [r3] __isnan([f1] x)  */
+
+EALIGN (__isnan, 4, 0)
+	CALL_MCOUNT 0
+	MFVSRD_R3_V1
+	lis     r9,0x7ff0
+	clrldi  r3,r3,1       /* r3 = r3 & 0x8000000000000000  */
+	rldicr  r9,r9,32,31   /* r9 = (r9 << 32) & 0xffffffff  */
+	subf    r3,r3,r9
+	rldicl  r3,r3,1,63
+	blr
+END (__isnan)
+
+/* It turns out that the 'double' version will also always work for
+   single-precision.  */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isnan, __isnanl)
diff --git a/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S
new file mode 100644
index 0000000..b48c85e
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power8/fpu/s_isnanf.S
@@ -0,0 +1 @@
+/* This function uses the same code as s_isnan.S.  */

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=55e71ccf31c29a7839344f03e0a7437ea0f5f211

commit 55e71ccf31c29a7839344f03e0a7437ea0f5f211
Author: Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Date:   Fri Nov 15 07:44:20 2013 -0600

    Partially revert commit 2663b74f8103a2a8a46b4896439b7a452480fc7c
    
    This change is necessary in order to avoid the issue documented at
    http://sourceware.org/ml/libc-alpha/2013-05/msg00350.html.

diff --git a/localedata/locales/bo_CN b/localedata/locales/bo_CN
index d813c10..c573d3f 100644
--- a/localedata/locales/bo_CN
+++ b/localedata/locales/bo_CN
@@ -145,8 +145,7 @@ END LC_MEASUREMENT
 
 LC_NAME
 % FIXME
-
-name_fmt  ""
+name_fmt	"FIXME"
 % name_gen	"FIXME"
 % name_miss	"FIXME"
 % name_mr	"FIXME"
diff --git a/localedata/locales/bo_IN b/localedata/locales/bo_IN
index 8ab793c..a1a6280 100644
--- a/localedata/locales/bo_IN
+++ b/localedata/locales/bo_IN
@@ -71,7 +71,7 @@ END LC_MEASUREMENT
 
 LC_NAME
 % FIXME
-name_fmt	""
+name_fmt	"FIXME"
 % name_gen	"FIXME"
 % name_miss	"FIXME"
 % name_mr	"FIXME"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fbed4f13980bf4ebd7df59b0e52bd2a16875f0db

commit fbed4f13980bf4ebd7df59b0e52bd2a16875f0db
Author: Ryan S. Arnold <rsa@linux.vnet.ibm.com>
Date:   Fri Nov 15 07:42:33 2013 -0600

    Remove assert() if DT_RUNPATH and DT_RPATH flags are found in ld.so.

diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 20ccf30..7f51d90 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -130,8 +130,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   assert (info[DT_FLAGS] == NULL
 	  || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
   /* Flags must not be set for ld.so.  */
-  assert (info[DT_RUNPATH] == NULL);
-  assert (info[DT_RPATH] == NULL);
+  info[DT_RUNPATH] == NULL;
+  info[DT_RPATH] == NULL;
 #else
   if (info[DT_FLAGS] != NULL)
     {

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]