diff options
| -rw-r--r-- | arch/x86/lib/memcpy_32.c | 38 | ||||
| -rw-r--r-- | arch/x86/lib/memmove_64.c | 46 |
2 files changed, 68 insertions, 16 deletions
diff --git a/arch/x86/lib/memcpy_32.c b/arch/x86/lib/memcpy_32.c index 5415a9d06f5..be424dfcf36 100644 --- a/arch/x86/lib/memcpy_32.c +++ b/arch/x86/lib/memcpy_32.c | |||
| @@ -25,19 +25,35 @@ void *memmove(void *dest, const void *src, size_t n) | |||
| 25 | int d0, d1, d2; | 25 | int d0, d1, d2; |
| 26 | 26 | ||
| 27 | if (dest < src) { | 27 | if (dest < src) { |
| 28 | memcpy(dest, src, n); | 28 | if ((dest + n) < src) |
| 29 | return memcpy(dest, src, n); | ||
| 30 | else | ||
| 31 | __asm__ __volatile__( | ||
| 32 | "rep\n\t" | ||
| 33 | "movsb\n\t" | ||
| 34 | : "=&c" (d0), "=&S" (d1), "=&D" (d2) | ||
| 35 | :"0" (n), | ||
| 36 | "1" (src), | ||
| 37 | "2" (dest) | ||
| 38 | :"memory"); | ||
| 39 | |||
| 29 | } else { | 40 | } else { |
| 30 | __asm__ __volatile__( | 41 | |
| 31 | "std\n\t" | 42 | if((src + count) < dest) |
| 32 | "rep\n\t" | 43 | return memcpy(dest, src, count); |
| 33 | "movsb\n\t" | 44 | else |
| 34 | "cld" | 45 | __asm__ __volatile__( |
| 35 | : "=&c" (d0), "=&S" (d1), "=&D" (d2) | 46 | "std\n\t" |
| 36 | :"0" (n), | 47 | "rep\n\t" |
| 37 | "1" (n-1+src), | 48 | "movsb\n\t" |
| 38 | "2" (n-1+dest) | 49 | "cld" |
| 39 | :"memory"); | 50 | : "=&c" (d0), "=&S" (d1), "=&D" (d2) |
| 51 | :"0" (n), | ||
| 52 | "1" (n-1+src), | ||
| 53 | "2" (n-1+dest) | ||
| 54 | :"memory"); | ||
| 40 | } | 55 | } |
| 56 | |||
| 41 | return dest; | 57 | return dest; |
| 42 | } | 58 | } |
| 43 | EXPORT_SYMBOL(memmove); | 59 | EXPORT_SYMBOL(memmove); |
diff --git a/arch/x86/lib/memmove_64.c b/arch/x86/lib/memmove_64.c index 0a33909bf12..ecacc4b3d9e 100644 --- a/arch/x86/lib/memmove_64.c +++ b/arch/x86/lib/memmove_64.c | |||
| @@ -8,13 +8,49 @@ | |||
| 8 | #undef memmove | 8 | #undef memmove |
| 9 | void *memmove(void *dest, const void *src, size_t count) | 9 | void *memmove(void *dest, const void *src, size_t count) |
| 10 | { | 10 | { |
| 11 | unsigned long d0, d1, d2, d3; | ||
| 11 | if (dest < src) { | 12 | if (dest < src) { |
| 12 | return memcpy(dest, src, count); | 13 | if ((dest + count) < src) |
| 14 | return memcpy(dest, src, count); | ||
| 15 | else | ||
| 16 | __asm__ __volatile__( | ||
| 17 | "movq %0, %3\n\t" | ||
| 18 | "shr $3, %0\n\t" | ||
| 19 | "andq $7, %3\n\t" | ||
| 20 | "rep\n\t" | ||
| 21 | "movsq\n\t" | ||
| 22 | "movq %3, %0\n\t" | ||
| 23 | "rep\n\t" | ||
| 24 | "movsb" | ||
| 25 | : "=&c" (d0), "=&S" (d1), "=&D" (d2), "=r" (d3) | ||
| 26 | :"0" (count), | ||
| 27 | "1" (src), | ||
| 28 | "2" (dest) | ||
| 29 | :"memory"); | ||
| 13 | } else { | 30 | } else { |
| 14 | char *p = dest + count; | 31 | if((src + count) < dest) |
| 15 | const char *s = src + count; | 32 | return memcpy(dest, src, count); |
| 16 | while (count--) | 33 | else |
| 17 | *--p = *--s; | 34 | __asm__ __volatile__( |
| 35 | "movq %0, %3\n\t" | ||
| 36 | "lea -8(%1, %0), %1\n\t" | ||
| 37 | "lea -8(%2, %0), %2\n\t" | ||
| 38 | "shr $3, %0\n\t" | ||
| 39 | "andq $7, %3\n\t" | ||
| 40 | "std\n\t" | ||
| 41 | "rep\n\t" | ||
| 42 | "movsq\n\t" | ||
| 43 | "lea 7(%1), %1\n\t" | ||
| 44 | "lea 7(%2), %2\n\t" | ||
| 45 | "movq %3, %0\n\t" | ||
| 46 | "rep\n\t" | ||
| 47 | "movsb\n\t" | ||
| 48 | "cld" | ||
| 49 | : "=&c" (d0), "=&S" (d1), "=&D" (d2), "=r" (d3) | ||
| 50 | :"0" (count), | ||
| 51 | "1" (src), | ||
| 52 | "2" (dest) | ||
| 53 | :"memory"); | ||
| 18 | } | 54 | } |
| 19 | return dest; | 55 | return dest; |
| 20 | } | 56 | } |
