aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/lib/memcpy.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/lib/memcpy.c')
-rw-r--r--arch/microblaze/lib/memcpy.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
index 014bac92bdff..cc495d7d99cc 100644
--- a/arch/microblaze/lib/memcpy.c
+++ b/arch/microblaze/lib/memcpy.c
@@ -33,17 +33,24 @@
33#include <asm/system.h> 33#include <asm/system.h>
34 34
35#ifdef __HAVE_ARCH_MEMCPY 35#ifdef __HAVE_ARCH_MEMCPY
36#ifndef CONFIG_OPT_LIB_FUNCTION
36void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c) 37void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
37{ 38{
38 const char *src = v_src; 39 const char *src = v_src;
39 char *dst = v_dst; 40 char *dst = v_dst;
40#ifndef CONFIG_OPT_LIB_FUNCTION 41
41 /* Simple, byte oriented memcpy. */ 42 /* Simple, byte oriented memcpy. */
42 while (c--) 43 while (c--)
43 *dst++ = *src++; 44 *dst++ = *src++;
44 45
45 return v_dst; 46 return v_dst;
46#else 47}
48#else /* CONFIG_OPT_LIB_FUNCTION */
49void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
50{
51 const char *src = v_src;
52 char *dst = v_dst;
53
47 /* The following code tries to optimize the copy by using unsigned 54 /* The following code tries to optimize the copy by using unsigned
48 * alignment. This will work fine if both source and destination are 55 * alignment. This will work fine if both source and destination are
49 * aligned on the same boundary. However, if they are aligned on 56 * aligned on the same boundary. However, if they are aligned on
@@ -86,7 +93,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
86 case 0x1: /* Unaligned - Off by 1 */ 93 case 0x1: /* Unaligned - Off by 1 */
87 /* Word align the source */ 94 /* Word align the source */
88 i_src = (const void *) ((unsigned)src & ~3); 95 i_src = (const void *) ((unsigned)src & ~3);
89 96#ifndef __MICROBLAZEEL__
90 /* Load the holding buffer */ 97 /* Load the holding buffer */
91 buf_hold = *i_src++ << 8; 98 buf_hold = *i_src++ << 8;
92 99
@@ -95,7 +102,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
95 *i_dst++ = buf_hold | value >> 24; 102 *i_dst++ = buf_hold | value >> 24;
96 buf_hold = value << 8; 103 buf_hold = value << 8;
97 } 104 }
105#else
106 /* Load the holding buffer */
107 buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
98 108
109 for (; c >= 4; c -= 4) {
110 value = *i_src++;
111 *i_dst++ = buf_hold | ((value & 0xFF) << 24);
112 buf_hold = (value & 0xFFFFFF00) >>8;
113 }
114#endif
99 /* Realign the source */ 115 /* Realign the source */
100 src = (const void *)i_src; 116 src = (const void *)i_src;
101 src -= 3; 117 src -= 3;
@@ -103,7 +119,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
103 case 0x2: /* Unaligned - Off by 2 */ 119 case 0x2: /* Unaligned - Off by 2 */
104 /* Word align the source */ 120 /* Word align the source */
105 i_src = (const void *) ((unsigned)src & ~3); 121 i_src = (const void *) ((unsigned)src & ~3);
106 122#ifndef __MICROBLAZEEL__
107 /* Load the holding buffer */ 123 /* Load the holding buffer */
108 buf_hold = *i_src++ << 16; 124 buf_hold = *i_src++ << 16;
109 125
@@ -112,7 +128,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
112 *i_dst++ = buf_hold | value >> 16; 128 *i_dst++ = buf_hold | value >> 16;
113 buf_hold = value << 16; 129 buf_hold = value << 16;
114 } 130 }
131#else
132 /* Load the holding buffer */
133 buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
115 134
135 for (; c >= 4; c -= 4) {
136 value = *i_src++;
137 *i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
138 buf_hold = (value & 0xFFFF0000) >>16;
139 }
140#endif
116 /* Realign the source */ 141 /* Realign the source */
117 src = (const void *)i_src; 142 src = (const void *)i_src;
118 src -= 2; 143 src -= 2;
@@ -120,7 +145,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
120 case 0x3: /* Unaligned - Off by 3 */ 145 case 0x3: /* Unaligned - Off by 3 */
121 /* Word align the source */ 146 /* Word align the source */
122 i_src = (const void *) ((unsigned)src & ~3); 147 i_src = (const void *) ((unsigned)src & ~3);
123 148#ifndef __MICROBLAZEEL__
124 /* Load the holding buffer */ 149 /* Load the holding buffer */
125 buf_hold = *i_src++ << 24; 150 buf_hold = *i_src++ << 24;
126 151
@@ -129,7 +154,16 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
129 *i_dst++ = buf_hold | value >> 8; 154 *i_dst++ = buf_hold | value >> 8;
130 buf_hold = value << 24; 155 buf_hold = value << 24;
131 } 156 }
157#else
158 /* Load the holding buffer */
159 buf_hold = (*i_src++ & 0xFF000000) >> 24;
132 160
161 for (; c >= 4; c -= 4) {
162 value = *i_src++;
163 *i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
164 buf_hold = (value & 0xFF000000) >> 24;
165 }
166#endif
133 /* Realign the source */ 167 /* Realign the source */
134 src = (const void *)i_src; 168 src = (const void *)i_src;
135 src -= 1; 169 src -= 1;
@@ -150,7 +184,7 @@ void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
150 } 184 }
151 185
152 return v_dst; 186 return v_dst;
153#endif
154} 187}
188#endif /* CONFIG_OPT_LIB_FUNCTION */
155EXPORT_SYMBOL(memcpy); 189EXPORT_SYMBOL(memcpy);
156#endif /* __HAVE_ARCH_MEMCPY */ 190#endif /* __HAVE_ARCH_MEMCPY */