x86/mm/pat: Don't report PAT on CPUs that don't support it
[linux/fpc-iii.git] / arch / openrisc / lib / memcpy.c
blob669887a60e27a74d506cb6101660264b369496d4
1 /*
2 * arch/openrisc/lib/memcpy.c
4 * Optimized memory copy routines for openrisc. These are mostly copied
5 * from ohter sources but slightly entended based on ideas discuassed in
6 * #openrisc.
8 * The word unroll implementation is an extension to the arm byte
9 * unrolled implementation, but using word copies (if things are
10 * properly aligned)
12 * The great arm loop unroll algorithm can be found at:
13 * arch/arm/boot/compressed/string.c
16 #include <linux/export.h>
18 #include <linux/string.h>
20 #ifdef CONFIG_OR1K_1200
22 * Do memcpy with word copies and loop unrolling. This gives the
23 * best performance on the OR1200 and MOR1KX archirectures
25 void *memcpy(void *dest, __const void *src, __kernel_size_t n)
27 int i = 0;
28 unsigned char *d, *s;
29 uint32_t *dest_w = (uint32_t *)dest, *src_w = (uint32_t *)src;
31 /* If both source and dest are word aligned copy words */
32 if (!((unsigned int)dest_w & 3) && !((unsigned int)src_w & 3)) {
33 /* Copy 32 bytes per loop */
34 for (i = n >> 5; i > 0; i--) {
35 *dest_w++ = *src_w++;
36 *dest_w++ = *src_w++;
37 *dest_w++ = *src_w++;
38 *dest_w++ = *src_w++;
39 *dest_w++ = *src_w++;
40 *dest_w++ = *src_w++;
41 *dest_w++ = *src_w++;
42 *dest_w++ = *src_w++;
45 if (n & 1 << 4) {
46 *dest_w++ = *src_w++;
47 *dest_w++ = *src_w++;
48 *dest_w++ = *src_w++;
49 *dest_w++ = *src_w++;
52 if (n & 1 << 3) {
53 *dest_w++ = *src_w++;
54 *dest_w++ = *src_w++;
57 if (n & 1 << 2)
58 *dest_w++ = *src_w++;
60 d = (unsigned char *)dest_w;
61 s = (unsigned char *)src_w;
63 } else {
64 d = (unsigned char *)dest_w;
65 s = (unsigned char *)src_w;
67 for (i = n >> 3; i > 0; i--) {
68 *d++ = *s++;
69 *d++ = *s++;
70 *d++ = *s++;
71 *d++ = *s++;
72 *d++ = *s++;
73 *d++ = *s++;
74 *d++ = *s++;
75 *d++ = *s++;
78 if (n & 1 << 2) {
79 *d++ = *s++;
80 *d++ = *s++;
81 *d++ = *s++;
82 *d++ = *s++;
86 if (n & 1 << 1) {
87 *d++ = *s++;
88 *d++ = *s++;
91 if (n & 1)
92 *d++ = *s++;
94 return dest;
96 #else
98 * Use word copies but no loop unrolling as we cannot assume there
99 * will be benefits on the archirecture
101 void *memcpy(void *dest, __const void *src, __kernel_size_t n)
103 unsigned char *d = (unsigned char *)dest, *s = (unsigned char *)src;
104 uint32_t *dest_w = (uint32_t *)dest, *src_w = (uint32_t *)src;
106 /* If both source and dest are word aligned copy words */
107 if (!((unsigned int)dest_w & 3) && !((unsigned int)src_w & 3)) {
108 for (; n >= 4; n -= 4)
109 *dest_w++ = *src_w++;
112 d = (unsigned char *)dest_w;
113 s = (unsigned char *)src_w;
115 /* For remaining or if not aligned, copy bytes */
116 for (; n >= 1; n -= 1)
117 *d++ = *s++;
119 return dest;
122 #endif
124 EXPORT_SYMBOL(memcpy);