[PATCH v2 1/6] RISC-V: memmove() speed optimized: Add implementation
m fally <[email protected]>
| Newsgroups | gmane.comp.lib.newlib |
|---|---|
| Message-ID | <[email protected]> |
Copy the common implementation of memmove() to the RISC-V port. Rename memmove.S to memmove-asm.S to keep naming of files consistent between functions. Update Makefile.inc with the changed filenames. Reviewed-by: Christian Herber <[email protected]> Signed-off-by: m fally <[email protected]> --- newlib/libc/machine/riscv/Makefile.inc | 2 +- .../riscv/{memmove.S => memmove-asm.S} | 0 newlib/libc/machine/riscv/memmove-stub.c | 14 --- newlib/libc/machine/riscv/memmove.c | 99 +++++++++++++++++++ 4 files changed, 100 insertions(+), 15 deletions(-) rename newlib/libc/machine/riscv/{memmove.S => memmove-asm.S} (100%) delete mode 100644 newlib/libc/machine/riscv/memmove-stub.c create mode 100644 newlib/libc/machine/riscv/memmove.c diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc index 85bed9177..3cc6e198f 100644 --- a/newlib/libc/machine/riscv/Makefile.inc +++ b/newlib/libc/machine/riscv/Makefile.inc @@ -1,3 +1,3 @@ libc_a_SOURCES += \ - %D%/memmove.S %D%/memmove-stub.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \ + %D%/memmove-asm.S %D%/memmove.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \ %D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/memchr.c %D%/memrchr.c %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c diff --git a/newlib/libc/machine/riscv/memmove.S b/newlib/libc/machine/riscv/memmove-asm.S similarity index 100% rename from newlib/libc/machine/riscv/memmove.S rename to newlib/libc/machine/riscv/memmove-asm.S diff --git a/newlib/libc/machine/riscv/memmove-stub.c b/newlib/libc/machine/riscv/memmove-stub.c deleted file mode 100644 index d882e46c1..000000000 --- a/newlib/libc/machine/riscv/memmove-stub.c +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright (c) 2019 SiFive Inc. All rights reserved. - - This copyrighted material is made available to anyone wishing to use, - modify, copy, or redistribute it subject to the terms and conditions - of the FreeBSD License. This program is distributed in the hope that - it will be useful, but WITHOUT ANY WARRANTY expressed or implied, - including the implied warranties of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. A copy of this license is available at - http://www.opensource.org/licenses. -*/ - -#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) -#include "../../string/memmove.c" -#endif diff --git a/newlib/libc/machine/riscv/memmove.c b/newlib/libc/machine/riscv/memmove.c new file mode 100644 index 000000000..b48da0905 --- /dev/null +++ b/newlib/libc/machine/riscv/memmove.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2019 SiFive Inc. All rights reserved. + + This copyrighted material is made available to anyone wishing to use, + modify, copy, or redistribute it subject to the terms and conditions + of the FreeBSD License. This program is distributed in the hope that + it will be useful, but WITHOUT ANY WARRANTY expressed or implied, + including the implied warranties of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. A copy of this license is available at + http://www.opensource.org/licenses. +*/ + +#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) +/* memmove defined in memmove-asm.S */ +#else + +#include "../../string/local.h" +#include <_ansi.h> +#include <limits.h> +#include <stddef.h> +#include <string.h> + +/*SUPPRESS 20*/ +void *__inhibit_loop_to_libcall +memmove (void *dst_void, const void *src_void, size_t length) +{ + char *dst = dst_void; + const char *src = src_void; + long *aligned_dst; + const long *aligned_src; + + if (src < dst && dst < src + length) + { + /* Destructive overlap...have to copy backwards */ + src += length; + dst += length; + + if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst)) + { + aligned_dst = (long *)dst; + aligned_src = (long *)src; + + /* Copy one long word at a time if possible. */ + while (!TOO_SMALL_LITTLE_BLOCK (length)) + { + *--aligned_dst = *--aligned_src; + length -= LITTLE_BLOCK_SIZE; + } + + /* Pick up any residual with a byte copier. */ + dst = (char *)aligned_dst; + src = (char *)aligned_src; + } + + while (length--) + { + *--dst = *--src; + } + } + else + { + /* Use optimizing algorithm for a non-destructive copy to closely + match memcpy. If the size is small or either SRC or DST is unaligned, + then punt into the byte copy loop. This should be rare. */ + if (!TOO_SMALL_LITTLE_BLOCK (length) && !UNALIGNED_X_Y (src, dst)) + { + aligned_dst = (long *)dst; + aligned_src = (long *)src; + + /* Copy 4X long words at a time if possible. */ + while (!TOO_SMALL_BIG_BLOCK (length)) + { + *aligned_dst++ = *aligned_src++; + *aligned_dst++ = *aligned_src++; + *aligned_dst++ = *aligned_src++; + *aligned_dst++ = *aligned_src++; + length -= BIG_BLOCK_SIZE; + } + + /* Copy one long word at a time if possible. */ + while (!TOO_SMALL_LITTLE_BLOCK (length)) + { + *aligned_dst++ = *aligned_src++; + length -= LITTLE_BLOCK_SIZE; + } + + /* Pick up any residual with a byte copier. */ + dst = (char *)aligned_dst; + src = (char *)aligned_src; + } + + while (length--) + { + *dst++ = *src++; + } + } + + return dst_void; +} +#endif -- 2.49.0