blob: 2befeca1aada00df053fa58bf0772773482d6aa8 [file] [log] [blame]
Kees Cook81b785f2016-04-26 14:46:06 -07001/*
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 */
Yinghai Lu8fee13a42010-08-02 16:21:22 -07008#include "../string.c"
Vivek Goyal820e8fe2014-03-18 15:26:38 -04009
Vivek Goyal820e8fe2014-03-18 15:26:38 -040010#ifdef CONFIG_X86_32
Kees Cook81b785f2016-04-26 14:46:06 -070011void *memcpy(void *dest, const void *src, size_t n)
Vivek Goyal820e8fe2014-03-18 15:26:38 -040012{
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
Kees Cook81b785f2016-04-26 14:46:06 -070025void *memcpy(void *dest, const void *src, size_t n)
Vivek Goyal820e8fe2014-03-18 15:26:38 -040026{
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
Vivek Goyal04999552014-03-18 15:26:40 -040039
40void *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}
Kees Cookbf0118d2016-04-20 13:55:45 -070049
Kees Cook81b785f2016-04-26 14:46:06 -070050void *memmove(void *dest, const void *src, size_t n)
Kees Cookbf0118d2016-04-20 13:55:45 -070051{
52 unsigned char *d = dest;
53 const unsigned char *s = src;
54
55 if (d <= s || d - s >= n)
Kees Cook81b785f2016-04-26 14:46:06 -070056 return memcpy(dest, src, n);
Kees Cookbf0118d2016-04-20 13:55:45 -070057
58 while (n-- > 0)
59 d[n] = s[n];
60
61 return dest;
62}