1 /* 2 * This provides an optimized implementation of memcpy, and a simplified 3 * implementation of memset and memmove. These are used here because the 4 * standard kernel runtime versions are not yet available and we don't 5 * trust the gcc built-in implementations as they may do unexpected things 6 * (e.g. FPU ops) in the minimal decompression stub execution environment. 7 */ 8 #include "../string.c" 9 10 #ifdef CONFIG_X86_32 11 void *memcpy(void *dest, const void *src, size_t n) 12 { 13 int d0, d1, d2; 14 asm volatile( 15 "rep ; movsl\n\t" 16 "movl %4,%%ecx\n\t" 17 "rep ; movsb\n\t" 18 : "=&c" (d0), "=&D" (d1), "=&S" (d2) 19 : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src) 20 : "memory"); 21 22 return dest; 23 } 24 #else 25 void *memcpy(void *dest, const void *src, size_t n) 26 { 27 long d0, d1, d2; 28 asm volatile( 29 "rep ; movsq\n\t" 30 "movq %4,%%rcx\n\t" 31 "rep ; movsb\n\t" 32 : "=&c" (d0), "=&D" (d1), "=&S" (d2) 33 : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src) 34 : "memory"); 35 36 return dest; 37 } 38 #endif 39 40 void *memset(void *s, int c, size_t n) 41 { 42 int i; 43 char *ss = s; 44 45 for (i = 0; i < n; i++) 46 ss[i] = c; 47 return s; 48 } 49 50 void *memmove(void *dest, const void *src, size_t n) 51 { 52 unsigned char *d = dest; 53 const unsigned char *s = src; 54 55 if (d <= s || d - s >= n) 56 return memcpy(dest, src, n); 57 58 while (n-- > 0) 59 d[n] = s[n]; 60 61 return dest; 62 } 63