Message ID | 1325707195-3218-1-git-send-email-graeme.russ@gmail.com |
---|---|
State | Awaiting Upstream |
Delegated to: | Graeme Russ |
Headers | show |
Hi, On Wed, Jan 4, 2012 at 11:59 AM, Graeme Russ <graeme.russ@gmail.com> wrote: > Taken from glibc version 2.14.90 > > Signed-off-by: Graeme Russ <graeme.russ@gmail.com> > --- > Changes for v2: > - None It feels a bit odd acking x86 patches but I have been through these and much of the series is generally useful for other archs... 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 --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; +}
Taken from glibc version 2.14.90 Signed-off-by: Graeme Russ <graeme.russ@gmail.com> --- Changes for v2: - None arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletions(-) -- 1.7.5.2.317.g391b14