diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/v850/lib/memcpy.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/v850/lib/memcpy.c')
-rw-r--r-- | arch/v850/lib/memcpy.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/arch/v850/lib/memcpy.c b/arch/v850/lib/memcpy.c new file mode 100644 index 000000000000..492847b3e612 --- /dev/null +++ b/arch/v850/lib/memcpy.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * arch/v850/lib/memcpy.c -- Memory copying | ||
3 | * | ||
4 | * Copyright (C) 2001,02 NEC Corporation | ||
5 | * Copyright (C) 2001,02 Miles Bader <miles@gnu.org> | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General | ||
8 | * Public License. See the file COPYING in the main directory of this | ||
9 | * archive for more details. | ||
10 | * | ||
11 | * Written by Miles Bader <miles@gnu.org> | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <asm/string.h> | ||
16 | |||
17 | #define CHUNK_SIZE 32 /* bytes */ | ||
18 | #define CHUNK_ALIGNED(addr) (((unsigned long)addr & 0x3) == 0) | ||
19 | |||
20 | /* Note that this macro uses 8 call-clobbered registers (not including | ||
21 | R1), which are few enough so that the following functions don't need | ||
22 | to spill anything to memory. It also uses R1, which is nominally | ||
23 | reserved for the assembler, but here it should be OK. */ | ||
24 | #define COPY_CHUNK(src, dst) \ | ||
25 | asm ("mov %0, ep;" \ | ||
26 | "sld.w 0[ep], r1; sld.w 4[ep], r12;" \ | ||
27 | "sld.w 8[ep], r13; sld.w 12[ep], r14;" \ | ||
28 | "sld.w 16[ep], r15; sld.w 20[ep], r17;" \ | ||
29 | "sld.w 24[ep], r18; sld.w 28[ep], r19;" \ | ||
30 | "mov %1, ep;" \ | ||
31 | "sst.w r1, 0[ep]; sst.w r12, 4[ep];" \ | ||
32 | "sst.w r13, 8[ep]; sst.w r14, 12[ep];" \ | ||
33 | "sst.w r15, 16[ep]; sst.w r17, 20[ep];" \ | ||
34 | "sst.w r18, 24[ep]; sst.w r19, 28[ep]" \ | ||
35 | :: "r" (src), "r" (dst) \ | ||
36 | : "r1", "r12", "r13", "r14", "r15", \ | ||
37 | "r17", "r18", "r19", "ep", "memory"); | ||
38 | |||
39 | void *memcpy (void *dst, const void *src, __kernel_size_t size) | ||
40 | { | ||
41 | char *_dst = dst; | ||
42 | const char *_src = src; | ||
43 | |||
44 | if (size >= CHUNK_SIZE && CHUNK_ALIGNED(_src) && CHUNK_ALIGNED(_dst)) { | ||
45 | /* Copy large blocks efficiently. */ | ||
46 | unsigned count; | ||
47 | for (count = size / CHUNK_SIZE; count; count--) { | ||
48 | COPY_CHUNK (_src, _dst); | ||
49 | _src += CHUNK_SIZE; | ||
50 | _dst += CHUNK_SIZE; | ||
51 | } | ||
52 | size %= CHUNK_SIZE; | ||
53 | } | ||
54 | |||
55 | if (size > 0) | ||
56 | do | ||
57 | *_dst++ = *_src++; | ||
58 | while (--size); | ||
59 | |||
60 | return dst; | ||
61 | } | ||
62 | |||
63 | void *memmove (void *dst, const void *src, __kernel_size_t size) | ||
64 | { | ||
65 | if ((unsigned long)dst < (unsigned long)src | ||
66 | || (unsigned long)src + size < (unsigned long)dst) | ||
67 | return memcpy (dst, src, size); | ||
68 | else { | ||
69 | char *_dst = dst + size; | ||
70 | const char *_src = src + size; | ||
71 | |||
72 | if (size >= CHUNK_SIZE | ||
73 | && CHUNK_ALIGNED (_src) && CHUNK_ALIGNED (_dst)) | ||
74 | { | ||
75 | /* Copy large blocks efficiently. */ | ||
76 | unsigned count; | ||
77 | for (count = size / CHUNK_SIZE; count; count--) { | ||
78 | _src -= CHUNK_SIZE; | ||
79 | _dst -= CHUNK_SIZE; | ||
80 | COPY_CHUNK (_src, _dst); | ||
81 | } | ||
82 | size %= CHUNK_SIZE; | ||
83 | } | ||
84 | |||
85 | if (size > 0) | ||
86 | do | ||
87 | *--_dst = *--_src; | ||
88 | while (--size); | ||
89 | |||
90 | return _dst; | ||
91 | } | ||
92 | } | ||