This source file includes following definitions.
- strcpy
- strncpy
- strcat
- strncat
- strcmp
- strncmp
- strchr
- strrchr
- strspn
- strcspn
- strpbrk
- strstr
- strlen
- strtok
- __memcpy
- __constant_memcpy
- memmove
- memcmp
- memchr
- __memset_generic
- __constant_c_and_count_memset
- memscan
1 #ifndef _I386_STRING_H_
2 #define _I386_STRING_H_
3
4
5
6
7
8
9
10
11
12
13
14
15
16 extern inline char * strcpy(char * dest,const char *src)
17 {
18 __asm__ __volatile__(
19 "cld\n"
20 "1:\tlodsb\n\t"
21 "stosb\n\t"
22 "testb %%al,%%al\n\t"
23 "jne 1b"
24 :
25 :"S" (src),"D" (dest):"si","di","ax","memory");
26 return dest;
27 }
28
29 extern inline char * strncpy(char * dest,const char *src,size_t count)
30 {
31 __asm__ __volatile__(
32 "cld\n"
33 "1:\tdecl %2\n\t"
34 "js 2f\n\t"
35 "lodsb\n\t"
36 "stosb\n\t"
37 "testb %%al,%%al\n\t"
38 "jne 1b\n\t"
39 "rep\n\t"
40 "stosb\n"
41 "2:"
42 :
43 :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
44 return dest;
45 }
46
47 extern inline char * strcat(char * dest,const char * src)
48 {
49 __asm__ __volatile__(
50 "cld\n\t"
51 "repne\n\t"
52 "scasb\n\t"
53 "decl %1\n"
54 "1:\tlodsb\n\t"
55 "stosb\n\t"
56 "testb %%al,%%al\n\t"
57 "jne 1b"
58 :
59 :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
60 return dest;
61 }
62
63 extern inline char * strncat(char * dest,const char * src,size_t count)
64 {
65 __asm__ __volatile__(
66 "cld\n\t"
67 "repne\n\t"
68 "scasb\n\t"
69 "decl %1\n\t"
70 "movl %4,%3\n"
71 "1:\tdecl %3\n\t"
72 "js 2f\n\t"
73 "lodsb\n\t"
74 "stosb\n\t"
75 "testb %%al,%%al\n\t"
76 "jne 1b\n"
77 "2:\txorl %2,%2\n\t"
78 "stosb"
79 :
80 :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
81 :"si","di","ax","cx","memory");
82 return dest;
83 }
84
85 extern inline int strcmp(const char * cs,const char * ct)
86 {
87 register int __res;
88 __asm__ __volatile__(
89 "cld\n"
90 "1:\tlodsb\n\t"
91 "scasb\n\t"
92 "jne 2f\n\t"
93 "testb %%al,%%al\n\t"
94 "jne 1b\n\t"
95 "xorl %%eax,%%eax\n\t"
96 "jmp 3f\n"
97 "2:\tsbbl %%eax,%%eax\n\t"
98 "orb $1,%%eax\n"
99 "3:"
100 :"=a" (__res):"S" (cs),"D" (ct):"si","di");
101 return __res;
102 }
103
104 extern inline int strncmp(const char * cs,const char * ct,size_t count)
105 {
106 register int __res;
107 __asm__ __volatile__(
108 "cld\n"
109 "1:\tdecl %3\n\t"
110 "js 2f\n\t"
111 "lodsb\n\t"
112 "scasb\n\t"
113 "jne 3f\n\t"
114 "testb %%al,%%al\n\t"
115 "jne 1b\n"
116 "2:\txorl %%eax,%%eax\n\t"
117 "jmp 4f\n"
118 "3:\tsbbl %%eax,%%eax\n\t"
119 "orb $1,%%al\n"
120 "4:"
121 :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
122 return __res;
123 }
124
125 extern inline char * strchr(const char * s, int c)
126 {
127 register char * __res;
128 __asm__ __volatile__(
129 "cld\n\t"
130 "movb %%al,%%ah\n"
131 "1:\tlodsb\n\t"
132 "cmpb %%ah,%%al\n\t"
133 "je 2f\n\t"
134 "testb %%al,%%al\n\t"
135 "jne 1b\n\t"
136 "movl $1,%1\n"
137 "2:\tmovl %1,%0\n\t"
138 "decl %0"
139 :"=a" (__res):"S" (s),"0" (c):"si");
140 return __res;
141 }
142
143 extern inline char * strrchr(const char * s, int c)
144 {
145 register char * __res;
146 __asm__ __volatile__(
147 "cld\n\t"
148 "movb %%al,%%ah\n"
149 "1:\tlodsb\n\t"
150 "cmpb %%ah,%%al\n\t"
151 "jne 2f\n\t"
152 "leal -1(%%esi),%0\n"
153 "2:\ttestb %%al,%%al\n\t"
154 "jne 1b"
155 :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
156 return __res;
157 }
158
159 extern inline size_t strspn(const char * cs, const char * ct)
160 {
161 register char * __res;
162 __asm__ __volatile__(
163 "cld\n\t"
164 "movl %4,%%edi\n\t"
165 "repne\n\t"
166 "scasb\n\t"
167 "notl %%ecx\n\t"
168 "decl %%ecx\n\t"
169 "movl %%ecx,%%edx\n"
170 "1:\tlodsb\n\t"
171 "testb %%al,%%al\n\t"
172 "je 2f\n\t"
173 "movl %4,%%edi\n\t"
174 "movl %%edx,%%ecx\n\t"
175 "repne\n\t"
176 "scasb\n\t"
177 "je 1b\n"
178 "2:\tdecl %0"
179 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
180 :"ax","cx","dx","di");
181 return __res-cs;
182 }
183
184 extern inline size_t strcspn(const char * cs, const char * ct)
185 {
186 register char * __res;
187 __asm__ __volatile__(
188 "cld\n\t"
189 "movl %4,%%edi\n\t"
190 "repne\n\t"
191 "scasb\n\t"
192 "notl %%ecx\n\t"
193 "decl %%ecx\n\t"
194 "movl %%ecx,%%edx\n"
195 "1:\tlodsb\n\t"
196 "testb %%al,%%al\n\t"
197 "je 2f\n\t"
198 "movl %4,%%edi\n\t"
199 "movl %%edx,%%ecx\n\t"
200 "repne\n\t"
201 "scasb\n\t"
202 "jne 1b\n"
203 "2:\tdecl %0"
204 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
205 :"ax","cx","dx","di");
206 return __res-cs;
207 }
208
209 extern inline char * strpbrk(const char * cs,const char * ct)
210 {
211 register char * __res;
212 __asm__ __volatile__(
213 "cld\n\t"
214 "movl %4,%%edi\n\t"
215 "repne\n\t"
216 "scasb\n\t"
217 "notl %%ecx\n\t"
218 "decl %%ecx\n\t"
219 "movl %%ecx,%%edx\n"
220 "1:\tlodsb\n\t"
221 "testb %%al,%%al\n\t"
222 "je 2f\n\t"
223 "movl %4,%%edi\n\t"
224 "movl %%edx,%%ecx\n\t"
225 "repne\n\t"
226 "scasb\n\t"
227 "jne 1b\n\t"
228 "decl %0\n\t"
229 "jmp 3f\n"
230 "2:\txorl %0,%0\n"
231 "3:"
232 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
233 :"ax","cx","dx","di");
234 return __res;
235 }
236
237 extern inline char * strstr(const char * cs,const char * ct)
238 {
239 register char * __res;
240 __asm__ __volatile__(
241 "cld\n\t" \
242 "movl %4,%%edi\n\t"
243 "repne\n\t"
244 "scasb\n\t"
245 "notl %%ecx\n\t"
246 "decl %%ecx\n\t"
247 "movl %%ecx,%%edx\n"
248 "1:\tmovl %4,%%edi\n\t"
249 "movl %%esi,%%eax\n\t"
250 "movl %%edx,%%ecx\n\t"
251 "repe\n\t"
252 "cmpsb\n\t"
253 "je 2f\n\t"
254 "xchgl %%eax,%%esi\n\t"
255 "incl %%esi\n\t"
256 "cmpb $0,-1(%%eax)\n\t"
257 "jne 1b\n\t"
258 "xorl %%eax,%%eax\n\t"
259 "2:"
260 :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
261 :"cx","dx","di","si");
262 return __res;
263 }
264
265 extern inline size_t strlen(const char * s)
266 {
267 register int __res;
268 __asm__ __volatile__(
269 "cld\n\t"
270 "repne\n\t"
271 "scasb\n\t"
272 "notl %0\n\t"
273 "decl %0"
274 :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
275 return __res;
276 }
277
278 extern char * ___strtok;
279
280 extern inline char * strtok(char * s,const char * ct)
281 {
282 register char * __res;
283 __asm__ __volatile__(
284 "testl %1,%1\n\t"
285 "jne 1f\n\t"
286 "testl %0,%0\n\t"
287 "je 8f\n\t"
288 "movl %0,%1\n"
289 "1:\txorl %0,%0\n\t"
290 "movl $-1,%%ecx\n\t"
291 "xorl %%eax,%%eax\n\t"
292 "cld\n\t"
293 "movl %4,%%edi\n\t"
294 "repne\n\t"
295 "scasb\n\t"
296 "notl %%ecx\n\t"
297 "decl %%ecx\n\t"
298 "je 7f\n\t"
299 "movl %%ecx,%%edx\n"
300 "2:\tlodsb\n\t"
301 "testb %%al,%%al\n\t"
302 "je 7f\n\t"
303 "movl %4,%%edi\n\t"
304 "movl %%edx,%%ecx\n\t"
305 "repne\n\t"
306 "scasb\n\t"
307 "je 2b\n\t"
308 "decl %1\n\t"
309 "cmpb $0,(%1)\n\t"
310 "je 7f\n\t"
311 "movl %1,%0\n"
312 "3:\tlodsb\n\t"
313 "testb %%al,%%al\n\t"
314 "je 5f\n\t"
315 "movl %4,%%edi\n\t"
316 "movl %%edx,%%ecx\n\t"
317 "repne\n\t"
318 "scasb\n\t"
319 "jne 3b\n\t"
320 "decl %1\n\t"
321 "cmpb $0,(%1)\n\t"
322 "je 5f\n\t"
323 "movb $0,(%1)\n\t"
324 "incl %1\n\t"
325 "jmp 6f\n"
326 "5:\txorl %1,%1\n"
327 "6:\tcmpb $0,(%0)\n\t"
328 "jne 7f\n\t"
329 "xorl %0,%0\n"
330 "7:\ttestl %0,%0\n\t"
331 "jne 8f\n\t"
332 "movl %0,%1\n"
333 "8:"
334 :"=b" (__res),"=S" (___strtok)
335 :"0" (___strtok),"1" (s),"g" (ct)
336 :"ax","cx","dx","di","memory");
337 return __res;
338 }
339
340 extern inline void * __memcpy(void * to, const void * from, size_t n)
341 {
342 __asm__ __volatile__(
343 "cld\n\t"
344 "movl %%edx, %%ecx\n\t"
345 "shrl $2,%%ecx\n\t"
346 "rep ; movsl\n\t"
347 "testb $1,%%dl\n\t"
348 "je 1f\n\t"
349 "movsb\n"
350 "1:\ttestb $2,%%dl\n\t"
351 "je 2f\n\t"
352 "movsw\n"
353 "2:\n"
354 :
355 :"d" (n),"D" ((long) to),"S" ((long) from)
356 : "cx","di","si","memory");
357 return (to);
358 }
359
360
361
362
363
364 extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
365 {
366 switch (n) {
367 case 0:
368 return to;
369 case 1:
370 *(unsigned char *)to = *(unsigned char *)from;
371 return to;
372 case 2:
373 *(unsigned short *)to = *(unsigned short *)from;
374 return to;
375 case 3:
376 *(unsigned short *)to = *(unsigned short *)from;
377 *(2+(unsigned char *)to) = *(2+(unsigned char *)from);
378 return to;
379 case 4:
380 *(unsigned long *)to = *(unsigned long *)from;
381 return to;
382 }
383 #define COMMON(x) \
384 __asm__("cld\n\t" \
385 "rep ; movsl" \
386 x \
387 : \
388 : "c" (n/4),"D" ((long) to),"S" ((long) from) \
389 : "cx","di","si","memory");
390
391 switch (n % 4) {
392 case 0: COMMON(""); return to;
393 case 1: COMMON("\n\tmovsb"); return to;
394 case 2: COMMON("\n\tmovsw"); return to;
395 case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
396 }
397 #undef COMMON
398 }
399
400 #define memcpy(t, f, n) \
401 (__builtin_constant_p(n) ? \
402 __constant_memcpy((t),(f),(n)) : \
403 __memcpy((t),(f),(n)))
404
405 extern inline void * memmove(void * dest,const void * src, size_t n)
406 {
407 if (dest<src)
408 __asm__ __volatile__(
409 "cld\n\t"
410 "rep\n\t"
411 "movsb"
412 :
413 :"c" (n),"S" (src),"D" (dest)
414 :"cx","si","di");
415 else
416 __asm__ __volatile__(
417 "std\n\t"
418 "rep\n\t"
419 "movsb\n\t"
420 "cld"
421 :
422 :"c" (n),
423 "S" (n-1+(const char *)src),
424 "D" (n-1+(char *)dest)
425 :"cx","si","di","memory");
426 return dest;
427 }
428
429 extern inline int memcmp(const void * cs,const void * ct,size_t count)
430 {
431 register int __res;
432 __asm__ __volatile__(
433 "cld\n\t"
434 "repe\n\t"
435 "cmpsb\n\t"
436 "je 1f\n\t"
437 "sbbl %%eax,%%eax\n\t"
438 "orb $1,%%al\n"
439 "1:"
440 :"=a" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
441 :"si","di","cx");
442 return __res;
443 }
444
445 extern inline void * memchr(const void * cs,int c,size_t count)
446 {
447 register void * __res;
448 if (!count)
449 return NULL;
450 __asm__ __volatile__(
451 "cld\n\t"
452 "repne\n\t"
453 "scasb\n\t"
454 "je 1f\n\t"
455 "movl $1,%0\n"
456 "1:\tdecl %0"
457 :"=D" (__res):"a" (c),"D" (cs),"c" (count)
458 :"cx");
459 return __res;
460 }
461
462 extern inline void * __memset_generic(void * s, char c,size_t count)
463 {
464 __asm__ __volatile__(
465 "cld\n\t"
466 "rep\n\t"
467 "stosb"
468 :
469 :"a" (c),"D" (s),"c" (count)
470 :"cx","di","memory");
471 return s;
472 }
473
474
475 #define __constant_c_memset(s,c,count) __memset_generic((s),(unsigned char)(c),(count))
476 #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
477
478
479
480
481
482 extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
483 {
484 switch (count) {
485 case 0:
486 return s;
487 case 1:
488 *(unsigned char *)s = pattern;
489 return s;
490 case 2:
491 *(unsigned short *)s = pattern;
492 return s;
493 case 3:
494 *(unsigned short *)s = pattern;
495 *(2+(unsigned char *)s) = pattern;
496 return s;
497 case 4:
498 *(unsigned long *)s = pattern;
499 return s;
500 }
501 #define COMMON(x) \
502 __asm__("cld\n\t" \
503 "rep ; stosl" \
504 x \
505 : \
506 : "a" (pattern),"c" (count/4),"D" ((long) s) \
507 : "cx","di","memory")
508
509 switch (count % 4) {
510 case 0: COMMON(""); return s;
511 case 1: COMMON("\n\tstosb"); return s;
512 case 2: COMMON("\n\tstosw"); return s;
513 case 3: COMMON("\n\tstosw\n\tstosb"); return s;
514 }
515 #undef COMMON
516 }
517
518 #define __constant_c_x_memset(s, c, count) \
519 (__builtin_constant_p(count) ? \
520 __constant_c_and_count_memset((s),(c),(count)) : \
521 __constant_c_memset((s),(c),(count)))
522
523 #define __memset(s, c, count) \
524 (__builtin_constant_p(count) ? \
525 __constant_count_memset((s),(c),(count)) : \
526 __memset_generic((s),(c),(count)))
527
528 #define memset(s, c, count) \
529 (__builtin_constant_p(c) ? \
530 __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
531 __memset((s),(c),(count)))
532
533
534
535
536 extern inline void * memscan(void * addr, int c, size_t size)
537 {
538 if (!size)
539 return addr;
540 __asm__("cld
541 repnz; scasb
542 jnz 1f
543 dec %%edi
544 1: "
545 : "=D" (addr), "=c" (size)
546 : "0" (addr), "1" (size), "a" (c));
547 return addr;
548 }
549
550 #endif