diff options
author | Leandro Lupori <[email protected]> | 2020-01-15 19:53:03 +0000 |
---|---|---|
committer | Leandro Lupori <[email protected]> | 2020-01-15 19:53:03 +0000 |
commit | 181e35008cfbe18b2cfccb08d349415d8c21d8b6 (patch) | |
tree | b45061f4afc62ad53a6b4b5871098055830ae5a6 | |
parent | 075fb85f0904d5a9ddb59d03f78a5dcb4237903d (diff) | |
download | src-181e35008cfb.tar.gz src-181e35008cfb.zip |
[PPC64] strncpy optimization
Assembly optimization of strncpy for PowerPC64, using double words
instead of bytes to copy strings.
Submitted by: Leonardo Bianconi <leonardo.bianconi_eldorado.org.br> (original version)
Reviewed by: jhibbits
Differential Revision: https://reviews.freebsd.org/D15369
Notes
Notes:
svn path=/head/; revision=356766
-rw-r--r-- | lib/libc/powerpc64/string/Makefile.inc | 5 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy.c | 33 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy_arch_2_05.S | 131 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy_resolver.c | 48 | ||||
-rw-r--r-- | lib/libc/string/strncpy.c | 11 |
5 files changed, 226 insertions, 2 deletions
diff --git a/lib/libc/powerpc64/string/Makefile.inc b/lib/libc/powerpc64/string/Makefile.inc index 171e30bf160d..0e21da4286cb 100644 --- a/lib/libc/powerpc64/string/Makefile.inc +++ b/lib/libc/powerpc64/string/Makefile.inc @@ -3,4 +3,7 @@ MDSRCS+= \ strcpy_arch_2_05.S \ strcpy.c \ - strcpy_resolver.c + strcpy_resolver.c \ + strncpy_arch_2_05.S \ + strncpy.c \ + strncpy_resolver.c diff --git a/lib/libc/powerpc64/string/strncpy.c b/lib/libc/powerpc64/string/strncpy.c new file mode 100644 index 000000000000..6d53615962b1 --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy.c @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define WEAK_STRNCPY +#include "../../string/strncpy.c" diff --git a/lib/libc/powerpc64/string/strncpy_arch_2_05.S b/lib/libc/powerpc64/string/strncpy_arch_2_05.S new file mode 100644 index 000000000000..98139c35af8c --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy_arch_2_05.S @@ -0,0 +1,131 @@ +/*- + * Copyright (c) 2018 Instituto de Pesquisas Eldorado + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <machine/asm.h> +__FBSDID("$FreeBSD$"); + +ENTRY(__strncpy_arch_2_05) + stdu %r1,-40(%r1) + mflr %r0 + std %r0,16(%r1) + std %r3,32(%r1) + + xor %r6,%r6,%r6 /* fixed 0 reg */ + +/* align loop */ + addi %r3,%r3,-1 +.Lalign_loop: + /* len? */ + cmpdi %r5,0 + beq .Lexit + /* aligned? */ + andi. %r0,%r4,7 + beq .Ldw_copy + /* copy */ + lbz %r7,0(%r4) + stbu %r7,1(%r3) + addi %r4,%r4,1 + addi %r5,%r5,-1 + /* zero? */ + cmpdi %r7,0 + beq .Lzero + b .Lalign_loop + +/* dword copy loop */ +.Ldw_copy: + /* prepare src and dst to use load/store and update */ + addi %r3,%r3,-7 + addi %r4,%r4,-8 +.Ldw_copy_loop: + cmpdi %r5,8 + blt .Lbyte_copy + + ldu %r0,8(%r4) + /* check for 0 */ + cmpb %r7,%r0,%r6 + cmpdi %r7,0 + bne .Lbyte_copy_and_zero + /* copy to dst */ + stdu %r0,8(%r3) + addi %r5,%r5,-8 + b .Ldw_copy_loop + +/* Copy remaining src bytes, zero-out buffer + * Note: r5 will be >= 8 + */ +.Lbyte_copy_and_zero: + addi %r3,%r3,7 + addi %r4,%r4,-1 +.Lbyte_copy_and_zero_loop: + lbzu %r7,1(%r4) + stbu %r7,1(%r3) + addi %r5,%r5,-1 + cmpdi %r7,0 + beq .Lzero + b .Lbyte_copy_and_zero_loop + +/* zero-out remaining dst bytes */ +.Lzero: + addi %r3,%r3,1 + li %r4,0 + /* r5 has len already */ + bl memset + nop + b .Lexit + +/* copy remaining (< 8) bytes */ +.Lbyte_copy: + cmpdi %r5,0 + beq .Lexit + addi %r3,%r3,7 + addi %r4,%r4,7 + mtctr %r5 +.Lbyte_copy_loop: + lbzu %r7,1(%r4) + stbu %r7,1(%r3) + cmpdi %r7,0 + /* 0 found: zero out remaining bytes */ + beq .Lbyte_copy_zero + bdnz .Lbyte_copy_loop + b .Lexit +.Lbyte_copy_zero_loop: + stbu %r6,1(%r3) +.Lbyte_copy_zero: + bdnz .Lbyte_copy_zero_loop + +.Lexit: + /* epilogue */ + ld %r3,32(%r1) + ld %r0,16(%r1) + mtlr %r0 + addi %r1,%r1,40 + blr + +END(__strncpy_arch_2_05) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/string/strncpy_resolver.c b/lib/libc/powerpc64/string/strncpy_resolver.c new file mode 100644 index 000000000000..ee4a95b6418b --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy_resolver.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2019 Leandro Lupori + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <machine/cpu.h> +#include <machine/ifunc.h> + +char * +__strncpy_arch_2_05(char * restrict dst, const char * restrict src, size_t len); + +char * +__strncpy(char * restrict dst, const char * restrict src, size_t len); + +DEFINE_UIFUNC(, char *, strncpy, + (char * restrict, const char * restrict, size_t)) +{ + if (cpu_features & PPC_FEATURE_ARCH_2_05) + return (__strncpy_arch_2_05); + else + return (__strncpy); +} diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c index 3c02ccae41d8..2ffce161c5c5 100644 --- a/lib/libc/string/strncpy.c +++ b/lib/libc/string/strncpy.c @@ -44,8 +44,17 @@ __FBSDID("$FreeBSD$"); * Copy src to dst, truncating or null-padding to always copy n bytes. * Return dst. */ +#ifdef WEAK_STRNCPY +__weak_reference(__strncpy, strncpy); +#endif + char * -strncpy(char * __restrict dst, const char * __restrict src, size_t n) +#ifdef WEAK_STRNCPY +__strncpy +#else +strncpy +#endif +(char * __restrict dst, const char * __restrict src, size_t n) { if (n != 0) { char *d = dst; |