diff mbox

[U-Boot,01/17] x86: Import glibc memcpy implementation

Message ID 1325477374-6417-2-git-send-email-graeme.russ@gmail.com
State Superseded
Headers show

Commit Message

Graeme Russ Jan. 2, 2012, 4:09 a.m. UTC
Taken from glibc version 2.14.90

Signed-off-by: Graeme Russ <graeme.russ@gmail.com>
---
 arch/x86/include/asm/string.h |    2 +-
 arch/x86/lib/string.c         |   61 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 1 deletions(-)

Comments

Simon Glass Jan. 4, 2012, 5:18 a.m. UTC | #1
On Sun, Jan 1, 2012 at 8:09 PM, Graeme Russ <graeme.russ@gmail.com> wrote:
> Taken from glibc version 2.14.90
>
> Signed-off-by: Graeme Russ <graeme.russ@gmail.com>

Acked-by: Simon Glass <sjg@chromium.org>

> ---
>  arch/x86/include/asm/string.h |    2 +-
>  arch/x86/lib/string.c         |   61 +++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 62 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h
> index 3aa6c11..0ad612f 100644
> --- a/arch/x86/include/asm/string.h
> +++ b/arch/x86/include/asm/string.h
> @@ -14,7 +14,7 @@ extern char * strrchr(const char * s, int c);
>  #undef __HAVE_ARCH_STRCHR
>  extern char * strchr(const char * s, int c);
>
> -#undef __HAVE_ARCH_MEMCPY
> +#define __HAVE_ARCH_MEMCPY
>  extern void * memcpy(void *, const void *, __kernel_size_t);
>
>  #undef __HAVE_ARCH_MEMMOVE
> diff --git a/arch/x86/lib/string.c b/arch/x86/lib/string.c
> index f2ea7e4..1fde81b 100644
> --- a/arch/x86/lib/string.c
> +++ b/arch/x86/lib/string.c
> @@ -85,3 +85,64 @@ void *memset(void *dstpp, int c, size_t len)
>
>        return dstpp;
>  }
> +
> +#define        OP_T_THRES      8
> +#define OPSIZ  (sizeof(op_t))
> +
> +#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)                            \
> +do {                                                                     \
> +       int __d0;                                                         \
> +       asm volatile(                                                     \
> +               /* Clear the direction flag, so copying goes forward.  */ \
> +               "cld\n"                                                   \
> +               /* Copy bytes.  */                                        \
> +               "rep\n"                                                   \
> +               "movsb" :                                                 \
> +               "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) :               \
> +               "0" (dst_bp), "1" (src_bp), "2" (nbytes) :                \
> +               "memory");                                                \
> +} while (0)
> +
> +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)               \
> +do {                                                                     \
> +       int __d0;                                                         \
> +       asm volatile(                                                     \
> +               /* Clear the direction flag, so copying goes forward.  */ \
> +               "cld\n"                                                   \
> +               /* Copy longwords.  */                                    \
> +               "rep\n"                                                   \
> +               "movsl" :                                                 \
> +               "=D" (dst_bp), "=S" (src_bp), "=c" (__d0) :               \
> +               "0" (dst_bp), "1" (src_bp), "2" ((nbytes) / 4) :          \
> +               "memory");                                                \
> +       (nbytes_left) = (nbytes) % 4;                                     \
> +} while (0)
> +
> +void *memcpy(void *dstpp, const void *srcpp, size_t len)
> +{
> +       unsigned long int dstp = (long int)dstpp;
> +       unsigned long int srcp = (long int)srcpp;
> +
> +       /* Copy from the beginning to the end.  */
> +
> +       /* If there not too few bytes to copy, use word copy.  */
> +       if (len >= OP_T_THRES) {
> +               /* Copy just a few bytes to make DSTP aligned.  */
> +               len -= (-dstp) % OPSIZ;
> +               BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ);
> +
> +               /* Copy from SRCP to DSTP taking advantage of the known
> +                * alignment of DSTP.  Number of bytes remaining is put
> +                * in the third argument, i.e. in LEN.  This number may
> +                * vary from machine to machine.
> +                */
> +               WORD_COPY_FWD(dstp, srcp, len, len);
> +
> +               /* Fall out and copy the tail.  */
> +       }
> +
> +       /* There are just a few bytes to copy. Use byte memory operations. */
> +       BYTE_COPY_FWD(dstp, srcp, len);
> +
> +       return dstpp;
> +}
> --
> 1.7.5.2.317.g391b14
>
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
diff mbox

Patch

diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h
index 3aa6c11..0ad612f 100644
--- a/arch/x86/include/asm/string.h
+++ b/arch/x86/include/asm/string.h
@@ -14,7 +14,7 @@  extern char * strrchr(const char * s, int c);
 #undef __HAVE_ARCH_STRCHR
 extern char * strchr(const char * s, int c);
 
-#undef __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMCPY
 extern void * memcpy(void *, const void *, __kernel_size_t);
 
 #undef __HAVE_ARCH_MEMMOVE
diff --git a/arch/x86/lib/string.c b/arch/x86/lib/string.c
index f2ea7e4..1fde81b 100644
--- a/arch/x86/lib/string.c
+++ b/arch/x86/lib/string.c
@@ -85,3 +85,64 @@  void *memset(void *dstpp, int c, size_t len)
 
 	return dstpp;
 }
+
+#define	OP_T_THRES	8
+#define OPSIZ	(sizeof(op_t))
+
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)				  \
+do {									  \
+	int __d0;							  \
+	asm volatile(							  \
+		/* Clear the direction flag, so copying goes forward.  */ \
+		"cld\n"							  \
+		/* Copy bytes.  */					  \
+		"rep\n"							  \
+		"movsb" :						  \
+		"=D" (dst_bp), "=S" (src_bp), "=c" (__d0) :		  \
+		"0" (dst_bp), "1" (src_bp), "2" (nbytes) :		  \
+		"memory");						  \
+} while (0)
+
+#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)		  \
+do {									  \
+	int __d0;							  \
+	asm volatile(							  \
+		/* Clear the direction flag, so copying goes forward.  */ \
+		"cld\n"							  \
+		/* Copy longwords.  */					  \
+		"rep\n"							  \
+		"movsl" :						  \
+		"=D" (dst_bp), "=S" (src_bp), "=c" (__d0) :		  \
+		"0" (dst_bp), "1" (src_bp), "2" ((nbytes) / 4) :	  \
+		"memory");						  \
+	(nbytes_left) = (nbytes) % 4;					  \
+} while (0)
+
+void *memcpy(void *dstpp, const void *srcpp, size_t len)
+{
+	unsigned long int dstp = (long int)dstpp;
+	unsigned long int srcp = (long int)srcpp;
+
+	/* Copy from the beginning to the end.  */
+
+	/* If there not too few bytes to copy, use word copy.  */
+	if (len >= OP_T_THRES) {
+		/* Copy just a few bytes to make DSTP aligned.  */
+		len -= (-dstp) % OPSIZ;
+		BYTE_COPY_FWD(dstp, srcp, (-dstp) % OPSIZ);
+
+		/* Copy from SRCP to DSTP taking advantage of the known
+		 * alignment of DSTP.  Number of bytes remaining is put
+		 * in the third argument, i.e. in LEN.  This number may
+		 * vary from machine to machine.
+		 */
+		WORD_COPY_FWD(dstp, srcp, len, len);
+
+		/* Fall out and copy the tail.  */
+	}
+
+	/* There are just a few bytes to copy. Use byte memory operations. */
+	BYTE_COPY_FWD(dstp, srcp, len);
+
+	return dstpp;
+}