Skip to content

Commit

Permalink
S390: Optimize strcmp and wcscmp.
Browse files Browse the repository at this point in the history
This patch provides optimized versions of strcmp and wcscmp with the z13
vector instructions.

The architecture specific string.h had a typo, which leads to ommiting the
inline version in this file if __USE_STRING_INLINES is defined.
Tested this inline version by tweaking test-strcmp.c.

ChangeLog:

	* sysdeps/s390/multiarch/strcmp-vx.S: New File.
	* sysdeps/s390/multiarch/strcmp.c: Likewise.
	* sysdeps/s390/multiarch/wcscmp-c.c: Likewise.
	* sysdeps/s390/multiarch/wcscmp-vx.S: Likewise.
	* sysdeps/s390/multiarch/wcscmp.c: Likewise.
	* sysdeps/s390/s390-32/multiarch/strcmp.c: Likewise.
	* sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise.
	* sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcmp and
	wcscmp functions.
	* sysdeps/s390/multiarch/ifunc-impl-list.c
	(__libc_ifunc_impl_list): Add ifunc test for strcmp, wcscmp.
	* string/strcmp.c (STRCMP): Define and use macro.
	* benchtests/bench-wcscmp.c: New File.
	* benchtests/Makefile (wcsmbs-bench): Add wcscmp.
	* sysdeps/s390/bits/string.h: Fix typo: _HAVE_STRING_ARCH_strcmp
	instead of _HAVE_STRING_ARCH_memchr.
  • Loading branch information
Stefan Liebler authored and Andreas Krebbel committed Aug 26, 2015
1 parent e1fe911 commit 63724a6
Show file tree
Hide file tree
Showing 14 changed files with 430 additions and 6 deletions.
19 changes: 19 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
2015-08-26 Stefan Liebler <stli@linux.vnet.ibm.com>

* sysdeps/s390/multiarch/strcmp-vx.S: New File.
* sysdeps/s390/multiarch/strcmp.c: Likewise.
* sysdeps/s390/multiarch/wcscmp-c.c: Likewise.
* sysdeps/s390/multiarch/wcscmp-vx.S: Likewise.
* sysdeps/s390/multiarch/wcscmp.c: Likewise.
* sysdeps/s390/s390-32/multiarch/strcmp.c: Likewise.
* sysdeps/s390/s390-64/multiarch/strcmp.c: Likewise.
* sysdeps/s390/multiarch/Makefile (sysdep_routines): Add strcmp and
wcscmp functions.
* sysdeps/s390/multiarch/ifunc-impl-list.c
(__libc_ifunc_impl_list): Add ifunc test for strcmp, wcscmp.
* string/strcmp.c (STRCMP): Define and use macro.
* benchtests/bench-wcscmp.c: New File.
* benchtests/Makefile (wcsmbs-bench): Add wcscmp.
* sysdeps/s390/bits/string.h: Fix typo: _HAVE_STRING_ARCH_strcmp
instead of _HAVE_STRING_ARCH_memchr.

2015-08-26 Stefan Liebler <stli@linux.vnet.ibm.com>

* sysdeps/s390/multiarch/strncat-c.c: New File.
Expand Down
3 changes: 2 additions & 1 deletion benchtests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok \
strcoll
wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat
wcsmbs-bench := wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat \
wcscmp
string-bench-all := $(string-bench) ${wcsmbs-bench}

# We have to generate locales
Expand Down
20 changes: 20 additions & 0 deletions benchtests/bench-wcscmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Measure wcscmp functions.
Copyright (C) 2015 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 WIDE 1
#include "bench-strcmp.c"
6 changes: 5 additions & 1 deletion string/strcmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@

#undef strcmp

#ifndef STRCMP
# define STRCMP strcmp
#endif

/* Compare S1 and S2, returning less than, equal to or
greater than zero if S1 is lexicographically less than,
equal to or greater than S2. */
int
strcmp (const char *p1, const char *p2)
STRCMP (const char *p1, const char *p2)
{
const unsigned char *s1 = (const unsigned char *) p1;
const unsigned char *s2 = (const unsigned char *) p2;
Expand Down
4 changes: 2 additions & 2 deletions sysdeps/s390/bits/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ memchr (const void *__str, int __c, size_t __n)
}
#endif

/* Search N bytes of S for C. */
#define _HAVE_STRING_ARCH_memchr 1
/* Compare S1 and S2. */
#define _HAVE_STRING_ARCH_strcmp 1
#ifndef _FORCE_INLINES
__STRING_INLINE int
strcmp (const char *__s1, const char *__s2)
Expand Down
6 changes: 4 additions & 2 deletions sysdeps/s390/multiarch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ sysdep_routines += strlen strlen-vx strlen-c \
strncpy strncpy-vx \
stpncpy stpncpy-vx stpncpy-c \
strcat strcat-vx strcat-c \
strncat strncat-vx strncat-c
strncat strncat-vx strncat-c \
strcmp strcmp-vx
endif

ifeq ($(subdir),wcsmbs)
Expand All @@ -17,5 +18,6 @@ sysdep_routines += wcslen wcslen-vx wcslen-c \
wcsncpy wcsncpy-vx wcsncpy-c \
wcpncpy wcpncpy-vx wcpncpy-c \
wcscat wcscat-vx wcscat-c \
wcsncat wcsncat-vx wcsncat-c
wcsncat wcsncat-vx wcsncat-c \
wcscmp wcscmp-vx wcscmp-c
endif
3 changes: 3 additions & 0 deletions sysdeps/s390/multiarch/ifunc-impl-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_VX_IMPL (strncat);
IFUNC_VX_IMPL (wcsncat);

IFUNC_VX_IMPL (strcmp);
IFUNC_VX_IMPL (wcscmp);

#endif /* HAVE_S390_VX_ASM_SUPPORT */

return i;
Expand Down
116 changes: 116 additions & 0 deletions sysdeps/s390/multiarch/strcmp-vx.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* Vector optimized 32/64 bit S/390 version of strcmp.
Copyright (C) 2015 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 HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)

# include "sysdep.h"
# include "asm-syntax.h"

.text

/* int strcmp (const char *s1, const char *s2)
Compare two strings
Register usage:
-r1=loaded byte count s1
-r2=s1
-r3=s2
-r4=loaded byte coutn s2, tmp
-r5=current_len
-v16=part of s1
-v17=part of s2
-v18=index of unequal
*/
ENTRY(__strcmp_vx)
.machine "z13"
.machinemode "zarch_nohighgprs"

lghi %r5,0 /* current_len = 0. */

.Lloop:
vlbb %v16,0(%r5,%r2),6 /* Load s1 to block boundary. */
vlbb %v17,0(%r5,%r3),6 /* Load s2 to block boundary. */
lcbb %r1,0(%r5,%r2),6 /* Get loaded byte count of s1. */
jo .Llt16_1 /* Jump away if vr is not fully loaded. */
lcbb %r4,0(%r5,%r3),6
jo .Llt16_2 /* Jump away if vr is not fully loaded. */
/* Both vrs are fully loaded. */
aghi %r5,16
vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
jno .Lfound

vlbb %v16,0(%r5,%r2),6
vlbb %v17,0(%r5,%r3),6
lcbb %r1,0(%r5,%r2),6
jo .Llt16_1
lcbb %r4,0(%r5,%r3),6
jo .Llt16_2
aghi %r5,16
vfenezbs %v18,%v16,%v17
jno .Lfound

vlbb %v16,0(%r5,%r2),6
vlbb %v17,0(%r5,%r3),6
lcbb %r1,0(%r5,%r2),6
jo .Llt16_1
lcbb %r4,0(%r5,%r3),6
jo .Llt16_2
aghi %r5,16
vfenezbs %v18,%v16,%v17
jno .Lfound

vlbb %v16,0(%r5,%r2),6
vlbb %v17,0(%r5,%r3),6
lcbb %r1,0(%r5,%r2),6
jo .Llt16_1
lcbb %r4,0(%r5,%r3),6
jo .Llt16_2
aghi %r5,16
vfenezbs %v18,%v16,%v17
jno .Lfound
j .Lloop

.Llt16_1:
lcbb %r4,0(%r5,%r3),6 /* Get loaded byte count of s2. */
.Llt16_2:
clr %r1,%r4
locrh %r1,%r4 /* Get minimum of bytes loaded in s1/2. */
algfr %r5,%r1 /* Add smallest loaded bytes to current_len. */
vfenezbs %v18,%v16,%v17 /* Compare not equal with zero search. */
vlgvb %r4,%v18,7 /* Get not equal index or 16 if all equal. */
clrjl %r4,%r1,.Lfound /* Jump away if miscompare is within loaded
bytes. */
j .Lloop

.Lfound:
je .Lend_equal
lghi %r2,1
lghi %r1,-1
locgrl %r2,%r1
br %r14
.Lend_equal:
lghi %r2,0
br %r14
END(__strcmp_vx)

# define strcmp __strcmp_c
# undef libc_hidden_builtin_def
# define libc_hidden_builtin_def(name) strong_alias(__strcmp_c, __GI_strcmp)
#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */

#include <strcmp.S>
26 changes: 26 additions & 0 deletions sysdeps/s390/multiarch/strcmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Multiple versions of strcmp.
Copyright (C) 2015 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 HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
# include <string.h>
# include <ifunc-resolve.h>


# undef strcmp
s390_vx_libc_ifunc2 (__strcmp, strcmp)
#endif
32 changes: 32 additions & 0 deletions sysdeps/s390/multiarch/wcscmp-c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* Default wcscmp implementation for S/390.
Copyright (C) 2015 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 HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
# define WCSCMP __wcscmp_c

# include <wchar.h>
extern __typeof (wcscmp) __wcscmp_c;
# undef weak_alias
# define weak_alias(name, alias)
# ifdef SHARED
# undef libc_hidden_def
# define libc_hidden_def(name) \
__hidden_ver1 (__wcscmp_c, __GI___wcscmp, __wcscmp_c);
# endif /* SHARED */
# include <wcsmbs/wcscmp.c>
#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
Loading

0 comments on commit 63724a6

Please sign in to comment.