This is the mail archive of the libc-alpha@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]

[PATCH] Add versions of wcscpy, wcschr, wcsrchr for power6/power7.


Add versions of wcscpy, wcschr, wcsrchr for power6/power7.

Initially based on the versions found in wcsmbs/* ; these files
have been changed by hand unrolling, and adding some additional
variables to allow some read-ahead to occur, which then relieves
some of the wait-for-increment/wait-for-load/wait-for-compare-results
pressure that was slowing down every iteration through the while-loop.

For 64-bit Power7, These changes give an approx 20% throughput boost for
the wcschr and wcsrchr functions; and approx 40% boost for the
wcscpy function.  32-bit improvements appear to be slightly better
with ~ %30 and ~ %45 respectively.  Results for Power6 closely match
those for power7.

Passed make check with no regressions.

---

2012-06-12  Will Schmidt  <will_schmidt@vnet.ibm.com>

	* powerpc32/power6/wcschr.c: New file.
	* powerpc32/power6/wcscpy.c: New file.
	* powerpc32/power6/wcsrchr.c: New file.
	* powerpc64/power6/wcschr.c: New file.
	* powerpc64/power6/wcscpy.c: New file.
	* powerpc64/power6/wcsrchr.c: New file.
---
 sysdeps/powerpc/powerpc32/power6/wcschr.c  |   88 ++++++++++++++++++++++++
 sysdeps/powerpc/powerpc32/power6/wcscpy.c  |  104 ++++++++++++++++++++++++++++
 sysdeps/powerpc/powerpc32/power6/wcsrchr.c |   88 ++++++++++++++++++++++++
 sysdeps/powerpc/powerpc64/power6/wcschr.c  |    1 
 sysdeps/powerpc/powerpc64/power6/wcscpy.c  |    1 
 sysdeps/powerpc/powerpc64/power6/wcsrchr.c |    1 
 6 files changed, 283 insertions(+)
 create mode 100644 sysdeps/powerpc/powerpc32/power6/wcschr.c
 create mode 100644 sysdeps/powerpc/powerpc32/power6/wcscpy.c
 create mode 100644 sysdeps/powerpc/powerpc32/power6/wcsrchr.c
 create mode 100644 sysdeps/powerpc/powerpc64/power6/wcschr.c
 create mode 100644 sysdeps/powerpc/powerpc64/power6/wcscpy.c
 create mode 100644 sysdeps/powerpc/powerpc64/power6/wcsrchr.c

diff --git a/sysdeps/powerpc/powerpc32/power6/wcschr.c b/sysdeps/powerpc/powerpc32/power6/wcschr.c
new file mode 100644
index 0000000..a981427
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6/wcschr.c
@@ -0,0 +1,88 @@
+/* wcschr.c - Wide Character Search for powerpc32/power6.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <wchar.h>
+
+
+/* Find the first occurrence of WC in WCS.  */
+wchar_t *
+wcschr (wcs, wc)
+     register const wchar_t *wcs;
+     register const wchar_t wc;
+{
+  register const wchar_t *wcs2 = wcs + 1;
+
+  if (*wcs == wc)
+    return (wchar_t *) wcs;
+  if (*wcs == L'\0')
+    return NULL;
+
+  do
+    {
+      wcs += 2;
+
+      if (*wcs2 == wc)
+        return (wchar_t *) wcs2;
+      if (*wcs2 == L'\0')
+        return NULL;
+       wcs2 += 2;
+
+      if (*wcs == wc)
+        return (wchar_t *) wcs;
+      if (*wcs == L'\0')
+        return NULL;
+      wcs += 2;
+
+      if (*wcs2 == wc)
+        return (wchar_t *) wcs2;
+      if (*wcs2 == L'\0')
+        return NULL;
+      wcs2 += 2;
+
+      if (*wcs == wc)
+        return (wchar_t *) wcs;
+      if (*wcs == L'\0')
+        return NULL;
+      wcs += 2;
+
+      if (*wcs2 == wc)
+        return (wchar_t *) wcs2;
+      if (*wcs2 == L'\0')
+        return NULL;
+      wcs2 += 2;
+
+      if (*wcs == wc)
+        return (wchar_t *) wcs;
+      if (*wcs == L'\0')
+        return NULL;
+      wcs += 2;
+
+      if (*wcs2 == wc)
+        return (wchar_t *) wcs2;
+      if (*wcs2 == L'\0')
+        return NULL;
+      wcs2 += 2;
+
+      if (*wcs == wc)
+        return (wchar_t *) wcs;
+    }
+  while (*wcs != L'\0');
+
+  return NULL;
+}
+libc_hidden_def (wcschr)
diff --git a/sysdeps/powerpc/powerpc32/power6/wcscpy.c b/sysdeps/powerpc/powerpc32/power6/wcscpy.c
new file mode 100644
index 0000000..9bd9077
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6/wcscpy.c
@@ -0,0 +1,104 @@
+/* wcscpy.c - Wide Character Copy for powerpc32/power6.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <wchar.h>
+
+
+/* Copy SRC to DEST.  */
+wchar_t *
+wcscpy (dest, src)
+     wchar_t *dest;
+     const wchar_t *src;
+{
+  wint_t c,d;
+  wchar_t *wcp, *wcp2;
+
+  if (__alignof__ (wchar_t) >= sizeof (wchar_t))
+    {
+      const ptrdiff_t off = dest - src;
+
+      wcp = (wchar_t *) src;
+      wcp2 = wcp + 1 ;
+
+      do
+        {
+          d = *wcp;
+          wcp[off] = d;
+          if (d == L'\0')
+            return dest;
+          wcp += 2;
+
+          c = *wcp2;
+          wcp2[off] = c;
+          if (c == L'\0')
+            return dest;
+          wcp2 += 2;
+
+          d = *wcp;
+          wcp[off] = d;
+          if (d == L'\0')
+            return dest;
+          wcp += 2;
+
+          c = *wcp2;
+          wcp2[off] = c;
+          if (c == L'\0')
+            return dest;
+          wcp2 += 2;
+
+          d = *wcp;
+          wcp[off] = d;
+          if (d == L'\0')
+            return dest;
+          wcp += 2;
+
+          c = *wcp2;
+          wcp2[off] = c;
+          if (c == L'\0')
+            return dest;
+          wcp2 += 2;
+
+          d = *wcp;
+          wcp[off] = d;
+          if (d == L'\0')
+            return dest;
+          wcp += 2;
+
+          c = *wcp2;
+          wcp2[off] = c;
+          if (c == L'\0')
+            return dest;
+          wcp2 += 2;
+        }
+      while (c != L'\0');
+
+    }
+  else
+    {
+      wcp = dest;
+
+      do
+        {
+          c = *src++;
+          *wcp++ = c;
+        }
+      while (c != L'\0');
+    }
+  return dest;
+}
diff --git a/sysdeps/powerpc/powerpc32/power6/wcsrchr.c b/sysdeps/powerpc/powerpc32/power6/wcsrchr.c
new file mode 100644
index 0000000..f9db8f8
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6/wcsrchr.c
@@ -0,0 +1,88 @@
+/* wcsrchr.c - Wide Character Reverse Search for powerpc32/power6.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <wchar.h>
+
+
+/* Find the last occurrence of WC in WCS.  */
+wchar_t *
+wcsrchr (wcs, wc)
+     register const wchar_t *wcs;
+     register const wchar_t wc;
+{
+  register const wchar_t *wcs2 = wcs + 1;
+  const wchar_t *retval = NULL;
+
+  if (*wcs == wc)
+    retval = wcs;
+
+  if (*wcs == L'\0') return (wchar_t *) retval;
+
+  do
+    {
+    wcs+=2;
+
+    if (*wcs2 == wc)
+      retval = wcs2;
+    if (*wcs2 == L'\0')
+      return (wchar_t *) retval;
+    wcs2+=2;
+
+    if (*wcs == wc)
+      retval = wcs;
+    if (*wcs == L'\0')
+      return (wchar_t *) retval;
+    wcs+=2;
+
+    if (*wcs2 == wc)
+      retval = wcs2;
+    if (*wcs2 == L'\0')
+      return (wchar_t *) retval;
+    wcs2+=2;
+
+    if (*wcs == wc)
+      retval = wcs;
+    if (*wcs == L'\0')
+      return (wchar_t *) retval;
+    wcs+=2;
+
+    if (*wcs2 == wc)
+      retval = wcs2;
+    if (*wcs2 == L'\0')
+      return (wchar_t *) retval;
+    wcs2+=2;
+
+    if (*wcs == wc)
+      retval = wcs;
+    if (*wcs == L'\0')
+      return (wchar_t *) retval;
+    wcs+=2;
+
+    if (*wcs2 == wc)
+      retval = wcs2;
+    if (*wcs2 == L'\0')
+      return (wchar_t *) retval;
+    wcs2+=2;
+
+    if (*wcs == wc)
+      retval = wcs;
+    }
+  while (*wcs != L'\0');
+
+  return (wchar_t *) retval;
+}
diff --git a/sysdeps/powerpc/powerpc64/power6/wcschr.c b/sysdeps/powerpc/powerpc64/power6/wcschr.c
new file mode 100644
index 0000000..9136c02
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6/wcschr.c
@@ -0,0 +1 @@
+#include "../../powerpc32/power6/wcschr.c"
diff --git a/sysdeps/powerpc/powerpc64/power6/wcscpy.c b/sysdeps/powerpc/powerpc64/power6/wcscpy.c
new file mode 100644
index 0000000..57b706a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6/wcscpy.c
@@ -0,0 +1 @@
+#include "../../powerpc32/power6/wcscpy.c"
diff --git a/sysdeps/powerpc/powerpc64/power6/wcsrchr.c b/sysdeps/powerpc/powerpc64/power6/wcsrchr.c
new file mode 100644
index 0000000..2327c05
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6/wcsrchr.c
@@ -0,0 +1 @@
+#include "../../powerpc32/power6/wcsrchr.c"


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