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