diff options
-rw-r--r-- | lib/libc/arch/powerpc/string/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/arch/powerpc/string/memmove.S | 168 |
2 files changed, 170 insertions, 2 deletions
diff --git a/lib/libc/arch/powerpc/string/Makefile.inc b/lib/libc/arch/powerpc/string/Makefile.inc index c03e0b4e49e..2ebd39efb71 100644 --- a/lib/libc/arch/powerpc/string/Makefile.inc +++ b/lib/libc/arch/powerpc/string/Makefile.inc @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile.inc,v 1.4 2014/11/30 19:43:56 deraadt Exp $ +# $OpenBSD: Makefile.inc,v 1.5 2014/12/04 12:10:26 deraadt Exp $ -SRCS+= bcopy.c memcpy.c memmove.c \ +SRCS+= memcpy.c memmove.S \ index.c rindex.c strchr.c strrchr.c \ bcmp.c bzero.c ffs.c memchr.c memcmp.c memset.c strcat.c \ strcmp.c strcpy.c strcspn.c strlen.c strlcat.c strlcpy.c \ diff --git a/lib/libc/arch/powerpc/string/memmove.S b/lib/libc/arch/powerpc/string/memmove.S new file mode 100644 index 00000000000..875c562b0b2 --- /dev/null +++ b/lib/libc/arch/powerpc/string/memmove.S @@ -0,0 +1,168 @@ +/* $OpenBSD: memmove.S,v 1.1 2014/12/04 12:10:26 deraadt Exp $ */ +/* $NetBSD: memmove.S,v 1.3 2011/01/15 07:31:12 matt Exp $ */ + +/* stropt/memmove.S, pl_string_common, pl_linux 10/11/04 11:45:37 + * ========================================================================== + * Optimized memmove implementation for IBM PowerPC 405/440. + * + * Copyright (c) 2003, IBM Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * * 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. + * * Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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> + + .text + +/* void *memcpy(void *to, const void *from, size_t len) */ +// ENTRY(memcpy) + mr %r8, %r3 /* Save dst (return value) */ + b fwd + +/* void bcopy(void *, void *, size_t) */ +ENTRY(bcopy) + mr %r6, %r3 /* swap src/dst */ + mr %r3, %r4 + mr %r4, %r6 + +/* void *memmove(void *, const void *, size_t) */ +ENTRY(memmove) + mr %r8, %r3 /* Save dst (return value) */ + + cmpw %r4, %r8 /* Branch to reverse if */ + blt reverse /* src < dest. Don't want to */ + /* overwrite end of src with */ + /* start of dest */ + +fwd: + addi %r4, %r4, -4 /* Back up src and dst pointers */ + addi %r8, %r8, -4 /* due to auto-update of 'load' */ + + srwi. %r9,%r5,2 /* How many words in total cnt */ + beq- last1 /* Handle byte by byte if < 4 */ + /* bytes total */ + mtctr %r9 /* Count of words for loop */ + lwzu %r7, 4(%r4) /* Preload first word */ + + b g1 + +g0: /* Main loop */ + + lwzu %r7, 4(%r4) /* Load a new word */ + stwu %r6, 4(%r8) /* Store previous word */ + +g1: + + bdz- last /* Dec cnt, and branch if just */ + /* one word to store */ + lwzu %r6, 4(%r4) /* Load another word */ + stwu %r7, 4(%r8) /* Store previous word */ + bdnz+ g0 /* Dec cnt, and loop again if */ + /* more words */ + mr %r7, %r6 /* If word count -> 0, then... */ + +last: + + stwu %r7, 4(%r8) /* ... store last word */ + +last1: /* Byte-by-byte copy */ + + clrlwi. %r5,%r5,30 /* If count -> 0, then ... */ + beqlr /* we're done */ + + mtctr %r5 /* else load count for loop */ + + lbzu %r6, 4(%r4) /* 1st byte: update addr by 4 */ + stbu %r6, 4(%r8) /* since we pre-adjusted by 4 */ + bdzlr- /* in anticipation of main loop */ + +last2: + + lbzu %r6, 1(%r4) /* But handle the rest by */ + stbu %r6, 1(%r8) /* updating addr by 1 */ + bdnz+ last2 + + blr + + /* We're here since src < dest. Don't want to overwrite end of */ + /* src with start of dest */ + +reverse: + + add %r4, %r4, %r5 /* Work from end to beginning */ + add %r8, %r8, %r5 /* so add count to string ptrs */ + srwi. %r9,%r5,2 /* Words in total count */ + beq- rlast1 /* Handle byte by byte if < 4 */ + /* bytes total */ + + mtctr %r9 /* Count of words for loop */ + + lwzu %r7, -4(%r4) /* Preload first word */ + b rg1 + +rg0: /* Main loop */ + + lwzu %r7, -4(%r4) /* Load a new word */ + stwu %r6, -4(%r8) /* Store previous word */ + +rg1: + + bdz- rlast /* Dec cnt, and branch if just */ + /* one word to store */ + + lwzu %r6, -4(%r4) /* Load another word */ + stwu %r7, -4(%r8) /* Store previous word */ + + bdnz+ rg0 /* Dec cnt, and loop again if */ + /* more words */ + + mr %r7, %r6 /* If word count -> 0, then... */ + +rlast: + + stwu %r7, -4(%r8) /* ... store last word */ + +rlast1: /* Byte-by-byte copy */ + + clrlwi. %r5,%r5,30 /* If count -> 0, then... */ + beqlr /* ... we're done */ + + mtctr %r5 /* else load count for loop */ + +rlast2: + + lbzu %r6, -1(%r4) /* Handle the rest, byte by */ + stbu %r6, -1(%r8) /* byte */ + + bdnz+ rlast2 /* Dec ctr, and branch if more */ + /* bytes left */ + blr |