| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * This file is subject to the terms and conditions of the GNU General Public | 
|  | 3 | * License.  See the file COPYING in the main directory of this archive | 
|  | 4 | * for more details. | 
|  | 5 | */ | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 6 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 7 | #define __IN_STRING_C | 
|  | 8 |  | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 9 | #include <linux/module.h> | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 10 | #include <linux/string.h> | 
|  | 11 |  | 
|  | 12 | char *strcpy(char *dest, const char *src) | 
|  | 13 | { | 
|  | 14 | return __kernel_strcpy(dest, src); | 
|  | 15 | } | 
|  | 16 | EXPORT_SYMBOL(strcpy); | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 17 |  | 
|  | 18 | void *memset(void *s, int c, size_t count) | 
|  | 19 | { | 
|  | 20 | void *xs = s; | 
|  | 21 | size_t temp, temp1; | 
|  | 22 |  | 
|  | 23 | if (!count) | 
|  | 24 | return xs; | 
|  | 25 | c &= 0xff; | 
|  | 26 | c |= c << 8; | 
|  | 27 | c |= c << 16; | 
|  | 28 | if ((long)s & 1) { | 
|  | 29 | char *cs = s; | 
|  | 30 | *cs++ = c; | 
|  | 31 | s = cs; | 
|  | 32 | count--; | 
|  | 33 | } | 
|  | 34 | if (count > 2 && (long)s & 2) { | 
|  | 35 | short *ss = s; | 
|  | 36 | *ss++ = c; | 
|  | 37 | s = ss; | 
|  | 38 | count -= 2; | 
|  | 39 | } | 
|  | 40 | temp = count >> 2; | 
|  | 41 | if (temp) { | 
|  | 42 | long *ls = s; | 
|  | 43 |  | 
|  | 44 | asm volatile ( | 
|  | 45 | "	movel %1,%2\n" | 
|  | 46 | "	andw  #7,%2\n" | 
|  | 47 | "	lsrl  #3,%1\n" | 
|  | 48 | "	negw  %2\n" | 
|  | 49 | "	jmp   %%pc@(2f,%2:w:2)\n" | 
|  | 50 | "1:	movel %3,%0@+\n" | 
|  | 51 | "	movel %3,%0@+\n" | 
|  | 52 | "	movel %3,%0@+\n" | 
|  | 53 | "	movel %3,%0@+\n" | 
|  | 54 | "	movel %3,%0@+\n" | 
|  | 55 | "	movel %3,%0@+\n" | 
|  | 56 | "	movel %3,%0@+\n" | 
|  | 57 | "	movel %3,%0@+\n" | 
|  | 58 | "2:	dbra  %1,1b\n" | 
|  | 59 | "	clrw  %1\n" | 
|  | 60 | "	subql #1,%1\n" | 
|  | 61 | "	jpl   1b" | 
|  | 62 | : "=a" (ls), "=d" (temp), "=&d" (temp1) | 
|  | 63 | : "d" (c), "0" (ls), "1" (temp)); | 
|  | 64 | s = ls; | 
|  | 65 | } | 
|  | 66 | if (count & 2) { | 
|  | 67 | short *ss = s; | 
|  | 68 | *ss++ = c; | 
|  | 69 | s = ss; | 
|  | 70 | } | 
|  | 71 | if (count & 1) { | 
|  | 72 | char *cs = s; | 
|  | 73 | *cs = c; | 
|  | 74 | } | 
|  | 75 | return xs; | 
|  | 76 | } | 
|  | 77 | EXPORT_SYMBOL(memset); | 
|  | 78 |  | 
|  | 79 | void *memcpy(void *to, const void *from, size_t n) | 
|  | 80 | { | 
|  | 81 | void *xto = to; | 
|  | 82 | size_t temp, temp1; | 
|  | 83 |  | 
|  | 84 | if (!n) | 
|  | 85 | return xto; | 
|  | 86 | if ((long)to & 1) { | 
|  | 87 | char *cto = to; | 
|  | 88 | const char *cfrom = from; | 
|  | 89 | *cto++ = *cfrom++; | 
|  | 90 | to = cto; | 
|  | 91 | from = cfrom; | 
|  | 92 | n--; | 
|  | 93 | } | 
|  | 94 | if (n > 2 && (long)to & 2) { | 
|  | 95 | short *sto = to; | 
|  | 96 | const short *sfrom = from; | 
|  | 97 | *sto++ = *sfrom++; | 
|  | 98 | to = sto; | 
|  | 99 | from = sfrom; | 
|  | 100 | n -= 2; | 
|  | 101 | } | 
|  | 102 | temp = n >> 2; | 
|  | 103 | if (temp) { | 
|  | 104 | long *lto = to; | 
|  | 105 | const long *lfrom = from; | 
|  | 106 |  | 
|  | 107 | asm volatile ( | 
|  | 108 | "	movel %2,%3\n" | 
|  | 109 | "	andw  #7,%3\n" | 
|  | 110 | "	lsrl  #3,%2\n" | 
|  | 111 | "	negw  %3\n" | 
|  | 112 | "	jmp   %%pc@(1f,%3:w:2)\n" | 
|  | 113 | "4:	movel %0@+,%1@+\n" | 
|  | 114 | "	movel %0@+,%1@+\n" | 
|  | 115 | "	movel %0@+,%1@+\n" | 
|  | 116 | "	movel %0@+,%1@+\n" | 
|  | 117 | "	movel %0@+,%1@+\n" | 
|  | 118 | "	movel %0@+,%1@+\n" | 
|  | 119 | "	movel %0@+,%1@+\n" | 
|  | 120 | "	movel %0@+,%1@+\n" | 
|  | 121 | "1:	dbra  %2,4b\n" | 
|  | 122 | "	clrw  %2\n" | 
|  | 123 | "	subql #1,%2\n" | 
|  | 124 | "	jpl   4b" | 
|  | 125 | : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) | 
|  | 126 | : "0" (lfrom), "1" (lto), "2" (temp)); | 
|  | 127 | to = lto; | 
|  | 128 | from = lfrom; | 
|  | 129 | } | 
|  | 130 | if (n & 2) { | 
|  | 131 | short *sto = to; | 
|  | 132 | const short *sfrom = from; | 
|  | 133 | *sto++ = *sfrom++; | 
|  | 134 | to = sto; | 
|  | 135 | from = sfrom; | 
|  | 136 | } | 
|  | 137 | if (n & 1) { | 
|  | 138 | char *cto = to; | 
|  | 139 | const char *cfrom = from; | 
|  | 140 | *cto = *cfrom; | 
|  | 141 | } | 
|  | 142 | return xto; | 
|  | 143 | } | 
|  | 144 | EXPORT_SYMBOL(memcpy); | 
|  | 145 |  | 
|  | 146 | void *memmove(void *dest, const void *src, size_t n) | 
|  | 147 | { | 
|  | 148 | void *xdest = dest; | 
|  | 149 | size_t temp; | 
|  | 150 |  | 
|  | 151 | if (!n) | 
|  | 152 | return xdest; | 
|  | 153 |  | 
|  | 154 | if (dest < src) { | 
|  | 155 | if ((long)dest & 1) { | 
|  | 156 | char *cdest = dest; | 
|  | 157 | const char *csrc = src; | 
|  | 158 | *cdest++ = *csrc++; | 
|  | 159 | dest = cdest; | 
|  | 160 | src = csrc; | 
|  | 161 | n--; | 
|  | 162 | } | 
|  | 163 | if (n > 2 && (long)dest & 2) { | 
|  | 164 | short *sdest = dest; | 
|  | 165 | const short *ssrc = src; | 
|  | 166 | *sdest++ = *ssrc++; | 
|  | 167 | dest = sdest; | 
|  | 168 | src = ssrc; | 
|  | 169 | n -= 2; | 
|  | 170 | } | 
|  | 171 | temp = n >> 2; | 
|  | 172 | if (temp) { | 
|  | 173 | long *ldest = dest; | 
|  | 174 | const long *lsrc = src; | 
|  | 175 | temp--; | 
|  | 176 | do | 
|  | 177 | *ldest++ = *lsrc++; | 
|  | 178 | while (temp--); | 
|  | 179 | dest = ldest; | 
|  | 180 | src = lsrc; | 
|  | 181 | } | 
|  | 182 | if (n & 2) { | 
|  | 183 | short *sdest = dest; | 
|  | 184 | const short *ssrc = src; | 
|  | 185 | *sdest++ = *ssrc++; | 
|  | 186 | dest = sdest; | 
|  | 187 | src = ssrc; | 
|  | 188 | } | 
|  | 189 | if (n & 1) { | 
|  | 190 | char *cdest = dest; | 
|  | 191 | const char *csrc = src; | 
|  | 192 | *cdest = *csrc; | 
|  | 193 | } | 
|  | 194 | } else { | 
|  | 195 | dest = (char *)dest + n; | 
|  | 196 | src = (const char *)src + n; | 
|  | 197 | if ((long)dest & 1) { | 
|  | 198 | char *cdest = dest; | 
|  | 199 | const char *csrc = src; | 
|  | 200 | *--cdest = *--csrc; | 
|  | 201 | dest = cdest; | 
|  | 202 | src = csrc; | 
|  | 203 | n--; | 
|  | 204 | } | 
|  | 205 | if (n > 2 && (long)dest & 2) { | 
|  | 206 | short *sdest = dest; | 
|  | 207 | const short *ssrc = src; | 
|  | 208 | *--sdest = *--ssrc; | 
|  | 209 | dest = sdest; | 
|  | 210 | src = ssrc; | 
|  | 211 | n -= 2; | 
|  | 212 | } | 
|  | 213 | temp = n >> 2; | 
|  | 214 | if (temp) { | 
|  | 215 | long *ldest = dest; | 
|  | 216 | const long *lsrc = src; | 
|  | 217 | temp--; | 
|  | 218 | do | 
|  | 219 | *--ldest = *--lsrc; | 
|  | 220 | while (temp--); | 
|  | 221 | dest = ldest; | 
|  | 222 | src = lsrc; | 
|  | 223 | } | 
|  | 224 | if (n & 2) { | 
|  | 225 | short *sdest = dest; | 
|  | 226 | const short *ssrc = src; | 
|  | 227 | *--sdest = *--ssrc; | 
|  | 228 | dest = sdest; | 
|  | 229 | src = ssrc; | 
|  | 230 | } | 
|  | 231 | if (n & 1) { | 
|  | 232 | char *cdest = dest; | 
|  | 233 | const char *csrc = src; | 
|  | 234 | *--cdest = *--csrc; | 
|  | 235 | } | 
|  | 236 | } | 
|  | 237 | return xdest; | 
|  | 238 | } | 
|  | 239 | EXPORT_SYMBOL(memmove); | 
|  | 240 |  | 
|  | 241 | int memcmp(const void *cs, const void *ct, size_t count) | 
|  | 242 | { | 
|  | 243 | const unsigned char *su1, *su2; | 
|  | 244 |  | 
|  | 245 | for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) | 
|  | 246 | if (*su1 != *su2) | 
|  | 247 | return *su1 < *su2 ? -1 : +1; | 
|  | 248 | return 0; | 
|  | 249 | } | 
|  | 250 | EXPORT_SYMBOL(memcmp); |