aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/powerpc64/string
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/powerpc64/string')
-rw-r--r--lib/libc/powerpc64/string/Makefile.inc16
-rw-r--r--lib/libc/powerpc64/string/bcopy.S338
-rw-r--r--lib/libc/powerpc64/string/bcopy_resolver.c70
-rw-r--r--lib/libc/powerpc64/string/bcopy_vsx.S59
-rw-r--r--lib/libc/powerpc64/string/memcpy.S131
-rw-r--r--lib/libc/powerpc64/string/memcpy_resolver.c3
-rw-r--r--lib/libc/powerpc64/string/memcpy_vsx.S64
-rw-r--r--lib/libc/powerpc64/string/memmove.S3
-rw-r--r--lib/libc/powerpc64/string/memmove_resolver.c3
-rw-r--r--lib/libc/powerpc64/string/memmove_vsx.S4
-rw-r--r--lib/libc/powerpc64/string/strcpy.c30
-rw-r--r--lib/libc/powerpc64/string/strcpy_arch_2_05.S202
-rw-r--r--lib/libc/powerpc64/string/strcpy_resolver.c44
-rw-r--r--lib/libc/powerpc64/string/strncpy.c30
-rw-r--r--lib/libc/powerpc64/string/strncpy_arch_2_05.S129
-rw-r--r--lib/libc/powerpc64/string/strncpy_resolver.c45
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);
+}