]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/bits/string.h
Update.
[thirdparty/glibc.git] / sysdeps / i386 / bits / string.h
CommitLineData
92f1da4d 1/* Optimized, inlined string functions. i386 version.
74015205 2 Copyright (C) 1997, 1998 Free Software Foundation, Inc.
92f1da4d
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20#ifndef _STRING_H
61eb22d3 21# error "Never use <bits/string.h> directly; include <string.h> instead."
92f1da4d
UD
22#endif
23
61eb22d3
UD
24/* The ix86 processors can access unaligned multi-byte variables. */
25#define _STRING_ARCH_unaligned 1
26
27
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
92f1da4d
UD
32
33#ifdef __cplusplus
34# define __STRING_INLINE inline
35#else
36# define __STRING_INLINE extern __inline
37#endif
38
39
40/* Copy N bytes of SRC to DEST. */
74015205 41#define _HAVE_STRING_ARCH_memcpy 1
92f1da4d
UD
42#define memcpy(dest, src, n) \
43 (__extension__ (__builtin_constant_p (n) \
44 ? __memcpy_c (dest, src, n) \
45 : memcpy (dest, src, n)))
46/* This looks horribly ugly, but the compiler can optimize it totally,
47 as the count is constant. */
48__STRING_INLINE void *
49__memcpy_c (void *__dest, __const void *__src, size_t __n)
50{
a44d2393 51 register unsigned long int __d0, __d1, __d2;
9a0a462c 52 switch (__n)
92f1da4d
UD
53 {
54 case 0:
55 return __dest;
56 case 1:
57 *(unsigned char *) __dest = *(const unsigned char *) __src;
58 return __dest;
59 case 2:
60 *(unsigned short int *) __dest = *(const unsigned short int *) __src;
61 return __dest;
62 case 3:
63 *(unsigned short int *) __dest = *(const unsigned short int *) __src;
64 *(2 + (unsigned char *) __dest) = *(2 + (const unsigned char *) __src);
65 return __dest;
66 case 4:
67 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
68 return __dest;
69 case 6: /* for ethernet addresses */
70 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
71 *(2 + (unsigned short int *) __dest) =
72 *(2 + (const unsigned short int *) __src);
73 return __dest;
74 case 8:
63bda0c1 75 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
92f1da4d
UD
76 *(1 + (unsigned long int *) __dest) =
77 *(1 + (const unsigned long int *) __src);
78 return __dest;
79 case 12:
80 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
81 *(1 + (unsigned long int *) __dest) =
82 *(1 + (const unsigned long int *) __src);
83 *(2 + (unsigned long int *) __dest) =
84 *(2 + (const unsigned long int *) __src);
85 return __dest;
86 case 16:
87 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
88 *(1 + (unsigned long int *) __dest) =
89 *(1 + (const unsigned long int *) __src);
90 *(2 + (unsigned long int *) __dest) =
91 *(2 + (const unsigned long int *) __src);
92 *(3 + (unsigned long int *) __dest) =
93 *(3 + (const unsigned long int *) __src);
94 return __dest;
95 case 20:
96 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
97 *(1 + (unsigned long int *) __dest) =
98 *(1 + (const unsigned long int *) __src);
99 *(2 + (unsigned long int *) __dest) =
100 *(2 + (const unsigned long int *) __src);
101 *(3 + (unsigned long int *) __dest) =
102 *(3 + (const unsigned long int *) __src);
103 *(4 + (unsigned long int *) __dest) =
104 *(4 + (const unsigned long int *) __src);
105 return __dest;
106 }
107#define __COMMON_CODE(x) \
108 __asm__ __volatile__ \
109 ("cld\n\t" \
110 "rep; movsl" \
111 x \
68b50604
UD
112 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
113 : "0" (__n / 4), "1" (__dest), "2" (__src) \
114 : "memory");
92f1da4d 115
9a0a462c 116 switch (__n % 4)
92f1da4d
UD
117 {
118 case 0:
119 __COMMON_CODE ("");
120 return __dest;
121 case 1:
122 __COMMON_CODE ("\n\tmovsb");
123 return __dest;
124 case 2:
125 __COMMON_CODE ("\n\tmovsw");
126 return __dest;
127 case 3:
128 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
129 return __dest;
130 }
131#undef __COMMON_CODE
132}
133
134
135/* Copy N bytes of SRC to DEST, guaranteeing
136 correct behavior for overlapping strings. */
74015205 137#define _HAVE_STRING_ARCH_memmove 1
92f1da4d
UD
138__STRING_INLINE void *
139memmove (void *__dest, __const void *__src, size_t __n)
140{
a44d2393 141 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
142 if (__dest < __src)
143 __asm__ __volatile__
144 ("cld\n\t"
145 "rep\n\t"
146 "movsb"
68b50604
UD
147 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
148 : "0" (__n), "1" (__src), "2" (__dest)
149 : "memory");
92f1da4d
UD
150 else
151 __asm__ __volatile__
152 ("std\n\t"
153 "rep\n\t"
154 "movsb\n\t"
155 "cld"
68b50604
UD
156 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
157 : "0" (__n), "1" (__n - 1 + (const char *) __src),
158 "2" (__n - 1 + (char *) __dest)
159 : "memory");
92f1da4d
UD
160 return __dest;
161}
162
163
164/* Set N bytes of S to C. */
74015205 165#define _HAVE_STRING_ARCH_memset 1
92f1da4d
UD
166#define memset(s, c, n) \
167 (__extension__ (__builtin_constant_p (c) \
168 ? (__builtin_constant_p (n) \
169 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
170 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
171 : __memset_gg (s, c, n)))
172
173__STRING_INLINE void *
174__memset_cc (void *__s, unsigned long int __pattern, size_t __n)
175{
a44d2393 176 register unsigned long int __d0, __d1;
92f1da4d
UD
177 switch (__n)
178 {
179 case 0:
63bda0c1 180 return __s;
92f1da4d
UD
181 case 1:
182 *(unsigned char *) __s = __pattern;
183 return __s;
184 case 2:
185 *(unsigned short int *) __s = __pattern;
63bda0c1 186 return __s;
92f1da4d
UD
187 case 3:
188 *(unsigned short int *) __s = __pattern;
189 *(2 + (unsigned char *) __s) = __pattern;
190 return __s;
191 case 4:
192 *(unsigned long *) __s = __pattern;
193 return __s;
194 }
195#define __COMMON_CODE(x) \
196 __asm__ __volatile__ \
197 ("cld\n\t" \
198 "rep; stosl" \
199 x \
68b50604 200 : "=&c" (__d0), "=&D" (__d1) \
a44d2393 201 : "a" (__pattern), "0" (__n / 4), "1" (__s) \
68b50604 202 : "memory")
92f1da4d
UD
203
204 switch (__n % 4)
205 {
206 case 0:
207 __COMMON_CODE ("");
208 return __s;
209 case 1:
210 __COMMON_CODE ("\n\tstosb");
211 return __s;
212 case 2:
63bda0c1 213 __COMMON_CODE ("\n\tstosw");
92f1da4d
UD
214 return s;
215 case 3:
216 __COMMON_CODE ("\n\tstosw\n\tstosb");
217 return __s;
218 }
219#undef __COMMON_CODE
220}
221
222__STRING_INLINE void *
223__memset_cg (void *__s, unsigned long __c, size_t __n)
224{
a44d2393 225 register unsigned long int __d0, __d1;
92f1da4d
UD
226 __asm__ __volatile__
227 ("cld\n\t"
228 "rep; stosl\n\t"
68b50604 229 "testb $2,%b3\n\t"
92f1da4d
UD
230 "je 1f\n\t"
231 "stosw\n"
232 "1:\n\t"
68b50604 233 "testb $1,%b3\n\t"
92f1da4d
UD
234 "je 2f\n\t"
235 "stosb\n"
236 "2:"
68b50604
UD
237 : "=&c" (__d0), "=&D" (__d1)
238 : "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
239 : "memory");
92f1da4d
UD
240 return __s;
241}
242
243__STRING_INLINE void *
244__memset_gg (void *__s, char __c, size_t __n)
245{
a44d2393 246 register unsigned long int __d0, __d1;
92f1da4d
UD
247 __asm__ __volatile__
248 ("cld\n\t"
9a0a462c 249 "rep; stosb"
68b50604
UD
250 : "=&D" (__d0), "=&c" (__d1)
251 : "a" (__c), "0" (__s), "1" (__n)
252 : "memory");
92f1da4d
UD
253 return __s;
254}
255
256
257
258
259/* Search N bytes of S for C. */
74015205 260#define _HAVE_STRING_ARCH_memchr 1
92f1da4d
UD
261__STRING_INLINE void *
262memchr (__const void *__s, int __c, size_t __n)
263{
a44d2393 264 register unsigned long int __d0;
92f1da4d 265 register void *__res;
a44d2393 266 if (__n == 0)
92f1da4d
UD
267 return NULL;
268 __asm__ __volatile__
269 ("cld\n\t"
a44d2393
UD
270 "repne; scasb\n\t"
271 "je 1f\n\t"
272 "movl $1,%0\n"
92f1da4d 273 "1:"
68b50604
UD
274 : "=D" (__res), "=&c" (__d0)
275 : "a" (__c), "0" (__s), "1" (__n));
92f1da4d
UD
276 return __res - 1;
277}
278
279
280/* Return the length of S. */
74015205 281#define _HAVE_STRING_ARCH_strlen 1
92f1da4d
UD
282__STRING_INLINE size_t
283strlen (__const char *__str)
284{
a44d2393 285 register unsigned long int __d0;
92f1da4d
UD
286 register size_t __res;
287 __asm__ __volatile__
288 ("cld\n\t"
289 "repne; scasb\n\t"
290 "notl %0"
68b50604
UD
291 : "=c" (__res), "=&D" (__d0)
292 : "1" (__str), "a" (0), "0" (0xffffffff)
293 : "cc");
92f1da4d
UD
294 return __res - 1;
295}
296
297
298/* Copy SRC to DEST. */
74015205 299#define _HAVE_STRING_ARCH_strcpy 1
92f1da4d
UD
300__STRING_INLINE char *
301strcpy (char *__dest, __const char *__src)
302{
a44d2393 303 register unsigned long int __d0, __d1;
92f1da4d
UD
304 __asm__ __volatile__
305 ("cld\n"
306 "1:\n\t"
307 "lodsb\n\t"
308 "stosb\n\t"
309 "testb %%al,%%al\n\t"
310 "jne 1b"
68b50604
UD
311 : "=&S" (__d0), "=&D" (__d1)
312 : "0" (__src), "1" (__dest)
313 : "ax", "memory", "cc");
92f1da4d
UD
314 return __dest;
315}
316
317
318/* Copy no more than N characters of SRC to DEST. */
74015205 319#define _HAVE_STRING_ARCH_strncpy 1
92f1da4d
UD
320__STRING_INLINE char *
321strncpy (char *__dest, __const char *__src, size_t __n)
322{
a44d2393 323 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
324 __asm__ __volatile__
325 ("cld\n"
326 "1:\n\t"
327 "decl %2\n\t"
328 "js 2f\n\t"
329 "lodsb\n\t"
330 "stosb\n\t"
331 "testb %%al,%%al\n\t"
332 "jne 1b\n\t"
333 "rep; stosb\n"
334 "2:"
68b50604
UD
335 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
336 : "0" (__src), "1" (__dest), "2" (__n)
337 : "ax", "memory", "cc");
92f1da4d
UD
338 return __dest;
339}
340
341
342/* Append SRC onto DEST. */
74015205 343#define _HAVE_STRING_ARCH_strcat 1
92f1da4d
UD
344__STRING_INLINE char *
345strcat (char *__dest, __const char *__src)
346{
a44d2393 347 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
348 __asm__ __volatile__
349 ("cld\n\t"
350 "repne; scasb\n\t"
351 "decl %1\n"
352 "1:\n\t"
353 "lodsb\n\t"
354 "stosb\n\t"
355 "testb %%al,%%al\n\t"
356 "jne 1b"
68b50604
UD
357 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
358 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
359 : "memory", "cc");
92f1da4d
UD
360 return __dest;
361}
362
363
364/* Append no more than N characters from SRC onto DEST. */
74015205 365#define _HAVE_STRING_ARCH_strncat 1
92f1da4d
UD
366__STRING_INLINE char *
367strncat (char *__dest, __const char *__src, size_t __n)
368{
a44d2393 369 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
370 __asm__ __volatile__
371 ("cld\n\t"
372 "repne; scasb\n\t"
373 "decl %1\n\t"
68b50604 374 "movl %5,%3\n"
92f1da4d
UD
375 "1:\n\t"
376 "decl %3\n\t"
377 "js 2f\n\t"
378 "lodsb\n\t"
379 "stosb\n\t"
380 "testb %%al,%%al\n\t"
381 "jne 1b\n"
382 "2:\n\t"
383 "xorl %2,%2\n\t"
384 "stosb"
68b50604
UD
385 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
386 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
387 : "memory", "cc");
92f1da4d
UD
388 return __dest;
389}
390
391
392/* Compare S1 and S2. */
74015205 393#define _HAVE_STRING_ARCH_strcmp 1
92f1da4d
UD
394__STRING_INLINE int
395strcmp (__const char *__s1, __const char *__s2)
396{
a44d2393 397 register unsigned long int __d0, __d1;
92f1da4d
UD
398 register int __res;
399 __asm__ __volatile__
400 ("cld\n"
401 "1:\n\t"
402 "lodsb\n\t"
403 "scasb\n\t"
404 "jne 2f\n\t"
405 "testb %%al,%%al\n\t"
406 "jne 1b\n\t"
407 "xorl %%eax,%%eax\n\t"
408 "jmp 3f\n"
409 "2:\n\t"
410 "sbbl %%eax,%%eax\n\t"
411 "orb $1,%%eax\n"
412 "3:"
68b50604
UD
413 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
414 : "1" (__s1), "2" (__s2)
415 : "cc");
92f1da4d
UD
416 return __res;
417}
418
419
420/* Compare N characters of S1 and S2. */
74015205 421#define _HAVE_STRING_ARCH_strncmp 1
92f1da4d
UD
422__STRING_INLINE int
423strncmp (__const char *__s1, __const char *__s2, size_t __n)
424{
a44d2393 425 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
426 register int __res;
427 __asm__ __volatile__
428 ("cld\n"
429 "1:\n\t"
430 "decl %3\n\t"
431 "js 2f\n\t"
432 "lodsb\n\t"
433 "scasb\n\t"
434 "jne 3f\n\t"
435 "testb %%al,%%al\n\t"
436 "jne 1b\n"
437 "2:\n\t"
438 "xorl %%eax,%%eax\n\t"
439 "jmp 4f\n"
440 "3:\n\t"
441 "sbbl %%eax,%%eax\n\t"
442 "orb $1,%%al\n"
443 "4:"
68b50604
UD
444 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
445 : "1" (__s1), "2" (__s2), "3" (__n)
446 : "cc");
92f1da4d
UD
447 return __res;
448}
449
450
451/* Find the first occurrence of C in S. */
74015205 452#define _HAVE_STRING_ARCH_strchr 1
92f1da4d
UD
453#define strchr(s, c) \
454 (__extension__ (__builtin_constant_p (c) \
455 ? __strchr_c (s, ((c) & 0xff) << 8) \
456 : __strchr_g (s, c)))
457
458__STRING_INLINE char *
459__strchr_g (__const char *__s, int __c)
460{
a44d2393 461 register unsigned long int __d0;
92f1da4d
UD
462 register char *__res;
463 __asm__ __volatile__
464 ("cld\n\t"
465 "movb %%al,%%ah\n"
466 "1:\n\t"
467 "lodsb\n\t"
468 "cmpb %%ah,%%al\n\t"
469 "je 2f\n\t"
470 "testb %%al,%%al\n\t"
471 "jne 1b\n\t"
472 "movl $1,%1\n"
473 "2:\n\t"
474 "movl %1,%0"
68b50604
UD
475 : "=a" (__res), "=&S" (__d0)
476 : "0" (__c), "1" (__s)
477 : "cc");
92f1da4d
UD
478 return __res - 1;
479}
480
481__STRING_INLINE char *
482__strchr_c (__const char *__s, int __c)
483{
a44d2393 484 register unsigned long int __d0;
92f1da4d
UD
485 register char *__res;
486 __asm__ __volatile__
487 ("cld\n\t"
488 "1:\n\t"
489 "lodsb\n\t"
490 "cmpb %%ah,%%al\n\t"
491 "je 2f\n\t"
492 "testb %%al,%%al\n\t"
493 "jne 1b\n\t"
494 "movl $1,%1\n"
495 "2:\n\t"
496 "movl %1,%0"
68b50604
UD
497 : "=a" (__res), "=&S" (__d0)
498 : "0" (__c), "1" (__s)
499 : "cc");
92f1da4d
UD
500 return __res - 1;
501}
502
503
504/* Return the length of the initial segment of S which
505 consists entirely of characters not in REJECT. */
74015205 506#define _HAVE_STRING_ARCH_strcspn 1
92f1da4d
UD
507#ifdef __PIC__
508__STRING_INLINE size_t
509strcspn (__const char *__s, __const char *__reject)
510{
a44d2393 511 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
512 register char *__res;
513 __asm__ __volatile__
514 ("pushl %%ebx\n\t"
515 "cld\n\t"
516 "movl %4,%%edi\n\t"
517 "repne; scasb\n\t"
518 "notl %%ecx\n\t"
519 "decl %%ecx\n\t"
520 "movl %%ecx,%%ebx\n"
521 "1:\n\t"
522 "lodsb\n\t"
523 "testb %%al,%%al\n\t"
524 "je 2f\n\t"
525 "movl %4,%%edi\n\t"
526 "movl %%ebx,%%ecx\n\t"
527 "repne; scasb\n\t"
528 "jne 1b\n"
529 "2:\n\t"
530 "popl %%ebx"
68b50604
UD
531 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
532 : "r" (__reject), "1" (0), "2" (0xffffffff), "3" (__s),
533 : "cc");
92f1da4d
UD
534 return (__res - 1) - __s;
535}
536#else
537__STRING_INLINE size_t
538strcspn (__const char *__s, __const char *__reject)
539{
a44d2393 540 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
541 register char *__res;
542 __asm__ __volatile__
543 ("cld\n\t"
68b50604 544 "movl %5,%%edi\n\t"
92f1da4d
UD
545 "repne; scasb\n\t"
546 "notl %%ecx\n\t"
547 "decl %%ecx\n\t"
548 "movl %%ecx,%%edx\n"
549 "1:\n\t"
550 "lodsb\n\t"
551 "testb %%al,%%al\n\t"
552 "je 2f\n\t"
68b50604 553 "movl %5,%%edi\n\t"
92f1da4d
UD
554 "movl %%edx,%%ecx\n\t"
555 "repne; scasb\n\t"
556 "jne 1b\n"
557 "2:"
68b50604
UD
558 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
559 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
560 : "cc");
92f1da4d
UD
561 return (__res - 1) - __s;
562}
563#endif
564
565
566/* Return the length of the initial segment of S which
567 consists entirely of characters in ACCEPT. */
74015205 568#define _HAVE_STRING_ARCH_strspn 1
92f1da4d
UD
569#ifdef __PIC__
570__STRING_INLINE size_t
571strspn (__const char *__s, __const char *__accept)
572{
a44d2393 573 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
574 register char *__res;
575 __asm__ __volatile__
576 ("pushl %%ebx\n\t"
577 "cld\n\t"
578 "movl %4,%%edi\n\t"
579 "repne; scasb\n\t"
580 "notl %%ecx\n\t"
581 "decl %%ecx\n\t"
582 "movl %%ecx,%%ebx\n"
583 "1:\n\t"
584 "lodsb\n\t"
585 "testb %%al,%%al\n\t"
586 "je 2f\n\t"
587 "movl %4,%%edi\n\t"
588 "movl %%ebx,%%ecx\n\t"
589 "repne; scasb\n\t"
590 "je 1b\n"
591 "2:\n\t"
592 "popl %%ebx"
68b50604
UD
593 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
594 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
595 : "cc");
92f1da4d
UD
596 return (__res - 1) - __s;
597}
598#else
599__STRING_INLINE size_t
600strspn (__const char *__s, __const char *__accept)
601{
a44d2393 602 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
603 register char *__res;
604 __asm__ __volatile__
605 ("cld\n\t"
68b50604 606 "movl %5,%%edi\n\t"
92f1da4d
UD
607 "repne; scasb\n\t"
608 "notl %%ecx\n\t"
609 "decl %%ecx\n\t"
610 "movl %%ecx,%%edx\n"
611 "1:\n\t"
612 "lodsb\n\t"
613 "testb %%al,%%al\n\t"
614 "je 2f\n\t"
68b50604 615 "movl %5,%%edi\n\t"
92f1da4d
UD
616 "movl %%edx,%%ecx\n\t"
617 "repne; scasb\n\t"
618 "je 1b\n"
619 "2:"
68b50604
UD
620 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
621 : "g" (__accept), "0" (__s), "a" (0), "c" (0xffffffff)
622 : "cc");
92f1da4d
UD
623 return (__res - 1) - __s;
624}
625#endif
626
627
628/* Find the first occurrence in S of any character in ACCEPT. */
74015205 629#define _HAVE_STRING_ARCH_strpbrk 1
92f1da4d
UD
630#ifdef __PIC__
631__STRING_INLINE char *
632strpbrk (__const char *__s, __const char *__accept)
633{
68b50604 634 unsigned long int __d0, __d1, __d2;
92f1da4d
UD
635 register char *__res;
636 __asm__ __volatile__
637 ("pushl %%ebx\n\t"
638 "cld\n\t"
639 "movl %4,%%edi\n\t"
640 "repne; scasb\n\t"
641 "notl %%ecx\n\t"
642 "decl %%ecx\n\t"
643 "movl %%ecx,%%ebx\n"
644 "1:\n\t"
645 "lodsb\n\t"
646 "testb %%al,%%al\n\t"
647 "je 2f\n\t"
648 "movl %4,%%edi\n\t"
649 "movl %%ebx,%%ecx\n\t"
650 "repne; scasb\n\t"
651 "jne 1b\n\t"
652 "decl %0\n\t"
653 "jmp 3f\n"
654 "2:\n\t"
655 "xorl %0,%0\n"
656 "3:\n\t"
657 "popl %%ebx"
68b50604
UD
658 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
659 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
660 : "cc");
92f1da4d
UD
661 return __res;
662}
663#else
664__STRING_INLINE char *
665strpbrk (__const char *__s, __const char *__accept)
666{
a44d2393 667 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
668 register char *__res;
669 __asm__ __volatile__
670 ("cld\n\t"
671 "movl %4,%%edi\n\t"
672 "repne; scasb\n\t"
673 "notl %%ecx\n\t"
674 "decl %%ecx\n\t"
675 "movl %%ecx,%%edx\n"
676 "1:\n\t"
677 "lodsb\n\t"
678 "testb %%al,%%al\n\t"
679 "je 2f\n\t"
680 "movl %4,%%edi\n\t"
681 "movl %%edx,%%ecx\n\t"
682 "repne; scasb\n\t"
683 "jne 1b\n\t"
684 "decl %0\n\t"
685 "jmp 3f\n"
686 "2:\n\t"
687 "xorl %0,%0\n"
688 "3:"
68b50604
UD
689 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
690 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
691 : "cc");
92f1da4d
UD
692 return __res;
693}
694#endif
695
696
697/* Find the first occurrence of NEEDLE in HAYSTACK. */
74015205 698#define _HAVE_STRING_ARCH_strstr 1
92f1da4d
UD
699#ifdef __PIC__
700__STRING_INLINE char *
701strstr (__const char *__haystack, __const char *__needle)
702{
a44d2393 703 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
704 register char *__res;
705 __asm__ __volatile__
706 ("pushl %%ebx\n\t"
707 "cld\n\t" \
708 "movl %4,%%edi\n\t"
709 "repne; scasb\n\t"
710 "notl %%ecx\n\t"
711 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
712 "movl %%ecx,%%ebx\n"
713 "1:\n\t"
714 "movl %4,%%edi\n\t"
715 "movl %%esi,%%eax\n\t"
716 "movl %%ebx,%%ecx\n\t"
717 "repe; cmpsb\n\t"
718 "je 2f\n\t" /* also works for empty string, see above */
719 "xchgl %%eax,%%esi\n\t"
720 "incl %%esi\n\t"
721 "cmpb $0,-1(%%eax)\n\t"
722 "jne 1b\n\t"
723 "xorl %%eax,%%eax\n\t"
724 "2:\n\t"
725 "popl %%ebx"
68b50604
UD
726 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
727 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
728 : "cc");
92f1da4d
UD
729 return __res;
730}
731#else
732__STRING_INLINE char *
733strstr (__const char *__haystack, __const char *__needle)
734{
a44d2393 735 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
736 register char *__res;
737 __asm__ __volatile__
738 ("cld\n\t" \
68b50604 739 "movl %5,%%edi\n\t"
92f1da4d
UD
740 "repne; scasb\n\t"
741 "notl %%ecx\n\t"
742 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
743 "movl %%ecx,%%edx\n"
744 "1:\n\t"
68b50604 745 "movl %5,%%edi\n\t"
92f1da4d
UD
746 "movl %%esi,%%eax\n\t"
747 "movl %%edx,%%ecx\n\t"
748 "repe; cmpsb\n\t"
749 "je 2f\n\t" /* also works for empty string, see above */
750 "xchgl %%eax,%%esi\n\t"
751 "incl %%esi\n\t"
752 "cmpb $0,-1(%%eax)\n\t"
753 "jne 1b\n\t"
754 "xorl %%eax,%%eax\n\t"
755 "2:"
68b50604
UD
756 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
757 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
758 : "cc");
92f1da4d
UD
759 return __res;
760}
761#endif
762
763
764#undef __STRING_INLINE
765
61eb22d3 766#endif /* use string inlines && GNU CC */