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