vfs: check userland buffers before reading them.
[haiku.git] / src / system / libroot / posix / glibc / include / arch / x86 / bits / string.h
blobd181afd48b8c16c4c67c57cf8f69417e80e60e75
1 /* Optimized, inlined string functions. i386 version.
2 Copyright (C) 1997,1998,1999,2000,2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifndef _STRING_H
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
22 #endif
24 /* The ix86 processors can access unaligned multi-byte variables. */
25 #define _STRING_ARCH_unaligned 1
28 /* We only provide optimizations if the user selects them and if
29 GNU CC is used. */
30 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
31 && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
33 #ifndef __STRING_INLINE
34 # ifdef __cplusplus
35 # define __STRING_INLINE inline
36 # else
37 # define __STRING_INLINE extern __inline
38 # endif
39 #endif
42 /* Copy N bytes of SRC to DEST. */
43 #define _HAVE_STRING_ARCH_memcpy 1
44 #define memcpy(dest, src, n) \
45 (__extension__ (__builtin_constant_p (n) \
46 ? __memcpy_c ((dest), (src), (n)) \
47 : memcpy ((dest), (src), (n))))
48 /* This looks horribly ugly, but the compiler can optimize it totally,
49 as the count is constant. */
50 __STRING_INLINE void *__memcpy_c (void *__dest, __const void *__src,
51 size_t __n);
53 __STRING_INLINE void *
54 __memcpy_c (void *__dest, __const void *__src, size_t __n)
56 register unsigned long int __d0, __d1, __d2;
57 union {
58 unsigned int __ui;
59 unsigned short int __usi;
60 unsigned char __uc;
61 } *__u = __dest;
62 switch (__n)
64 case 0:
65 return __dest;
66 case 1:
67 __u->__uc = *(const unsigned char *) __src;
68 return __dest;
69 case 2:
70 __u->__usi = *(const unsigned short int *) __src;
71 return __dest;
72 case 3:
73 __u->__usi = *(const unsigned short int *) __src;
74 __u = (void *) __u + 2;
75 __u->__uc = *(2 + (const unsigned char *) __src);
76 return __dest;
77 case 4:
78 __u->__ui = *(const unsigned int *) __src;
79 return __dest;
80 case 6:
81 __u->__ui = *(const unsigned int *) __src;
82 __u = (void *) __u + 4;
83 __u->__usi = *(2 + (const unsigned short int *) __src);
84 return __dest;
85 case 8:
86 __u->__ui = *(const unsigned int *) __src;
87 __u = (void *) __u + 4;
88 __u->__ui = *(1 + (const unsigned int *) __src);
89 return __dest;
90 case 12:
91 __u->__ui = *(const unsigned int *) __src;
92 __u = (void *) __u + 4;
93 __u->__ui = *(1 + (const unsigned int *) __src);
94 __u = (void *) __u + 4;
95 __u->__ui = *(2 + (const unsigned int *) __src);
96 return __dest;
97 case 16:
98 __u->__ui = *(const unsigned int *) __src;
99 __u = (void *) __u + 4;
100 __u->__ui = *(1 + (const unsigned int *) __src);
101 __u = (void *) __u + 4;
102 __u->__ui = *(2 + (const unsigned int *) __src);
103 __u = (void *) __u + 4;
104 __u->__ui = *(3 + (const unsigned int *) __src);
105 return __dest;
106 case 20:
107 __u->__ui = *(const unsigned int *) __src;
108 __u = (void *) __u + 4;
109 __u->__ui = *(1 + (const unsigned int *) __src);
110 __u = (void *) __u + 4;
111 __u->__ui = *(2 + (const unsigned int *) __src);
112 __u = (void *) __u + 4;
113 __u->__ui = *(3 + (const unsigned int *) __src);
114 __u = (void *) __u + 4;
115 __u->__ui = *(4 + (const unsigned int *) __src);
116 return __dest;
118 #define __COMMON_CODE(x) \
119 __asm__ __volatile__ \
120 ("cld\n\t" \
121 "rep; movsl" \
123 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
124 : "0" (__n / 4), "1" (&__u->__uc), "2" (__src) \
125 : "memory");
127 switch (__n % 4)
129 case 0:
130 __COMMON_CODE ("");
131 break;
132 case 1:
133 __COMMON_CODE ("\n\tmovsb");
134 break;
135 case 2:
136 __COMMON_CODE ("\n\tmovsw");
137 break;
138 case 3:
139 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
140 break;
142 return __dest;
143 #undef __COMMON_CODE
147 /* Copy N bytes of SRC to DEST, guaranteeing
148 correct behavior for overlapping strings. */
149 #define _HAVE_STRING_ARCH_memmove 1
150 #ifndef _FORCE_INLINES
151 __STRING_INLINE void *
152 memmove (void *__dest, __const void *__src, size_t __n)
154 register unsigned long int __d0, __d1, __d2;
155 if (__dest < __src)
156 __asm__ __volatile__
157 ("cld\n\t"
158 "rep\n\t"
159 "movsb"
160 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
161 : "0" (__n), "1" (__src), "2" (__dest)
162 : "memory");
163 else
164 __asm__ __volatile__
165 ("std\n\t"
166 "rep\n\t"
167 "movsb\n\t"
168 "cld"
169 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
170 : "0" (__n), "1" (__n - 1 + (const char *) __src),
171 "2" (__n - 1 + (char *) __dest)
172 : "memory");
173 return __dest;
175 #endif
177 /* Set N bytes of S to C. */
178 #define _HAVE_STRING_ARCH_memset 1
179 #define _USE_STRING_ARCH_memset 1
180 #define memset(s, c, n) \
181 (__extension__ (__builtin_constant_p (c) \
182 ? (__builtin_constant_p (n) \
183 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
184 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
185 : __memset_gg (s, c, n)))
187 __STRING_INLINE void *__memset_cc (void *__s, unsigned long int __pattern,
188 size_t __n);
190 __STRING_INLINE void *
191 __memset_cc (void *__s, unsigned long int __pattern, size_t __n)
193 register unsigned long int __d0, __d1;
194 union {
195 unsigned int __ui;
196 unsigned short int __usi;
197 unsigned char __uc;
198 } *__u = __s;
199 switch (__n)
201 case 0:
202 return __s;
203 case 1:
204 __u->__uc = __pattern;
205 return __s;
206 case 2:
207 __u->__usi = __pattern;
208 return __s;
209 case 3:
210 __u->__usi = __pattern;
211 __u = __extension__ ((void *) __u + 2);
212 __u->__uc = __pattern;
213 return __s;
214 case 4:
215 __u->__ui = __pattern;
216 return __s;
218 #define __COMMON_CODE(x) \
219 __asm__ __volatile__ \
220 ("cld\n\t" \
221 "rep; stosl" \
223 : "=&c" (__d0), "=&D" (__d1) \
224 : "a" (__pattern), "0" (__n / 4), "1" (&__u->__uc) \
225 : "memory")
227 switch (__n % 4)
229 case 0:
230 __COMMON_CODE ("");
231 break;
232 case 1:
233 __COMMON_CODE ("\n\tstosb");
234 break;
235 case 2:
236 __COMMON_CODE ("\n\tstosw");
237 break;
238 case 3:
239 __COMMON_CODE ("\n\tstosw\n\tstosb");
240 break;
242 return __s;
243 #undef __COMMON_CODE
246 __STRING_INLINE void *__memset_cg (void *__s, unsigned long __c, size_t __n);
248 __STRING_INLINE void *
249 __memset_cg (void *__s, unsigned long __c, size_t __n)
251 register unsigned long int __d0, __d1;
252 __asm__ __volatile__
253 ("cld\n\t"
254 "rep; stosl\n\t"
255 "testb $2,%b3\n\t"
256 "je 1f\n\t"
257 "stosw\n"
258 "1:\n\t"
259 "testb $1,%b3\n\t"
260 "je 2f\n\t"
261 "stosb\n"
262 "2:"
263 : "=&c" (__d0), "=&D" (__d1)
264 : "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
265 : "memory");
266 return __s;
269 __STRING_INLINE void *__memset_gg (void *__s, char __c, size_t __n);
271 __STRING_INLINE void *
272 __memset_gg (void *__s, char __c, size_t __n)
274 register unsigned long int __d0, __d1;
275 __asm__ __volatile__
276 ("cld\n\t"
277 "rep; stosb"
278 : "=&D" (__d0), "=&c" (__d1)
279 : "a" (__c), "0" (__s), "1" (__n)
280 : "memory");
281 return __s;
287 /* Search N bytes of S for C. */
288 #define _HAVE_STRING_ARCH_memchr 1
289 #ifndef _FORCE_INLINES
290 __STRING_INLINE void *
291 memchr (__const void *__s, int __c, size_t __n)
293 register unsigned long int __d0;
294 register void *__res;
295 if (__n == 0)
296 return NULL;
297 __asm__ __volatile__
298 ("cld\n\t"
299 "repne; scasb\n\t"
300 "je 1f\n\t"
301 "movl $1,%0\n"
302 "1:"
303 : "=D" (__res), "=&c" (__d0)
304 : "a" (__c), "0" (__s), "1" (__n),
305 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
306 : "cc");
307 return __res - 1;
309 #endif
311 #define _HAVE_STRING_ARCH_memrchr 1
312 #ifndef _FORCE_INLINES
313 __STRING_INLINE void *
314 __memrchr (__const void *__s, int __c, size_t __n)
316 register unsigned long int __d0;
317 register void *__res;
318 if (__n == 0)
319 return NULL;
320 __asm__ __volatile__
321 ("std\n\t"
322 "repne; scasb\n\t"
323 "je 1f\n\t"
324 "orl $-1,%0\n"
325 "1:\tcld\n\t"
326 "incl %0"
327 : "=D" (__res), "=&c" (__d0)
328 : "a" (__c), "0" (__s + __n - 1), "1" (__n),
329 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
330 : "cc");
331 return __res;
333 # ifdef __USE_GNU
334 # define memrchr(s, c, n) __memrchr (s, c, n)
335 # endif
336 #endif
338 /* Return the length of S. */
339 #define _HAVE_STRING_ARCH_strlen 1
340 #ifndef _FORCE_INLINES
341 __STRING_INLINE size_t
342 strlen (__const char *__str)
344 register unsigned long int __d0;
345 register size_t __res;
346 __asm__ __volatile__
347 ("cld\n\t"
348 "repne; scasb\n\t"
349 "notl %0"
350 : "=c" (__res), "=&D" (__d0)
351 : "1" (__str), "a" (0), "0" (0xffffffff),
352 "m" ( *(struct { char __x[0xfffffff]; } *)__str)
353 : "cc");
354 return __res - 1;
356 #endif
358 /* Copy SRC to DEST. */
359 #define _HAVE_STRING_ARCH_strcpy 1
360 #ifndef _FORCE_INLINES
361 __STRING_INLINE char *
362 strcpy (char *__dest, __const char *__src)
364 register unsigned long int __d0, __d1;
365 __asm__ __volatile__
366 ("cld\n"
367 "1:\n\t"
368 "lodsb\n\t"
369 "stosb\n\t"
370 "testb %%al,%%al\n\t"
371 "jne 1b"
372 : "=&S" (__d0), "=&D" (__d1)
373 : "0" (__src), "1" (__dest)
374 : "ax", "memory", "cc");
375 return __dest;
377 #endif
379 /* Copy no more than N characters of SRC to DEST. */
380 #define _HAVE_STRING_ARCH_strncpy 1
381 #ifndef _FORCE_INLINES
382 __STRING_INLINE char *
383 strncpy (char *__dest, __const char *__src, size_t __n)
385 register unsigned long int __d0, __d1, __d2;
386 __asm__ __volatile__
387 ("cld\n"
388 "1:\n\t"
389 "decl %2\n\t"
390 "js 2f\n\t"
391 "lodsb\n\t"
392 "stosb\n\t"
393 "testb %%al,%%al\n\t"
394 "jne 1b\n\t"
395 "rep; stosb\n"
396 "2:"
397 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
398 : "0" (__src), "1" (__dest), "2" (__n)
399 : "ax", "memory", "cc");
400 return __dest;
402 #endif
404 /* Append SRC onto DEST. */
405 #define _HAVE_STRING_ARCH_strcat 1
406 #ifndef _FORCE_INLINES
407 __STRING_INLINE char *
408 strcat (char *__dest, __const char *__src)
410 register unsigned long int __d0, __d1, __d2, __d3;
411 __asm__ __volatile__
412 ("cld\n\t"
413 "repne; scasb\n\t"
414 "decl %1\n"
415 "1:\n\t"
416 "lodsb\n\t"
417 "stosb\n\t"
418 "testb %%al,%%al\n\t"
419 "jne 1b"
420 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
421 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
422 : "memory", "cc");
423 return __dest;
425 #endif
427 /* Append no more than N characters from SRC onto DEST. */
428 #define _HAVE_STRING_ARCH_strncat 1
429 #ifndef _FORCE_INLINES
430 __STRING_INLINE char *
431 strncat (char *__dest, __const char *__src, size_t __n)
433 register unsigned long int __d0, __d1, __d2, __d3;
434 __asm__ __volatile__
435 ("cld\n\t"
436 "repne; scasb\n\t"
437 "decl %1\n\t"
438 "movl %4,%2\n"
439 "1:\n\t"
440 "decl %2\n\t"
441 "js 2f\n\t"
442 "lodsb\n\t"
443 "stosb\n\t"
444 "testb %%al,%%al\n\t"
445 "jne 1b\n\t"
446 "jmp 3f\n"
447 "2:\n\t"
448 "xorl %3,%3\n\t"
449 "stosb\n"
450 "3:"
451 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
452 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
453 : "memory", "cc");
454 return __dest;
456 #endif
458 /* Compare S1 and S2. */
459 #define _HAVE_STRING_ARCH_strcmp 1
460 #ifndef _FORCE_INLINES
461 __STRING_INLINE int
462 strcmp (__const char *__s1, __const char *__s2)
464 register unsigned long int __d0, __d1;
465 register int __res;
466 __asm__ __volatile__
467 ("cld\n"
468 "1:\n\t"
469 "lodsb\n\t"
470 "scasb\n\t"
471 "jne 2f\n\t"
472 "testb %%al,%%al\n\t"
473 "jne 1b\n\t"
474 "xorl %%eax,%%eax\n\t"
475 "jmp 3f\n"
476 "2:\n\t"
477 "sbbl %%eax,%%eax\n\t"
478 "orb $1,%%al\n"
479 "3:"
480 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
481 : "1" (__s1), "2" (__s2),
482 "m" ( *(struct { char __x[0xfffffff]; } *)__s1),
483 "m" ( *(struct { char __x[0xfffffff]; } *)__s2)
484 : "cc");
485 return __res;
487 #endif
489 /* Compare N characters of S1 and S2. */
490 #define _HAVE_STRING_ARCH_strncmp 1
491 #ifndef _FORCE_INLINES
492 __STRING_INLINE int
493 strncmp (__const char *__s1, __const char *__s2, size_t __n)
495 register unsigned long int __d0, __d1, __d2;
496 register int __res;
497 __asm__ __volatile__
498 ("cld\n"
499 "1:\n\t"
500 "decl %3\n\t"
501 "js 2f\n\t"
502 "lodsb\n\t"
503 "scasb\n\t"
504 "jne 3f\n\t"
505 "testb %%al,%%al\n\t"
506 "jne 1b\n"
507 "2:\n\t"
508 "xorl %%eax,%%eax\n\t"
509 "jmp 4f\n"
510 "3:\n\t"
511 "sbbl %%eax,%%eax\n\t"
512 "orb $1,%%al\n"
513 "4:"
514 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
515 : "1" (__s1), "2" (__s2), "3" (__n),
516 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
517 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
518 : "cc");
519 return __res;
521 #endif
523 /* Find the first occurrence of C in S. */
524 #define _HAVE_STRING_ARCH_strchr 1
525 #define _USE_STRING_ARCH_strchr 1
526 #define strchr(s, c) \
527 (__extension__ (__builtin_constant_p (c) \
528 ? __strchr_c (s, ((c) & 0xff) << 8) \
529 : __strchr_g (s, c)))
531 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
533 __STRING_INLINE char *
534 __strchr_g (__const char *__s, int __c)
536 register unsigned long int __d0;
537 register char *__res;
538 __asm__ __volatile__
539 ("cld\n\t"
540 "movb %%al,%%ah\n"
541 "1:\n\t"
542 "lodsb\n\t"
543 "cmpb %%ah,%%al\n\t"
544 "je 2f\n\t"
545 "testb %%al,%%al\n\t"
546 "jne 1b\n\t"
547 "movl $1,%1\n"
548 "2:\n\t"
549 "movl %1,%0"
550 : "=a" (__res), "=&S" (__d0)
551 : "0" (__c), "1" (__s),
552 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
553 : "cc");
554 return __res - 1;
557 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
559 __STRING_INLINE char *
560 __strchr_c (__const char *__s, int __c)
562 register unsigned long int __d0;
563 register char *__res;
564 __asm__ __volatile__
565 ("cld\n\t"
566 "1:\n\t"
567 "lodsb\n\t"
568 "cmpb %%ah,%%al\n\t"
569 "je 2f\n\t"
570 "testb %%al,%%al\n\t"
571 "jne 1b\n\t"
572 "movl $1,%1\n"
573 "2:\n\t"
574 "movl %1,%0"
575 : "=a" (__res), "=&S" (__d0)
576 : "0" (__c), "1" (__s),
577 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
578 : "cc");
579 return __res - 1;
583 /* Find the first occurrence of C in S or the final NUL byte. */
584 #define _HAVE_STRING_ARCH_strchrnul 1
585 #define __strchrnul(s, c) \
586 (__extension__ (__builtin_constant_p (c) \
587 ? ((c) == '\0' \
588 ? (char *) __rawmemchr (s, c) \
589 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
590 : __strchrnul_g (s, c)))
592 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
594 __STRING_INLINE char *
595 __strchrnul_g (__const char *__s, int __c)
597 register unsigned long int __d0;
598 register char *__res;
599 __asm__ __volatile__
600 ("cld\n\t"
601 "movb %%al,%%ah\n"
602 "1:\n\t"
603 "lodsb\n\t"
604 "cmpb %%ah,%%al\n\t"
605 "je 2f\n\t"
606 "testb %%al,%%al\n\t"
607 "jne 1b\n\t"
608 "2:\n\t"
609 "movl %1,%0"
610 : "=a" (__res), "=&S" (__d0)
611 : "0" (__c), "1" (__s),
612 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
613 : "cc");
614 return __res - 1;
617 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
619 __STRING_INLINE char *
620 __strchrnul_c (__const char *__s, int __c)
622 register unsigned long int __d0;
623 register char *__res;
624 __asm__ __volatile__
625 ("cld\n\t"
626 "1:\n\t"
627 "lodsb\n\t"
628 "cmpb %%ah,%%al\n\t"
629 "je 2f\n\t"
630 "testb %%al,%%al\n\t"
631 "jne 1b\n\t"
632 "2:\n\t"
633 "movl %1,%0"
634 : "=a" (__res), "=&S" (__d0)
635 : "0" (__c), "1" (__s),
636 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
637 : "cc");
638 return __res - 1;
640 #ifdef __USE_GNU
641 # define strchrnul(s, c) __strchrnul (s, c)
642 #endif
645 /* Return the length of the initial segment of S which
646 consists entirely of characters not in REJECT. */
647 #define _HAVE_STRING_ARCH_strcspn 1
648 #ifndef _FORCE_INLINES
649 # ifdef __PIC__
650 __STRING_INLINE size_t
651 strcspn (__const char *__s, __const char *__reject)
653 register unsigned long int __d0, __d1, __d2;
654 register char *__res;
655 __asm__ __volatile__
656 ("pushl %%ebx\n\t"
657 "cld\n\t"
658 "movl %4,%%edi\n\t"
659 "repne; scasb\n\t"
660 "notl %%ecx\n\t"
661 "decl %%ecx\n\t"
662 "movl %%ecx,%%ebx\n"
663 "1:\n\t"
664 "lodsb\n\t"
665 "testb %%al,%%al\n\t"
666 "je 2f\n\t"
667 "movl %4,%%edi\n\t"
668 "movl %%ebx,%%ecx\n\t"
669 "repne; scasb\n\t"
670 "jne 1b\n"
671 "2:\n\t"
672 "popl %%ebx"
673 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
674 : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
675 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
676 : "cc");
677 return (__res - 1) - __s;
679 # else
680 __STRING_INLINE size_t
681 strcspn (__const char *__s, __const char *__reject)
683 register unsigned long int __d0, __d1, __d2, __d3;
684 register char *__res;
685 __asm__ __volatile__
686 ("cld\n\t"
687 "movl %5,%%edi\n\t"
688 "repne; scasb\n\t"
689 "notl %%ecx\n\t"
690 "decl %%ecx\n\t"
691 "movl %%ecx,%%edx\n"
692 "1:\n\t"
693 "lodsb\n\t"
694 "testb %%al,%%al\n\t"
695 "je 2f\n\t"
696 "movl %5,%%edi\n\t"
697 "movl %%edx,%%ecx\n\t"
698 "repne; scasb\n\t"
699 "jne 1b\n"
700 "2:"
701 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
702 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
703 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
704 : "cc");
705 return (__res - 1) - __s;
707 # endif
708 #endif
711 /* Return the length of the initial segment of S which
712 consists entirely of characters in ACCEPT. */
713 #define _HAVE_STRING_ARCH_strspn 1
714 #ifndef _FORCE_INLINES
715 # ifdef __PIC__
716 __STRING_INLINE size_t
717 strspn (__const char *__s, __const char *__accept)
719 register unsigned long int __d0, __d1, __d2;
720 register char *__res;
721 __asm__ __volatile__
722 ("pushl %%ebx\n\t"
723 "cld\n\t"
724 "movl %4,%%edi\n\t"
725 "repne; scasb\n\t"
726 "notl %%ecx\n\t"
727 "decl %%ecx\n\t"
728 "movl %%ecx,%%ebx\n"
729 "1:\n\t"
730 "lodsb\n\t"
731 "testb %%al,%%al\n\t"
732 "je 2f\n\t"
733 "movl %4,%%edi\n\t"
734 "movl %%ebx,%%ecx\n\t"
735 "repne; scasb\n\t"
736 "je 1b\n"
737 "2:\n\t"
738 "popl %%ebx"
739 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
740 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
741 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
742 : "cc");
743 return (__res - 1) - __s;
745 # else
746 __STRING_INLINE size_t
747 strspn (__const char *__s, __const char *__accept)
749 register unsigned long int __d0, __d1, __d2, __d3;
750 register char *__res;
751 __asm__ __volatile__
752 ("cld\n\t"
753 "movl %5,%%edi\n\t"
754 "repne; scasb\n\t"
755 "notl %%ecx\n\t"
756 "decl %%ecx\n\t"
757 "movl %%ecx,%%edx\n"
758 "1:\n\t"
759 "lodsb\n\t"
760 "testb %%al,%%al\n\t"
761 "je 2f\n\t"
762 "movl %5,%%edi\n\t"
763 "movl %%edx,%%ecx\n\t"
764 "repne; scasb\n\t"
765 "je 1b\n"
766 "2:"
767 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
768 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
769 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
770 : "cc");
771 return (__res - 1) - __s;
773 # endif
774 #endif
777 /* Find the first occurrence in S of any character in ACCEPT. */
778 #define _HAVE_STRING_ARCH_strpbrk 1
779 #ifndef _FORCE_INLINES
780 # ifdef __PIC__
781 __STRING_INLINE char *
782 strpbrk (__const char *__s, __const char *__accept)
784 unsigned long int __d0, __d1, __d2;
785 register char *__res;
786 __asm__ __volatile__
787 ("pushl %%ebx\n\t"
788 "cld\n\t"
789 "movl %4,%%edi\n\t"
790 "repne; scasb\n\t"
791 "notl %%ecx\n\t"
792 "decl %%ecx\n\t"
793 "movl %%ecx,%%ebx\n"
794 "1:\n\t"
795 "lodsb\n\t"
796 "testb %%al,%%al\n\t"
797 "je 2f\n\t"
798 "movl %4,%%edi\n\t"
799 "movl %%ebx,%%ecx\n\t"
800 "repne; scasb\n\t"
801 "jne 1b\n\t"
802 "decl %0\n\t"
803 "jmp 3f\n"
804 "2:\n\t"
805 "xorl %0,%0\n"
806 "3:\n\t"
807 "popl %%ebx"
808 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
809 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
810 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
811 : "cc");
812 return __res;
814 # else
815 __STRING_INLINE char *
816 strpbrk (__const char *__s, __const char *__accept)
818 register unsigned long int __d0, __d1, __d2, __d3;
819 register char *__res;
820 __asm__ __volatile__
821 ("cld\n\t"
822 "movl %5,%%edi\n\t"
823 "repne; scasb\n\t"
824 "notl %%ecx\n\t"
825 "decl %%ecx\n\t"
826 "movl %%ecx,%%edx\n"
827 "1:\n\t"
828 "lodsb\n\t"
829 "testb %%al,%%al\n\t"
830 "je 2f\n\t"
831 "movl %5,%%edi\n\t"
832 "movl %%edx,%%ecx\n\t"
833 "repne; scasb\n\t"
834 "jne 1b\n\t"
835 "decl %0\n\t"
836 "jmp 3f\n"
837 "2:\n\t"
838 "xorl %0,%0\n"
839 "3:"
840 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
841 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
842 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
843 : "cc");
844 return __res;
846 # endif
847 #endif
850 /* Find the first occurrence of NEEDLE in HAYSTACK. */
851 #define _HAVE_STRING_ARCH_strstr 1
852 #ifndef _FORCE_INLINES
853 # ifdef __PIC__
854 __STRING_INLINE char *
855 strstr (__const char *__haystack, __const char *__needle)
857 register unsigned long int __d0, __d1, __d2;
858 register char *__res;
859 __asm__ __volatile__
860 ("pushl %%ebx\n\t"
861 "cld\n\t" \
862 "movl %4,%%edi\n\t"
863 "repne; scasb\n\t"
864 "notl %%ecx\n\t"
865 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
866 "movl %%ecx,%%ebx\n"
867 "1:\n\t"
868 "movl %4,%%edi\n\t"
869 "movl %%esi,%%eax\n\t"
870 "movl %%ebx,%%ecx\n\t"
871 "repe; cmpsb\n\t"
872 "je 2f\n\t" /* also works for empty string, see above */
873 "xchgl %%eax,%%esi\n\t"
874 "incl %%esi\n\t"
875 "cmpb $0,-1(%%eax)\n\t"
876 "jne 1b\n\t"
877 "xorl %%eax,%%eax\n\t"
878 "2:\n\t"
879 "popl %%ebx"
880 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
881 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
882 : "memory", "cc");
883 return __res;
885 # else
886 __STRING_INLINE char *
887 strstr (__const char *__haystack, __const char *__needle)
889 register unsigned long int __d0, __d1, __d2, __d3;
890 register char *__res;
891 __asm__ __volatile__
892 ("cld\n\t" \
893 "movl %5,%%edi\n\t"
894 "repne; scasb\n\t"
895 "notl %%ecx\n\t"
896 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
897 "movl %%ecx,%%edx\n"
898 "1:\n\t"
899 "movl %5,%%edi\n\t"
900 "movl %%esi,%%eax\n\t"
901 "movl %%edx,%%ecx\n\t"
902 "repe; cmpsb\n\t"
903 "je 2f\n\t" /* also works for empty string, see above */
904 "xchgl %%eax,%%esi\n\t"
905 "incl %%esi\n\t"
906 "cmpb $0,-1(%%eax)\n\t"
907 "jne 1b\n\t"
908 "xorl %%eax,%%eax\n\t"
909 "2:"
910 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
911 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
912 : "memory", "cc");
913 return __res;
915 # endif
916 #endif
918 #ifndef _FORCE_INLINES
919 # undef __STRING_INLINE
920 #endif
922 #endif /* use string inlines && GNU CC */