diff options
Diffstat (limited to 'lib/libc/powerpc64/string')
-rw-r--r-- | lib/libc/powerpc64/string/Makefile.inc | 16 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/bcopy.S | 338 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/bcopy_resolver.c | 70 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/bcopy_vsx.S | 59 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memcpy.S | 131 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memcpy_resolver.c | 3 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memcpy_vsx.S | 64 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memmove.S | 3 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memmove_resolver.c | 3 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/memmove_vsx.S | 4 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strcpy.c | 30 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strcpy_arch_2_05.S | 202 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strcpy_resolver.c | 44 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy.c | 30 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy_arch_2_05.S | 129 | ||||
-rw-r--r-- | lib/libc/powerpc64/string/strncpy_resolver.c | 45 |
16 files changed, 1171 insertions, 0 deletions
diff --git a/lib/libc/powerpc64/string/Makefile.inc b/lib/libc/powerpc64/string/Makefile.inc new file mode 100644 index 000000000000..c9d7c9d71676 --- /dev/null +++ b/lib/libc/powerpc64/string/Makefile.inc @@ -0,0 +1,16 @@ +MDSRCS+= \ + bcopy.S \ + bcopy_vsx.S \ + bcopy_resolver.c \ + memcpy.S \ + memcpy_vsx.S \ + memcpy_resolver.c \ + memmove.S \ + memmove_vsx.S \ + memmove_resolver.c \ + strncpy_arch_2_05.S \ + strncpy.c \ + strncpy_resolver.c \ + strcpy_arch_2_05.S \ + strcpy.c \ + strcpy_resolver.c diff --git a/lib/libc/powerpc64/string/bcopy.S b/lib/libc/powerpc64/string/bcopy.S new file mode 100644 index 000000000000..6f6223214e26 --- /dev/null +++ b/lib/libc/powerpc64/string/bcopy.S @@ -0,0 +1,338 @@ +/*- + * 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> +#define BLOCK_SIZE_BITS 6 +#define BLOCK_SIZE (1 << BLOCK_SIZE_BITS) +#define BLOCK_SIZE_MASK (BLOCK_SIZE - 1) + +/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults.*/ +#ifndef ALIGN_MASK +#define ALIGN_MASK 0x7 +#endif + +#define MULTI_PHASE_THRESHOLD 512 + +#ifndef FN_NAME +#ifdef MEMMOVE +#define FN_NAME __memmove +WEAK_REFERENCE(__memmove, memmove); +#else +#define FN_NAME __bcopy +WEAK_REFERENCE(__bcopy, bcopy); +#endif +#endif + +/* + * r3: dst + * r4: src + * r5: len + */ + +ENTRY(FN_NAME) + cmpld %r3, %r4 /* src == dst? nothing to do */ + beqlr- + cmpdi %r5, 0 /* len == 0? nothing to do */ + beqlr- + +#ifdef MEMMOVE + std %r3, -8(%r1) /* save dst */ +#else /* bcopy: swap src/dst */ + mr %r0, %r3 + mr %r3, %r4 + mr %r4, %r0 +#endif + + /* First check for relative alignment, if unaligned copy one byte at a time */ + andi. %r8, %r3, ALIGN_MASK + andi. %r7, %r4, ALIGN_MASK + cmpd %r7, %r8 + bne .Lunaligned + + + cmpldi %r5, MULTI_PHASE_THRESHOLD + bge .Lmulti_phase + b .Lfast_copy + +.Lunaligned: + /* forward or backward copy? */ + cmpd %r4, %r3 + blt .Lbackward_unaligned + + /* Just need to setup increment and jump to copy */ + li %r0, 1 + mtctr %r5 + b .Lsingle_1_loop + +.Lbackward_unaligned: + /* advance src and dst to last byte, set decrement and jump to copy */ + add %r3, %r3, %r5 + addi %r3, %r3, -1 + add %r4, %r4, %r5 + addi %r4, %r4, -1 + li %r0, -1 + mtctr %r5 + b .Lsingle_1_loop + +.Lfast_copy: + /* align src */ + cmpd %r4, %r3 /* forward or backward copy? */ + blt .Lbackward_align + + .align 5 +.Lalign: + andi. %r0, %r4, 15 + beq .Lsingle_copy + lbz %r0, 0(%r4) + addi %r4, %r4, 1 + stb %r0, 0(%r3) + addi %r3, %r3, 1 + addi %r5, %r5, -1 + cmpdi %r5, 0 + beq- .Ldone + b .Lalign + +.Lbackward_align: + /* advance src and dst to end (past last byte) */ + add %r3, %r3, %r5 + add %r4, %r4, %r5 + .align 5 +.Lbackward_align_loop: + andi. %r0, %r4, 15 + beq .Lbackward_single_copy + lbzu %r0, -1(%r4) + addi %r5, %r5, -1 + stbu %r0, -1(%r3) + cmpdi %r5, 0 + beq- .Ldone + b .Lbackward_align_loop + +.Lsingle_copy: + /* forward copy */ + li %r0, 1 + li %r8, 16 + li %r9, 0 + b .Lsingle_phase + +.Lbackward_single_copy: + /* backward copy */ + li %r0, -1 + li %r8, -16 + li %r9, -15 + /* point src and dst to last byte */ + addi %r3, %r3, -1 + addi %r4, %r4, -1 + +.Lsingle_phase: + srdi. %r6, %r5, 4 /* number of 16-bytes */ + beq .Lsingle_1 + + /* pre-adjustment */ + add %r3, %r3, %r9 + add %r4, %r4, %r9 + + mtctr %r6 + .align 5 +.Lsingle_16_loop: + ld %r6, 0(%r4) + ld %r7, 8(%r4) + add %r4, %r4, %r8 + std %r6, 0(%r3) + std %r7, 8(%r3) + add %r3, %r3, %r8 + bdnz .Lsingle_16_loop + + /* post-adjustment */ + sub %r3, %r3, %r9 + sub %r4, %r4, %r9 + +.Lsingle_1: + andi. %r6, %r5, 0x0f /* number of 1-bytes */ + beq .Ldone /* 1-bytes == 0? done */ + + mtctr %r6 + .align 5 +.Lsingle_1_loop: + lbz %r6, 0(%r4) + add %r4, %r4, %r0 /* increment */ + stb %r6, 0(%r3) + add %r3, %r3, %r0 /* increment */ + bdnz .Lsingle_1_loop + +.Ldone: +#ifdef MEMMOVE + ld %r3, -8(%r1) /* restore dst */ +#endif + blr + + +.Lmulti_phase: + /* set up multi-phase copy parameters */ + + /* r7 = bytes before the aligned section of the buffer */ + andi. %r6, %r4, 15 + subfic %r7, %r6, 16 + /* r8 = bytes in and after the aligned section of the buffer */ + sub %r8, %r5, %r7 + /* r9 = bytes after the aligned section of the buffer */ + andi. %r9, %r8, BLOCK_SIZE_MASK + /* r10 = BLOCKS in the aligned section of the buffer */ + srdi %r10, %r8, BLOCK_SIZE_BITS + + /* forward or backward copy? */ + cmpd %r4, %r3 + blt .Lbackward_multi_copy + + /* set up forward copy parameters */ + std %r7, -32(%r1) /* bytes to copy in phase 1 */ + std %r10, -40(%r1) /* BLOCKS to copy in phase 2 */ + std %r9, -48(%r1) /* bytes to copy in phase 3 */ + + li %r0, 1 /* increment for phases 1 and 3 */ + li %r5, BLOCK_SIZE /* increment for phase 2 */ + + /* op offsets for phase 2 */ + li %r7, 0 + li %r8, 16 + li %r9, 32 + li %r10, 48 + + std %r8, -16(%r1) /* 16-byte increment (16) */ + std %r7, -24(%r1) /* 16-byte pre/post adjustment (0) */ + + b .Lphase1 + +.Lbackward_multi_copy: + /* set up backward copy parameters */ + std %r9, -32(%r1) /* bytes to copy in phase 1 */ + std %r10, -40(%r1) /* BLOCKS to copy in phase 2 */ + std %r7, -48(%r1) /* bytes to copy in phase 3 */ + + li %r0, -1 /* increment for phases 1 and 3 */ + add %r6, %r5, %r0 /* r6 = len - 1 */ + li %r5, -BLOCK_SIZE /* increment for phase 2 */ + /* advance src and dst to the last position */ + add %r3, %r3, %r6 + add %r4, %r4, %r6 + + /* op offsets for phase 2 */ + li %r7, -15 + li %r8, -31 + li %r9, -47 + li %r10, -63 + + add %r6, %r7, %r0 /* r6 = -16 */ + std %r6, -16(%r1) /* 16-byte increment (-16) */ + std %r7, -24(%r1) /* 16-byte pre/post adjustment (-15) */ + +.Lphase1: + ld %r6, -32(%r1) /* bytes to copy in phase 1 */ + cmpldi %r6, 0 /* r6 == 0? skip phase 1 */ + beq+ .Lphase2 + + mtctr %r6 + .align 5 +.Lphase1_loop: + lbz %r6, 0(%r4) + add %r4, %r4, %r0 /* phase 1 increment */ + stb %r6, 0(%r3) + add %r3, %r3, %r0 /* phase 1 increment */ + bdnz .Lphase1_loop + +.Lphase2: + ld %r6, -40(%r1) /* BLOCKS to copy in phase 2 */ + cmpldi %r6, 0 /* %r6 == 0? skip phase 2 */ + beq .Lphase3 + +#ifdef FN_PHASE2 +FN_PHASE2 +#else + /* save registers */ + std %r14, -56(%r1) + std %r15, -64(%r1) + std %r16, -72(%r1) + std %r17, -80(%r1) + std %r18, -88(%r1) + std %r19, -96(%r1) + std %r20, -104(%r1) + std %r21, -112(%r1) + + addi %r18, %r7, 8 + addi %r19, %r8, 8 + addi %r20, %r9, 8 + addi %r21, %r10, 8 + + mtctr %r6 + .align 5 +.Lphase2_loop: + ldx %r14, %r7, %r4 + ldx %r15, %r18, %r4 + ldx %r16, %r8, %r4 + ldx %r17, %r19, %r4 + stdx %r14, %r7, %r3 + stdx %r15, %r18, %r3 + stdx %r16, %r8, %r3 + stdx %r17, %r19, %r3 + + ldx %r14, %r9, %r4 + ldx %r15, %r20, %r4 + ldx %r16, %r10, %r4 + ldx %r17, %r21, %r4 + stdx %r14, %r9, %r3 + stdx %r15, %r20, %r3 + stdx %r16, %r10, %r3 + stdx %r17, %r21, %r3 + + add %r4, %r4, %r5 /* phase 2 increment */ + add %r3, %r3, %r5 /* phase 2 increment */ + + bdnz .Lphase2_loop + + /* restore registers */ + ld %r14, -56(%r1) + ld %r15, -64(%r1) + ld %r16, -72(%r1) + ld %r17, -80(%r1) + ld %r18, -88(%r1) + ld %r19, -96(%r1) + ld %r20, -104(%r1) + ld %r21, -112(%r1) +#endif + +.Lphase3: + /* load registers for transitioning into the single-phase logic */ + ld %r5, -48(%r1) /* bytes to copy in phase 3 */ + ld %r8, -16(%r1) /* 16-byte increment */ + ld %r9, -24(%r1) /* 16-byte pre/post adjustment */ + b .Lsingle_phase + +END(FN_NAME) + + .section .note.GNU-stack,"",%progbits + diff --git a/lib/libc/powerpc64/string/bcopy_resolver.c b/lib/libc/powerpc64/string/bcopy_resolver.c new file mode 100644 index 000000000000..c99c53b2f9b3 --- /dev/null +++ b/lib/libc/powerpc64/string/bcopy_resolver.c @@ -0,0 +1,70 @@ +/*- + * 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/cpu.h> +#include <machine/ifunc.h> + +#define _CAT(a,b) a##b +#define CAT(a,b) _CAT(a,b) +#define CAT3(a,b,c) CAT(CAT(a,b),c) + +#ifdef MEMCOPY +#define FN_NAME memcpy +#define FN_RET void * +#define FN_PARAMS (void *dst, const void *src, size_t len) + +#elif defined(MEMMOVE) +#define FN_NAME memmove +#define FN_RET void * +#define FN_PARAMS (void *dst, const void *src, size_t len) + +#else +#define FN_NAME bcopy +#define FN_RET void +#define FN_PARAMS (const void *src, void *dst, size_t len) +#endif + +#define FN_NAME_NOVSX CAT(__, FN_NAME) +#define FN_NAME_VSX CAT3(__, FN_NAME, _vsx) + +FN_RET FN_NAME_NOVSX FN_PARAMS; +FN_RET FN_NAME_VSX FN_PARAMS; + +DEFINE_UIFUNC(, FN_RET, FN_NAME, FN_PARAMS) +{ + /* VSX instructions were added in POWER ISA 2.06, + * however it requires data to be word-aligned. + * Since POWER ISA 2.07B this is solved transparently + * by the hardware + */ + if (cpu_features & PPC_FEATURE_HAS_VSX) + return (FN_NAME_VSX); + else + return (FN_NAME_NOVSX); +} diff --git a/lib/libc/powerpc64/string/bcopy_vsx.S b/lib/libc/powerpc64/string/bcopy_vsx.S new file mode 100644 index 000000000000..f1740d3db7b5 --- /dev/null +++ b/lib/libc/powerpc64/string/bcopy_vsx.S @@ -0,0 +1,59 @@ +/*- + * 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. + */ + +#ifndef FN_NAME +#define FN_NAME __bcopy_vsx +#endif + +/* + * r3: dst + * r4: src + * r5: block increment + * r6: blocks to copy + * r7/r8/r9/r10: 16-byte offsets to copy + */ + +#define FN_PHASE2 \ + mtctr %r6 ;\ + .align 5 ;\ +.Lphase2_loop: ;\ + lxvd2x %vs6, %r7, %r4 ;\ + lxvd2x %vs7, %r8, %r4 ;\ + lxvd2x %vs8, %r9, %r4 ;\ + lxvd2x %vs9, %r10, %r4 ;\ + stxvd2x %vs6, %r7, %r3 ;\ + stxvd2x %vs7, %r8, %r3 ;\ + stxvd2x %vs8, %r9, %r3 ;\ + stxvd2x %vs9, %r10, %r3 ;\ + /* phase 2 increment */ ;\ + add %r4, %r4, %r5 ;\ + add %r3, %r3, %r5 ;\ + \ + bdnz .Lphase2_loop ;\ + +#include "bcopy.S" diff --git a/lib/libc/powerpc64/string/memcpy.S b/lib/libc/powerpc64/string/memcpy.S new file mode 100644 index 000000000000..28f3f2bb0ab4 --- /dev/null +++ b/lib/libc/powerpc64/string/memcpy.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> +#ifndef FN_NAME +#define FN_NAME __memcpy +WEAK_REFERENCE(__memcpy, memcpy); +#define BLOCK_BITS 4 +#endif + +#define BLOCK_BYTES (1 << BLOCK_BITS) +#define BLOCK_MASK (BLOCK_BYTES - 1) + +/* Minimum 8 byte alignment, to avoid cache-inhibited alignment faults. */ +#ifndef ALIGN_MASK +#define ALIGN_MASK 0x7 +#endif + +/* + * r3: dst + * r4: src + * r5: len + */ +ENTRY(FN_NAME) + cmpdi %r5, 0 /* len == 0? nothing to do */ + beqlr- + + /* If src and dst are relatively misaligned, do byte copies. */ + andi. %r8, %r3, ALIGN_MASK + andi. %r7, %r4, ALIGN_MASK + cmpd %r8, %r7 + mr %r7, %r5 + mr %r8, %r3 /* save dst */ + bne .Lcopy_remaining_fix_index_byte + + /* align src */ +.Lalignment_loop: + lbz %r6, 0(%r4) + stb %r6, 0(%r3) + addi %r3, %r3, 1 + addi %r4, %r4, 1 + addi %r5, %r5, -1 + cmpdi %r5, 0 + beq .Lexit + andi. %r0, %r4, BLOCK_MASK + bne .Lalignment_loop + + /* r7 = remaining, non-block, bytes */ + andi. %r7, %r5, BLOCK_MASK + + /* Check if there are blocks of BLOCK_BYTES to be copied */ + xor. %r5, %r5, %r7 + beq .Lcopy_remaining_fix_index_byte + +#ifdef FN_COPY_LOOP +FN_COPY_LOOP +#else + /* Setup to copy word with ldu and stdu */ + ld %r6, 0(%r4) + ld %r9, 8(%r4) + std %r6, 0(%r3) + std %r9, 8(%r3) + addi %r5, %r5, -BLOCK_BYTES + cmpd %r5, 0 + beq .Lcopy_remaining_fix_index_word + + srdi %r5, %r5, BLOCK_BITS + mtctr %r5 +.Lcopy_word: + ldu %r6, 16(%r4) + ld %r9, 8(%r4) + stdu %r6, 16(%r3) + std %r9, 8(%r3) + bdnz .Lcopy_word + +.Lcopy_remaining_fix_index_word: + /* Check if there are remaining bytes */ + cmpd %r7, 0 + beq .Lexit + addi %r3, %r3, BLOCK_MASK + addi %r4, %r4, BLOCK_MASK + b .Lcopy_remaining +#endif + +.Lcopy_remaining_fix_index_byte: + addi %r4, %r4, -1 + addi %r3, %r3, -1 + + /* Copy remaining bytes */ +.Lcopy_remaining: + mtctr %r7 +.Lcopy_remaining_loop: + lbzu %r6, 1(%r4) + stbu %r6, 1(%r3) + bdnz .Lcopy_remaining_loop + +.Lexit: + /* Restore dst */ + mr %r3, %r8 + blr + +END(FN_NAME) + + .section .note.GNU-stack,"",%progbits + diff --git a/lib/libc/powerpc64/string/memcpy_resolver.c b/lib/libc/powerpc64/string/memcpy_resolver.c new file mode 100644 index 000000000000..d1ac75edf5b4 --- /dev/null +++ b/lib/libc/powerpc64/string/memcpy_resolver.c @@ -0,0 +1,3 @@ + +#define MEMCOPY +#include "bcopy_resolver.c" diff --git a/lib/libc/powerpc64/string/memcpy_vsx.S b/lib/libc/powerpc64/string/memcpy_vsx.S new file mode 100644 index 000000000000..69554e026f35 --- /dev/null +++ b/lib/libc/powerpc64/string/memcpy_vsx.S @@ -0,0 +1,64 @@ +/*- + * 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. + */ + +#define FN_NAME __memcpy_vsx +#define BLOCK_BITS 6 +#define ALIGN_MASK 0xf + +/* + * r5: bytes to copy (multiple of BLOCK_BYTES) + * + */ +#define FN_COPY_LOOP \ + /* Load CTR with number of blocks */ \ + srdi %r5, %r5, BLOCK_BITS ;\ + mtctr %r5 ;\ + /* Prepare indexes to load and store data */ \ + xor %r6, %r6, %r6 ;\ + li %r9, 16 ;\ + li %r10, 32 ;\ + li %r11, 48 ;\ +.Lcopy_vsx_loop: \ + lxvd2x %vs6, %r6, %r4 ;\ + lxvd2x %vs7, %r9, %r4 ;\ + lxvd2x %vs8, %r10, %r4 ;\ + lxvd2x %vs9, %r11, %r4 ;\ + stxvd2x %vs6, %r6, %r3 ;\ + stxvd2x %vs7, %r9, %r3 ;\ + stxvd2x %vs8, %r10, %r3 ;\ + stxvd2x %vs9, %r11, %r3 ;\ + \ + addi %r3, %r3, BLOCK_BYTES ;\ + addi %r4, %r4, BLOCK_BYTES ;\ + bdnz .Lcopy_vsx_loop ;\ + \ + /* Check if there is remaining bytes */ \ + cmpd %r7, 0 ;\ + beq .Lexit ;\ + +#include "memcpy.S" diff --git a/lib/libc/powerpc64/string/memmove.S b/lib/libc/powerpc64/string/memmove.S new file mode 100644 index 000000000000..3d49c57100df --- /dev/null +++ b/lib/libc/powerpc64/string/memmove.S @@ -0,0 +1,3 @@ + +#define MEMMOVE +#include "bcopy.S" diff --git a/lib/libc/powerpc64/string/memmove_resolver.c b/lib/libc/powerpc64/string/memmove_resolver.c new file mode 100644 index 000000000000..fcb11ee0ae43 --- /dev/null +++ b/lib/libc/powerpc64/string/memmove_resolver.c @@ -0,0 +1,3 @@ + +#define MEMMOVE +#include "bcopy_resolver.c" diff --git a/lib/libc/powerpc64/string/memmove_vsx.S b/lib/libc/powerpc64/string/memmove_vsx.S new file mode 100644 index 000000000000..9e7d51ce4683 --- /dev/null +++ b/lib/libc/powerpc64/string/memmove_vsx.S @@ -0,0 +1,4 @@ + +#define MEMMOVE +#define FN_NAME __memmove_vsx +#include "bcopy_vsx.S" diff --git a/lib/libc/powerpc64/string/strcpy.c b/lib/libc/powerpc64/string/strcpy.c new file mode 100644 index 000000000000..d0be3ca468a0 --- /dev/null +++ b/lib/libc/powerpc64/string/strcpy.c @@ -0,0 +1,30 @@ +/*- + * 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. + */ + + +#define WEAK_STRCPY +#include "../../string/strcpy.c" diff --git a/lib/libc/powerpc64/string/strcpy_arch_2_05.S b/lib/libc/powerpc64/string/strcpy_arch_2_05.S new file mode 100644 index 000000000000..36728fa0b40f --- /dev/null +++ b/lib/libc/powerpc64/string/strcpy_arch_2_05.S @@ -0,0 +1,202 @@ +/*- + * 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> +#if 0 + RCSID("$NetBSD: strcpy.S,v 1.0 2018/05/08 13:00:49 lbianc Exp $") +#endif + +ENTRY(__strcpy_arch_2_05) + mr %r8, %r3 + +/* + * Aligning the reading address, even if it is already aligned to avoid + * performance degradation with strings with 8 bytes or less. + */ +.Lalignment: + lbz %r0,0(%r4) + cmpdi cr7,%r0,0 + stb %r0,0(%r8) + beq cr7,.Lexit + addi %r4,%r4,1 + addi %r8,%r8,1 + andi. %r0,%r4,0x7 + bne .Lalignment + +/* Copy by double word with aligned address. */ +.Lcopy_dw: + ld %r0,0(%r4) + xor %r6,%r6,%r6 + cmpb %r5,%r0,%r6 + cmpdi cr7,%r5,0 + bne cr7,.Lcheck_zero + /* Backward r8 to use stdu instruction in Lcopy_dw_loop */ + addi %r8,%r8,-8 +.Lcopy_dw_loop: + stdu %r0,8(%r8) + ldu %r0,8(%r4) + cmpb %r5,%r0,%r6 + cmpdi cr7,%r5,0 + beq cr7,.Lcopy_dw_loop + + addi %r8,%r8,8 /* Forward r8 to use std instruction. */ +#if defined(__BIG_ENDIAN__) +/* Find where the zero is located. */ +.Lcheck_zero: + rldicr. %r5,%r0,0,7 + beq .Lfound_on_byte_0 + rldicr. %r7,%r0,8,7 + beq .Lfound_on_byte_1 + rldicr. %r7,%r0,16,7 + beq .Lfound_on_byte_2 + rldicr. %r7,%r0,24,7 + beq .Lfound_on_byte_3 + andis. %r7,%r0,0xff00 + beq .Lfound_on_byte_4 + andis. %r7,%r0,0xff + beq .Lfound_on_byte_5 + andi. %r7,%r0,0xff00 + beq .Lfound_on_byte_6 + +/* Copy the last string bytes according to the string end position. */ +.Lfound_on_byte_7: + std %r0,0(%r8) + b .Lexit + +.Lfound_on_byte_6: + srdi %r6,%r0,32 + stw %r6,0(%r8) + srdi %r6,%r0,16 + sth %r6,4(%r8) + srdi %r6,%r0,8 + stb %r6,6(%r8) + b .Lexit + +.Lfound_on_byte_5: + srdi %r6,%r0,32 + stw %r6,0(%r8) + srdi %r6,%r0,16 + sth %r6,4(%r8) + b .Lexit + +.Lfound_on_byte_4: + srdi %r6,%r0,32 + stw %r6,0(%r8) + srdi %r6,%r0,24 + stb %r6,4(%r8) + b .Lexit + +.Lfound_on_byte_3: + srdi %r6,%r0,32 + stw %r6,0(%r8) + b .Lexit + +.Lfound_on_byte_2: + srdi %r6,%r0,48 + sth %r6,0(%r8) + srdi %r6,%r0,40 + stb %r6,2(%r8) + b .Lexit + +.Lfound_on_byte_1: + srdi %r6,%r0,48 + sth %r6,0(%r8) + b .Lexit + +.Lfound_on_byte_0: + srdi %r6,%r0,56 + stb %r6,0(%r8) +#elif defined(__LITTLE_ENDIAN__) +/* Find where the zero is located. */ +.Lcheck_zero: + andi. %r7,%r0,0xff + beq .Lfound_on_byte_0 + andi. %r7,%r0,0xff00 + beq .Lfound_on_byte_1 + andis. %r7,%r0,0xff + beq .Lfound_on_byte_2 + andis. %r7,%r0,0xff00 + beq .Lfound_on_byte_3 + rldicr. %r7,%r0,24,7 + beq .Lfound_on_byte_4 + rldicr. %r7,%r0,16,7 + beq .Lfound_on_byte_5 + rldicr. %r7,%r0,8,7 + beq .Lfound_on_byte_6 + +/* Copy the last string bytes according to the string end position. */ +.Lfound_on_byte_7: + std %r0,0(%r8) + b .Lexit + +.Lfound_on_byte_6: + stw %r0,0(%r8) + srdi %r6,%r0,32 + sth %r6,4(%r8) + srdi %r6,%r0,48 + stb %r6,6(%r8) + b .Lexit + +.Lfound_on_byte_5: + stw %r0,0(%r8) + srdi %r6,%r0,32 + sth %r6,4(%r8) + b .Lexit + +.Lfound_on_byte_4: + stw %r0,0(%r8) + srdi %r6,%r0,32 + stb %r6,4(%r8) + b .Lexit + +.Lfound_on_byte_3: + stw %r0,0(%r8) + b .Lexit + +.Lfound_on_byte_2: + sth %r0,0(%r8) + srdi %r6,%r0,16 + stb %r6,2(%r8) + b .Lexit + +.Lfound_on_byte_1: + sth %r0,0(%r8) + b .Lexit + +.Lfound_on_byte_0: + stb %r0,0(%r8) +#else +#error "Unable to determine Endianness" +#endif +.Lexit: + blr + +END(__strcpy_arch_2_05) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpc64/string/strcpy_resolver.c b/lib/libc/powerpc64/string/strcpy_resolver.c new file mode 100644 index 000000000000..7a64ce41c7e4 --- /dev/null +++ b/lib/libc/powerpc64/string/strcpy_resolver.c @@ -0,0 +1,44 @@ +/*- + * 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 <machine/cpu.h> +#include <machine/ifunc.h> + +char * +__strcpy_arch_2_05(char * restrict dst, const char * restrict src); + +char * +__strcpy(char * restrict dst, const char * restrict src); + +DEFINE_UIFUNC(, char *, strcpy, (char * restrict, const char * restrict)) +{ + if (cpu_features & PPC_FEATURE_ARCH_2_05) + return (__strcpy_arch_2_05); + else + return (__strcpy); +} diff --git a/lib/libc/powerpc64/string/strncpy.c b/lib/libc/powerpc64/string/strncpy.c new file mode 100644 index 000000000000..aef3fb88724a --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy.c @@ -0,0 +1,30 @@ +/*- + * 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. + */ + + +#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..f78d1c49c62a --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy_arch_2_05.S @@ -0,0 +1,129 @@ +/*- + * 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> +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..402b5c5226d0 --- /dev/null +++ b/lib/libc/powerpc64/string/strncpy_resolver.c @@ -0,0 +1,45 @@ +/*- + * 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 <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); +} |