[U-Boot] [PATCH 02/12] x86: Add an accelerated memmove() function
Bin Meng
bmeng.cn at gmail.com
Wed Oct 5 11:20:00 CEST 2016
Hi Simon,
On Mon, Oct 3, 2016 at 11:12 AM, Simon Glass <sjg at chromium.org> wrote:
> Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the
> display.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> arch/x86/include/asm/string.h | 2 +-
> arch/x86/lib/Makefile | 1 +
> arch/x86/lib/memmove.c | 193 ++++++++++++++++++++++++++++++++++++++++++
Other optimized routines are put in arch/x86/lib/string.c. Can we put
this memmove() there too?
> 3 files changed, 195 insertions(+), 1 deletion(-)
> create mode 100644 arch/x86/lib/memmove.c
>
> diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h
> index 0ad612f..38afd23 100644
> --- a/arch/x86/include/asm/string.h
> +++ b/arch/x86/include/asm/string.h
> @@ -17,7 +17,7 @@ extern char * strchr(const char * s, int c);
> #define __HAVE_ARCH_MEMCPY
> extern void * memcpy(void *, const void *, __kernel_size_t);
>
> -#undef __HAVE_ARCH_MEMMOVE
> +#define __HAVE_ARCH_MEMMOVE
> extern void * memmove(void *, const void *, __kernel_size_t);
>
> #undef __HAVE_ARCH_MEMCHR
> diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
> index e17f0bb..b380d62 100644
> --- a/arch/x86/lib/Makefile
> +++ b/arch/x86/lib/Makefile
> @@ -17,6 +17,7 @@ obj-y += gcc.o
> obj-y += init_helpers.o
> obj-y += interrupts.o
> obj-y += lpc-uclass.o
> +obj-y += memmove.o
> obj-y += mpspec.o
> obj-$(CONFIG_ENABLE_MRC_CACHE) += mrccache.o
> obj-y += cmd_mtrr.o
> diff --git a/arch/x86/lib/memmove.c b/arch/x86/lib/memmove.c
> new file mode 100644
> index 0000000..504a184
> --- /dev/null
> +++ b/arch/x86/lib/memmove.c
> @@ -0,0 +1,193 @@
> +/*
> + * Copyright (c) 2016 Google, Inc
> + * Taken from Linux v4.7. There is no copyright notice on the original file.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +
> +void *memmove(void *dest, const void *src, size_t n)
> +{
> + int d0, d1, d2, d3, d4, d5;
> + char *ret = dest;
> +
> + __asm__ __volatile__(
> + /* Handle more 16 bytes in loop */
> + "cmp $0x10, %0\n\t"
> + "jb 1f\n\t"
> +
> + /* Decide forward/backward copy mode */
> + "cmp %2, %1\n\t"
> + "jb 2f\n\t"
> +
> + /*
> + * movs instruction have many startup latency
> + * so we handle small size by general register.
> + */
> + "cmp $680, %0\n\t"
> + "jb 3f\n\t"
> + /*
> + * movs instruction is only good for aligned case.
> + */
nits: use single line comment format. Please fix this globally in this file.
> + "mov %1, %3\n\t"
> + "xor %2, %3\n\t"
> + "and $0xff, %3\n\t"
> + "jz 4f\n\t"
> + "3:\n\t"
> + "sub $0x10, %0\n\t"
> +
> + /*
> + * We gobble 16 bytes forward in each loop.
> + */
> + "3:\n\t"
> + "sub $0x10, %0\n\t"
> + "mov 0*4(%1), %3\n\t"
> + "mov 1*4(%1), %4\n\t"
> + "mov %3, 0*4(%2)\n\t"
> + "mov %4, 1*4(%2)\n\t"
> + "mov 2*4(%1), %3\n\t"
> + "mov 3*4(%1), %4\n\t"
> + "mov %3, 2*4(%2)\n\t"
> + "mov %4, 3*4(%2)\n\t"
> + "lea 0x10(%1), %1\n\t"
> + "lea 0x10(%2), %2\n\t"
> + "jae 3b\n\t"
> + "add $0x10, %0\n\t"
> + "jmp 1f\n\t"
> +
> + /*
> + * Handle data forward by movs.
> + */
> + ".p2align 4\n\t"
> + "4:\n\t"
> + "mov -4(%1, %0), %3\n\t"
> + "lea -4(%2, %0), %4\n\t"
> + "shr $2, %0\n\t"
> + "rep movsl\n\t"
> + "mov %3, (%4)\n\t"
> + "jmp 11f\n\t"
> + /*
> + * Handle data backward by movs.
> + */
> + ".p2align 4\n\t"
> + "6:\n\t"
> + "mov (%1), %3\n\t"
> + "mov %2, %4\n\t"
> + "lea -4(%1, %0), %1\n\t"
> + "lea -4(%2, %0), %2\n\t"
> + "shr $2, %0\n\t"
> + "std\n\t"
> + "rep movsl\n\t"
> + "mov %3,(%4)\n\t"
> + "cld\n\t"
> + "jmp 11f\n\t"
> +
> + /*
> + * Start to prepare for backward copy.
> + */
> + ".p2align 4\n\t"
> + "2:\n\t"
> + "cmp $680, %0\n\t"
> + "jb 5f\n\t"
> + "mov %1, %3\n\t"
> + "xor %2, %3\n\t"
> + "and $0xff, %3\n\t"
> + "jz 6b\n\t"
> +
> + /*
> + * Calculate copy position to tail.
> + */
> + "5:\n\t"
> + "add %0, %1\n\t"
> + "add %0, %2\n\t"
> + "sub $0x10, %0\n\t"
> +
> + /*
> + * We gobble 16 bytes backward in each loop.
> + */
> + "7:\n\t"
> + "sub $0x10, %0\n\t"
> +
> + "mov -1*4(%1), %3\n\t"
> + "mov -2*4(%1), %4\n\t"
> + "mov %3, -1*4(%2)\n\t"
> + "mov %4, -2*4(%2)\n\t"
> + "mov -3*4(%1), %3\n\t"
> + "mov -4*4(%1), %4\n\t"
> + "mov %3, -3*4(%2)\n\t"
> + "mov %4, -4*4(%2)\n\t"
> + "lea -0x10(%1), %1\n\t"
> + "lea -0x10(%2), %2\n\t"
> + "jae 7b\n\t"
> + /*
> + * Calculate copy position to head.
> + */
> + "add $0x10, %0\n\t"
> + "sub %0, %1\n\t"
> + "sub %0, %2\n\t"
> +
> + /*
> + * Move data from 8 bytes to 15 bytes.
> + */
> + ".p2align 4\n\t"
> + "1:\n\t"
> + "cmp $8, %0\n\t"
> + "jb 8f\n\t"
> + "mov 0*4(%1), %3\n\t"
> + "mov 1*4(%1), %4\n\t"
> + "mov -2*4(%1, %0), %5\n\t"
> + "mov -1*4(%1, %0), %1\n\t"
> +
> + "mov %3, 0*4(%2)\n\t"
> + "mov %4, 1*4(%2)\n\t"
> + "mov %5, -2*4(%2, %0)\n\t"
> + "mov %1, -1*4(%2, %0)\n\t"
> + "jmp 11f\n\t"
> +
> + /*
> + * Move data from 4 bytes to 7 bytes.
> + */
> + ".p2align 4\n\t"
> + "8:\n\t"
> + "cmp $4, %0\n\t"
> + "jb 9f\n\t"
> + "mov 0*4(%1), %3\n\t"
> + "mov -1*4(%1, %0), %4\n\t"
> + "mov %3, 0*4(%2)\n\t"
> + "mov %4, -1*4(%2, %0)\n\t"
> + "jmp 11f\n\t"
> +
> + /*
> + * Move data from 2 bytes to 3 bytes.
> + */
> + ".p2align 4\n\t"
> + "9:\n\t"
> + "cmp $2, %0\n\t"
> + "jb 10f\n\t"
> + "movw 0*2(%1), %%dx\n\t"
> + "movw -1*2(%1, %0), %%bx\n\t"
> + "movw %%dx, 0*2(%2)\n\t"
> + "movw %%bx, -1*2(%2, %0)\n\t"
> + "jmp 11f\n\t"
> +
> + /*
> + * Move data for 1 byte.
> + */
> + ".p2align 4\n\t"
> + "10:\n\t"
> + "cmp $1, %0\n\t"
> + "jb 11f\n\t"
> + "movb (%1), %%cl\n\t"
> + "movb %%cl, (%2)\n\t"
> + ".p2align 4\n\t"
> + "11:"
> + : "=&c" (d0), "=&S" (d1), "=&D" (d2),
> + "=r" (d3), "=r" (d4), "=r"(d5)
> + : "0" (n),
> + "1" (src),
> + "2" (dest)
> + : "memory");
> +
> + return ret;
> +}
> --
Regards,
Bin
More information about the U-Boot
mailing list