]>
Commit | Line | Data |
---|---|---|
81b785f3 KC |
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 | */ | |
dc425a6e KC |
8 | #include "error.h" |
9 | ||
8fee13a4 | 10 | #include "../string.c" |
820e8fec | 11 | |
820e8fec | 12 | #ifdef CONFIG_X86_32 |
00ec2c37 | 13 | static void *__memcpy(void *dest, const void *src, size_t n) |
820e8fec VG |
14 | { |
15 | int d0, d1, d2; | |
16 | asm volatile( | |
17 | "rep ; movsl\n\t" | |
18 | "movl %4,%%ecx\n\t" | |
19 | "rep ; movsb\n\t" | |
20 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | |
21 | : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src) | |
22 | : "memory"); | |
23 | ||
24 | return dest; | |
25 | } | |
26 | #else | |
00ec2c37 | 27 | static void *__memcpy(void *dest, const void *src, size_t n) |
820e8fec VG |
28 | { |
29 | long d0, d1, d2; | |
30 | asm volatile( | |
31 | "rep ; movsq\n\t" | |
32 | "movq %4,%%rcx\n\t" | |
33 | "rep ; movsb\n\t" | |
34 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) | |
35 | : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src) | |
36 | : "memory"); | |
37 | ||
38 | return dest; | |
39 | } | |
40 | #endif | |
04999550 VG |
41 | |
42 | void *memset(void *s, int c, size_t n) | |
43 | { | |
44 | int i; | |
45 | char *ss = s; | |
46 | ||
47 | for (i = 0; i < n; i++) | |
48 | ss[i] = c; | |
49 | return s; | |
50 | } | |
bf0118db | 51 | |
81b785f3 | 52 | void *memmove(void *dest, const void *src, size_t n) |
bf0118db KC |
53 | { |
54 | unsigned char *d = dest; | |
55 | const unsigned char *s = src; | |
56 | ||
57 | if (d <= s || d - s >= n) | |
00ec2c37 | 58 | return __memcpy(dest, src, n); |
bf0118db KC |
59 | |
60 | while (n-- > 0) | |
61 | d[n] = s[n]; | |
62 | ||
63 | return dest; | |
64 | } | |
00ec2c37 KC |
65 | |
66 | /* Detect and warn about potential overlaps, but handle them with memmove. */ | |
67 | void *memcpy(void *dest, const void *src, size_t n) | |
68 | { | |
69 | if (dest > src && dest - src < n) { | |
70 | warn("Avoiding potentially unsafe overlapping memcpy()!"); | |
71 | return memmove(dest, src, n); | |
72 | } | |
73 | return __memcpy(dest, src, n); | |
74 | } |