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 }
410 #define COMMON(x) \
411 __asm__("cld\n\t" \
412 "rep ; movsl" \
413 x \
414 : \
415 : "c" (n/4),"D" ((long) to),"S" ((long) from) \
416 : "cx","di","si","memory");
417
418 switch (n % 4) {
419 case 0: COMMON(""); return to;
420 case 1: COMMON("\n\tmovsb"); return to;
421 case 2: COMMON("\n\tmovsw"); return to;
422 case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
423 }
424 #undef COMMON
425 }
426
427 #define __HAVE_ARCH_MEMCPY
428 #define memcpy(t, f, n) \
429 (__builtin_constant_p(n) ? \
430 __constant_memcpy((t),(f),(n)) : \
431 __memcpy((t),(f),(n)))
432
433 #define __HAVE_ARCH_MEMMOVE
434 extern inline void * memmove(void * dest,const void * src, size_t n)
435 {
436 if (dest<src)
437 __asm__ __volatile__(
438 "cld\n\t"
439 "rep\n\t"
440 "movsb"
441 :
442 :"c" (n),"S" (src),"D" (dest)
443 :"cx","si","di");
444 else
445 __asm__ __volatile__(
446 "std\n\t"
447 "rep\n\t"
448 "movsb\n\t"
449 "cld"
450 :
451 :"c" (n),
452 "S" (n-1+(const char *)src),
453 "D" (n-1+(char *)dest)
454 :"cx","si","di","memory");
455 return dest;
456 }
457
458 #define memcmp __builtin_memcmp
459
460 #define __HAVE_ARCH_MEMCHR
461 extern inline void * memchr(const void * cs,int c,size_t count)
462 {
463 register void * __res;
464 if (!count)
465 return NULL;
466 __asm__ __volatile__(
467 "cld\n\t"
468 "repne\n\t"
469 "scasb\n\t"
470 "je 1f\n\t"
471 "movl $1,%0\n"
472 "1:\tdecl %0"
473 :"=D" (__res):"a" (c),"D" (cs),"c" (count)
474 :"cx");
475 return __res;
476 }
477
478 extern inline void * __memset_generic(void * s, char c,size_t count)
479 {
480 __asm__ __volatile__(
481 "cld\n\t"
482 "rep\n\t"
483 "stosb"
484 :
485 :"a" (c),"D" (s),"c" (count)
486 :"cx","di","memory");
487 return s;
488 }
489
490
491 #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
492
493
494
495
496
497
498 extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
499 {
500 __asm__ __volatile__(
501 "cld\n\t"
502 "rep ; stosl\n\t"
503 "testb $2,%b1\n\t"
504 "je 1f\n\t"
505 "stosw\n"
506 "1:\ttestb $1,%b1\n\t"
507 "je 2f\n\t"
508 "stosb\n"
509 "2:"
510 :
511 :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
512 :"cx","di","memory");
513 return (s);
514 }
515
516
517 #define __HAVE_ARCH_STRNLEN
518 extern inline size_t strnlen(const char * s, size_t count)
519 {
520 register int __res;
521 __asm__ __volatile__(
522 "movl %1,%0\n\t"
523 "jmp 2f\n"
524 "1:\tcmpb $0,(%0)\n\t"
525 "je 3f\n\t"
526 "incl %0\n"
527 "2:\tdecl %2\n\t"
528 "cmpl $-1,%2\n\t"
529 "jne 1b\n"
530 "3:\tsubl %1,%0"
531 :"=a" (__res):"c" (s),"d" (count));
532 return __res;
533 }
534
535
536
537
538
539
540 extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
541 {
542 switch (count) {
543 case 0:
544 return s;
545 case 1:
546 *(unsigned char *)s = pattern;
547 return s;
548 case 2:
549 *(unsigned short *)s = pattern;
550 return s;
551 case 3:
552 *(unsigned short *)s = pattern;
553 *(2+(unsigned char *)s) = pattern;
554 return s;
555 case 4:
556 *(unsigned long *)s = pattern;
557 return s;
558 }
559 #define COMMON(x) \
560 __asm__("cld\n\t" \
561 "rep ; stosl" \
562 x \
563 : \
564 : "a" (pattern),"c" (count/4),"D" ((long) s) \
565 : "cx","di","memory")
566
567 switch (count % 4) {
568 case 0: COMMON(""); return s;
569 case 1: COMMON("\n\tstosb"); return s;
570 case 2: COMMON("\n\tstosw"); return s;
571 case 3: COMMON("\n\tstosw\n\tstosb"); return s;
572 }
573 #undef COMMON
574 }
575
576 #define __constant_c_x_memset(s, c, count) \
577 (__builtin_constant_p(count) ? \
578 __constant_c_and_count_memset((s),(c),(count)) : \
579 __constant_c_memset((s),(c),(count)))
580
581 #define __memset(s, c, count) \
582 (__builtin_constant_p(count) ? \
583 __constant_count_memset((s),(c),(count)) : \
584 __memset_generic((s),(c),(count)))
585
586 #define __HAVE_ARCH_MEMSET
587 #define memset(s, c, count) \
588 (__builtin_constant_p(c) ? \
589 __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
590 __memset((s),(c),(count)))
591
592
593
594
595 #define __HAVE_ARCH_MEMSCAN
596 extern inline void * memscan(void * addr, int c, size_t size)
597 {
598 if (!size)
599 return addr;
600 __asm__("cld
601 repnz; scasb
602 jnz 1f
603 dec %%edi
604 1: "
605 : "=D" (addr), "=c" (size)
606 : "0" (addr), "1" (size), "a" (c));
607 return addr;
608 }
609
610 #endif
611 #endif