]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/i386/i486/bits/string.h
Update.
[thirdparty/glibc.git] / sysdeps / i386 / i486 / bits / string.h
1 /* Optimized, inlined string functions. i486 version.
2 Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
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
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
22 #endif
23
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 && !__BOUNDED_POINTERS__
32
33 #ifndef __STRING_INLINE
34 # ifdef __cplusplus
35 # define __STRING_INLINE inline
36 # else
37 # define __STRING_INLINE extern __inline
38 # endif
39 #endif
40
41 /* The macros are used in some of the optimized implementations below. */
42 #define __STRING_SMALL_GET16(src, idx) \
43 (((src)[idx + 1] << 8) | (src)[idx])
44 #define __STRING_SMALL_GET32(src, idx) \
45 ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8 \
46 | (src)[idx + 1]) << 8 | (src)[idx])
47
48
49 /* Copy N bytes of SRC to DEST. */
50 #define _HAVE_STRING_ARCH_memcpy 1
51 #define memcpy(dest, src, n) \
52 (__extension__ (__builtin_constant_p (n) \
53 ? __memcpy_c (dest, src, n) \
54 : __memcpy_g (dest, src, n)))
55 #define __memcpy_c(dest, src, n) \
56 ((n) == 0 \
57 ? (dest) \
58 : (((n) % 4 == 0) \
59 ? __memcpy_by4 (dest, src, n) \
60 : (((n) % 2 == 0) \
61 ? __memcpy_by2 (dest, src, n) \
62 : __memcpy_g (dest, src, n))))
63
64 __STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src,
65 size_t __n);
66
67 __STRING_INLINE void *
68 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
69 {
70 register unsigned long int __d0, __d1;
71 register void *__tmp = __dest;
72 __asm__ __volatile__
73 ("1:\n\t"
74 "movl (%2),%0\n\t"
75 "leal 4(%2),%2\n\t"
76 "movl %0,(%1)\n\t"
77 "leal 4(%1),%1\n\t"
78 "decl %3\n\t"
79 "jnz 1b"
80 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
81 : "1" (__tmp), "2" (__src), "3" (__n / 4)
82 : "memory", "cc");
83 return __dest;
84 }
85
86 __STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
87 size_t __n);
88
89 __STRING_INLINE void *
90 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
91 {
92 register unsigned long int __d0, __d1;
93 register void *__tmp = __dest;
94 __asm__ __volatile__
95 ("shrl $1,%3\n\t"
96 "jz 2f\n" /* only a word */
97 "1:\n\t"
98 "movl (%2),%0\n\t"
99 "leal 4(%2),%2\n\t"
100 "movl %0,(%1)\n\t"
101 "leal 4(%1),%1\n\t"
102 "decl %3\n\t"
103 "jnz 1b\n"
104 "2:\n\t"
105 "movw (%2),%w0\n\t"
106 "movw %w0,(%1)"
107 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
108 : "1" (__tmp), "2" (__src), "3" (__n / 2)
109 : "memory", "cc");
110 return __dest;
111 }
112
113 __STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
114 size_t __n);
115
116 __STRING_INLINE void *
117 __memcpy_g (void *__dest, __const void *__src, size_t __n)
118 {
119 register unsigned long int __d0, __d1, __d2;
120 register void *__tmp = __dest;
121 __asm__ __volatile__
122 ("cld\n\t"
123 "shrl $1,%%ecx\n\t"
124 "jnc 1f\n\t"
125 "movsb\n"
126 "1:\n\t"
127 "shrl $1,%%ecx\n\t"
128 "jnc 2f\n\t"
129 "movsw\n"
130 "2:\n\t"
131 "rep; movsl"
132 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
133 : "0" (__n), "1" (__tmp), "2" (__src)
134 : "memory", "cc");
135 return __dest;
136 }
137
138 #define _HAVE_STRING_ARCH_memmove 1
139 #ifndef _FORCE_INLINES
140 /* Copy N bytes of SRC to DEST, guaranteeing
141 correct behavior for overlapping strings. */
142 __STRING_INLINE void *
143 memmove (void *__dest, __const void *__src, size_t __n)
144 {
145 register unsigned long int __d0, __d1, __d2;
146 register void *__tmp = __dest;
147 if (__dest < __src)
148 __asm__ __volatile__
149 ("cld\n\t"
150 "rep; movsb"
151 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
152 : "0" (__n), "1" (__src), "2" (__tmp)
153 : "memory");
154 else
155 __asm__ __volatile__
156 ("std\n\t"
157 "rep; movsb\n\t"
158 "cld"
159 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
160 : "0" (__n), "1" (__n - 1 + (__const char *) __src),
161 "2" (__n - 1 + (char *) __tmp)
162 : "memory");
163 return __dest;
164 }
165 #endif
166
167 /* Compare N bytes of S1 and S2. */
168 #define _HAVE_STRING_ARCH_memcmp 1
169 #ifndef _FORCE_INLINES
170 # ifndef __PIC__
171 /* gcc has problems to spill registers when using PIC. */
172 __STRING_INLINE int
173 memcmp (__const void *__s1, __const void *__s2, size_t __n)
174 {
175 register unsigned long int __d0, __d1, __d2;
176 register int __res;
177 __asm__ __volatile__
178 ("cld\n\t"
179 "testl %3,%3\n\t"
180 "repe; cmpsb\n\t"
181 "je 1f\n\t"
182 "sbbl %0,%0\n\t"
183 "orl $1,%0\n"
184 "1:"
185 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
186 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
187 : "cc");
188 return __res;
189 }
190 # endif
191 #endif
192
193 /* Set N bytes of S to C. */
194 #define _HAVE_STRING_ARCH_memset 1
195 #define memset(s, c, n) \
196 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
197 ? ((n) == 1 \
198 ? __memset_c1 (s, c) \
199 : __memset_gc (s, c, n)) \
200 : (__builtin_constant_p (c) \
201 ? (__builtin_constant_p (n) \
202 ? __memset_ccn (s, c, n) \
203 : memset (s, c, n)) \
204 : (__builtin_constant_p (n) \
205 ? __memset_gcn (s, c, n) \
206 : memset (s, c, n)))))
207
208 #define __memset_c1(s, c) ({ void *__s = (s); \
209 *((unsigned char *) __s) = (unsigned char) (c); \
210 __s; })
211
212 #define __memset_gc(s, c, n) \
213 ({ void *__s = (s); \
214 union { \
215 unsigned int __ui; \
216 unsigned short int __usi; \
217 unsigned char __uc; \
218 } *__u = __s; \
219 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
220 \
221 /* We apply a trick here. `gcc' would implement the following \
222 assignments using immediate operands. But this uses to much \
223 memory (7, instead of 4 bytes). So we force the value in a \
224 registers. */ \
225 if (n == 3 || n >= 5) \
226 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
227 \
228 /* This `switch' statement will be removed at compile-time. */ \
229 switch (n) \
230 { \
231 case 15: \
232 __u->__ui = __c; \
233 __u = __extension__ ((void *) __u + 4); \
234 case 11: \
235 __u->__ui = __c; \
236 __u = __extension__ ((void *) __u + 4); \
237 case 7: \
238 __u->__ui = __c; \
239 __u = __extension__ ((void *) __u + 4); \
240 case 3: \
241 __u->__usi = (unsigned short int) __c; \
242 __u = __extension__ ((void *) __u + 2); \
243 __u->__uc = (unsigned char) __c; \
244 break; \
245 \
246 case 14: \
247 __u->__ui = __c; \
248 __u = __extension__ ((void *) __u + 4); \
249 case 10: \
250 __u->__ui = __c; \
251 __u = __extension__ ((void *) __u + 4); \
252 case 6: \
253 __u->__ui = __c; \
254 __u = __extension__ ((void *) __u + 4); \
255 case 2: \
256 __u->__usi = (unsigned short int) __c; \
257 break; \
258 \
259 case 13: \
260 __u->__ui = __c; \
261 __u = __extension__ ((void *) __u + 4); \
262 case 9: \
263 __u->__ui = __c; \
264 __u = __extension__ ((void *) __u + 4); \
265 case 5: \
266 __u->__ui = __c; \
267 __u = __extension__ ((void *) __u + 4); \
268 case 1: \
269 __u->__uc = (unsigned char) __c; \
270 break; \
271 \
272 case 16: \
273 __u->__ui = __c; \
274 __u = __extension__ ((void *) __u + 4); \
275 case 12: \
276 __u->__ui = __c; \
277 __u = __extension__ ((void *) __u + 4); \
278 case 8: \
279 __u->__ui = __c; \
280 __u = __extension__ ((void *) __u + 4); \
281 case 4: \
282 __u->__ui = __c; \
283 case 0: \
284 break; \
285 } \
286 \
287 __s; })
288
289 #define __memset_ccn(s, c, n) \
290 (((n) % 4 == 0) \
291 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
292 n) \
293 : (((n) % 2 == 0) \
294 ? __memset_ccn_by2 (s, \
295 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
296 n) \
297 : memset (s, c, n)))
298
299 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
300 size_t __n);
301
302 __STRING_INLINE void *
303 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
304 {
305 register void *__tmp = __s;
306 register unsigned long int __d0;
307 #ifdef __i686__
308 __asm__ __volatile__
309 ("cld\n\t"
310 "rep; stosl"
311 : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0)
312 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
313 : "memory", "cc");
314 #else
315 __asm__ __volatile__
316 ("1:\n\t"
317 "movl %0,(%1)\n\t"
318 "addl $4,%1\n\t"
319 "decl %2\n\t"
320 "jnz 1b\n"
321 : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0)
322 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
323 : "memory", "cc");
324 #endif
325 return __s;
326 }
327
328 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
329 size_t __n);
330
331 __STRING_INLINE void *
332 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
333 {
334 register unsigned long int __d0, __d1;
335 register void *__tmp = __s;
336 #ifdef __i686__
337 __asm__ __volatile__
338 ("cld\n\t"
339 "rep; stosl\n"
340 "stosw"
341 : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1)
342 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
343 : "memory", "cc");
344 #else
345 __asm__ __volatile__
346 ("1:\tmovl %0,(%1)\n\t"
347 "leal 4(%1),%1\n\t"
348 "decl %2\n\t"
349 "jnz 1b\n"
350 "movw %w0,(%1)"
351 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
352 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
353 : "memory", "cc");
354 #endif
355 return __s;
356 }
357
358 #define __memset_gcn(s, c, n) \
359 (((n) % 4 == 0) \
360 ? __memset_gcn_by4 (s, c, n) \
361 : (((n) % 2 == 0) \
362 ? __memset_gcn_by2 (s, c, n) \
363 : memset (s, c, n)))
364
365 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
366
367 __STRING_INLINE void *
368 __memset_gcn_by4 (void *__s, int __c, size_t __n)
369 {
370 register void *__tmp = __s;
371 register unsigned long int __d0;
372 __asm__ __volatile__
373 ("movb %b0,%h0\n"
374 "pushw %w0\n\t"
375 "shll $16,%0\n\t"
376 "popw %w0\n"
377 "1:\n\t"
378 "movl %0,(%1)\n\t"
379 "addl $4,%1\n\t"
380 "decl %2\n\t"
381 "jnz 1b\n"
382 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
383 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
384 : "memory", "cc");
385 return __s;
386 }
387
388 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
389
390 __STRING_INLINE void *
391 __memset_gcn_by2 (void *__s, int __c, size_t __n)
392 {
393 register unsigned long int __d0, __d1;
394 register void *__tmp = __s;
395 __asm__ __volatile__
396 ("movb %b0,%h0\n\t"
397 "pushw %w0\n\t"
398 "shll $16,%0\n\t"
399 "popw %w0\n"
400 "1:\n\t"
401 "movl %0,(%1)\n\t"
402 "leal 4(%1),%1\n\t"
403 "decl %2\n\t"
404 "jnz 1b\n"
405 "movw %w0,(%1)"
406 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
407 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
408 : "memory", "cc");
409 return __s;
410 }
411
412
413 /* Search N bytes of S for C. */
414 #define _HAVE_STRING_ARCH_memchr 1
415 #ifndef _FORCE_INLINES
416 __STRING_INLINE void *
417 memchr (__const void *__s, int __c, size_t __n)
418 {
419 register unsigned long int __d0;
420 #ifdef __i686__
421 register unsigned long int __d1;
422 #endif
423 register unsigned char *__res;
424 if (__n == 0)
425 return NULL;
426 #ifdef __i686__
427 __asm__ __volatile__
428 ("cld\n\t"
429 "repne; scasb\n\t"
430 "cmovne %2,%0"
431 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
432 : "a" (__c), "0" (__s), "1" (__n), "2" (1)
433 : "cc");
434 #else
435 __asm__ __volatile__
436 ("cld\n\t"
437 "repne; scasb\n\t"
438 "je 1f\n\t"
439 "movl $1,%0\n"
440 "1:"
441 : "=D" (__res), "=&c" (__d0)
442 : "a" (__c), "0" (__s), "1" (__n)
443 : "cc");
444 #endif
445 return __res - 1;
446 }
447 #endif
448
449 #define _HAVE_STRING_ARCH_memrchr 1
450 #ifndef _FORCE_INLINES
451 __STRING_INLINE void *
452 __memrchr (__const void *__s, int __c, size_t __n)
453 {
454 register unsigned long int __d0;
455 # ifdef __i686__
456 register unsigned long int __d1;
457 # endif
458 register void *__res;
459 if (__n == 0)
460 return NULL;
461 # ifdef __i686__
462 __asm__ __volatile__
463 ("std\n\t"
464 "repne; scasb\n\t"
465 "cmovne %2,%0\n\t"
466 "cld"
467 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
468 : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1)
469 : "cc");
470 # else
471 __asm__ __volatile__
472 ("std\n\t"
473 "repne; scasb\n\t"
474 "je 1f\n\t"
475 "orl $-1,%0\n"
476 "1:\tcld"
477 : "=D" (__res), "=&c" (__d0)
478 : "a" (__c), "0" (__s + __n - 1), "1" (__n)
479 : "cc");
480 # endif
481 return __res + 1;
482 }
483 # ifdef __USE_GNU
484 # define memrchr(s, c, n) __memrchr (s, c, n)
485 # endif
486 #endif
487
488 /* Return pointer to C in S. */
489 #define _HAVE_STRING_ARCH_rawmemchr 1
490 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
491
492 #ifndef _FORCE_INLINES
493 __STRING_INLINE void *
494 __rawmemchr (const void *__s, int __c)
495 {
496 register unsigned long int __d0;
497 register unsigned char *__res;
498 __asm__ __volatile__
499 ("cld\n\t"
500 "repne; scasb\n\t"
501 : "=D" (__res), "=&c" (__d0)
502 : "a" (__c), "0" (__s), "1" (0xffffffff)
503 : "cc");
504 return __res - 1;
505 }
506 # ifdef __USE_GNU
507 __STRING_INLINE void *
508 rawmemchr (const void *__s, int __c)
509 {
510 return __rawmemchr (__s, __c);
511 }
512 # endif /* use GNU */
513 #endif
514
515
516 /* Return the length of S. */
517 #define _HAVE_STRING_ARCH_strlen 1
518 #define strlen(str) \
519 (__extension__ (__builtin_constant_p (str) \
520 ? __builtin_strlen (str) \
521 : __strlen_g (str)))
522 __STRING_INLINE size_t __strlen_g (__const char *__str);
523
524 __STRING_INLINE size_t
525 __strlen_g (__const char *__str)
526 {
527 register char __dummy;
528 register __const char *__tmp = __str;
529 __asm__ __volatile__
530 ("1:\n\t"
531 "movb (%0),%b1\n\t"
532 "leal 1(%0),%0\n\t"
533 "testb %b1,%b1\n\t"
534 "jne 1b"
535 : "=r" (__tmp), "=&q" (__dummy)
536 : "0" (__str)
537 : "memory", "cc" );
538 return __tmp - __str - 1;
539 }
540
541
542 /* Copy SRC to DEST. */
543 #define _HAVE_STRING_ARCH_strcpy 1
544 #define strcpy(dest, src) \
545 (__extension__ (__builtin_constant_p (src) \
546 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
547 ? __strcpy_small (dest, src, strlen (src) + 1) \
548 : (char *) memcpy ((char *) dest, \
549 (__const char *) src, \
550 strlen (src) + 1)) \
551 : __strcpy_g (dest, src)))
552
553 #define __strcpy_small(dest, src, srclen) \
554 (__extension__ ({ char *__dest = (dest); \
555 union { \
556 unsigned int __ui; \
557 unsigned short int __usi; \
558 unsigned char __uc; \
559 char __c; \
560 } *__u = (void *) __dest; \
561 switch (srclen) \
562 { \
563 case 1: \
564 __u->__uc = '\0'; \
565 break; \
566 case 2: \
567 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
568 break; \
569 case 3: \
570 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
571 __u = __extension__ ((void *) __u + 2); \
572 __u->__uc = '\0'; \
573 break; \
574 case 4: \
575 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
576 break; \
577 case 5: \
578 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
579 __u = __extension__ ((void *) __u + 4); \
580 __u->__uc = '\0'; \
581 break; \
582 case 6: \
583 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
584 __u = __extension__ ((void *) __u + 4); \
585 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
586 break; \
587 case 7: \
588 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
589 __u = __extension__ ((void *) __u + 4); \
590 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
591 __u = __extension__ ((void *) __u + 2); \
592 __u->__uc = '\0'; \
593 break; \
594 case 8: \
595 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
596 __u = __extension__ ((void *) __u + 4); \
597 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
598 break; \
599 } \
600 (char *) __dest; }))
601
602 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
603
604 __STRING_INLINE char *
605 __strcpy_g (char *__dest, __const char *__src)
606 {
607 register char *__tmp = __dest;
608 register char __dummy;
609 __asm__ __volatile__
610 (
611 "1:\n\t"
612 "movb (%0),%b2\n\t"
613 "leal 1(%0),%0\n\t"
614 "movb %b2,(%1)\n\t"
615 "leal 1(%1),%1\n\t"
616 "testb %b2,%b2\n\t"
617 "jne 1b"
618 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
619 : "0" (__src), "1" (__tmp)
620 : "memory", "cc");
621 return __dest;
622 }
623
624
625 #ifdef __USE_GNU
626 # define _HAVE_STRING_ARCH_stpcpy 1
627 /* Copy SRC to DEST. */
628 # define __stpcpy(dest, src) \
629 (__extension__ (__builtin_constant_p (src) \
630 ? (strlen (src) + 1 <= 8 \
631 ? __stpcpy_small (dest, src, strlen (src) + 1) \
632 : __stpcpy_c (dest, src, strlen (src) + 1)) \
633 : __stpcpy_g (dest, src)))
634 # define __stpcpy_c(dest, src, srclen) \
635 ((srclen) % 4 == 0 \
636 ? __mempcpy_by4 (dest, src, srclen) - 1 \
637 : ((srclen) % 2 == 0 \
638 ? __mempcpy_by2 (dest, src, srclen) - 1 \
639 : __mempcpy_byn (dest, src, srclen) - 1))
640
641 /* In glibc itself we use this symbol for namespace reasons. */
642 # define stpcpy(dest, src) __stpcpy (dest, src)
643
644 # define __stpcpy_small(dest, src, srclen) \
645 (__extension__ ({ union { \
646 unsigned int __ui; \
647 unsigned short int __usi; \
648 unsigned char __uc; \
649 char __c; \
650 } *__u = (void *) (dest); \
651 switch (srclen) \
652 { \
653 case 1: \
654 __u->__uc = '\0'; \
655 break; \
656 case 2: \
657 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
658 __u = __extension__ ((void *) __u + 1); \
659 break; \
660 case 3: \
661 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
662 __u = __extension__ ((void *) __u + 2); \
663 __u->__uc = '\0'; \
664 break; \
665 case 4: \
666 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
667 __u = __extension__ ((void *) __u + 3); \
668 break; \
669 case 5: \
670 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
671 __u = __extension__ ((void *) __u + 4); \
672 __u->__uc = '\0'; \
673 break; \
674 case 6: \
675 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
676 __u = __extension__ ((void *) __u + 4); \
677 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
678 __u = __extension__ ((void *) __u + 1); \
679 break; \
680 case 7: \
681 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
682 __u = __extension__ ((void *) __u + 4); \
683 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
684 __u = __extension__ ((void *) __u + 2); \
685 __u->__uc = '\0'; \
686 break; \
687 case 8: \
688 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
689 __u = __extension__ ((void *) __u + 4); \
690 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
691 __u = __extension__ ((void *) __u + 3); \
692 break; \
693 } \
694 (char *) __u; }))
695
696 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
697 size_t __srclen);
698
699 __STRING_INLINE char *
700 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
701 {
702 register char *__tmp = __dest;
703 register unsigned long int __d0, __d1;
704 __asm__ __volatile__
705 ("1:\n\t"
706 "movl (%2),%0\n\t"
707 "leal 4(%2),%2\n\t"
708 "movl %0,(%1)\n\t"
709 "leal 4(%1),%1\n\t"
710 "decl %3\n\t"
711 "jnz 1b"
712 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
713 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
714 : "memory", "cc");
715 return __tmp;
716 }
717
718 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
719 size_t __srclen);
720
721 __STRING_INLINE char *
722 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
723 {
724 register char *__tmp = __dest;
725 register unsigned long int __d0, __d1;
726 __asm__ __volatile__
727 ("shrl $1,%3\n\t"
728 "jz 2f\n" /* only a word */
729 "1:\n\t"
730 "movl (%2),%0\n\t"
731 "leal 4(%2),%2\n\t"
732 "movl %0,(%1)\n\t"
733 "leal 4(%1),%1\n\t"
734 "decl %3\n\t"
735 "jnz 1b\n"
736 "2:\n\t"
737 "movw (%2),%w0\n\t"
738 "movw %w0,(%1)"
739 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
740 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
741 : "memory", "cc");
742 return __tmp + 2;
743 }
744
745 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
746 size_t __srclen);
747
748 __STRING_INLINE char *
749 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
750 {
751 register unsigned long __d0, __d1;
752 register char *__tmp = __dest;
753 __asm__ __volatile__
754 ("cld\n\t"
755 "shrl $1,%%ecx\n\t"
756 "jnc 1f\n\t"
757 "movsb\n"
758 "1:\n\t"
759 "shrl $1,%%ecx\n\t"
760 "jnc 2f\n\t"
761 "movsw\n"
762 "2:\n\t"
763 "rep; movsl"
764 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
765 : "0" (__tmp), "1" (__srclen), "2" (__src)
766 : "memory", "cc");
767 return __tmp;
768 }
769
770 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
771
772 __STRING_INLINE char *
773 __stpcpy_g (char *__dest, __const char *__src)
774 {
775 register char *__tmp = __dest;
776 register char __dummy;
777 __asm__ __volatile__
778 (
779 "1:\n\t"
780 "movb (%0),%b2\n\t"
781 "leal 1(%0),%0\n\t"
782 "movb %b2,(%1)\n\t"
783 "leal 1(%1),%1\n\t"
784 "testb %b2,%b2\n\t"
785 "jne 1b"
786 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
787 : "0" (__src), "1" (__tmp)
788 : "memory", "cc");
789 return __tmp - 1;
790 }
791 #endif
792
793
794 /* Copy no more than N characters of SRC to DEST. */
795 #define _HAVE_STRING_ARCH_strncpy 1
796 #define strncpy(dest, src, n) \
797 (__extension__ (__builtin_constant_p (src) \
798 ? ((strlen (src) + 1 >= ((size_t) (n)) \
799 ? (char *) memcpy ((char *) dest, \
800 (__const char *) src, n) \
801 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
802 : __strncpy_gg (dest, src, n)))
803 #define __strncpy_cg(dest, src, srclen, n) \
804 (((srclen) % 4 == 0) \
805 ? __strncpy_by4 (dest, src, srclen, n) \
806 : (((srclen) % 2 == 0) \
807 ? __strncpy_by2 (dest, src, srclen, n) \
808 : __strncpy_byn (dest, src, srclen, n)))
809
810 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
811 size_t __srclen, size_t __n);
812
813 __STRING_INLINE char *
814 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
815 {
816 register char *__tmp = __dest;
817 register int __dummy1, __dummy2;
818 __asm__ __volatile__
819 ("1:\n\t"
820 "movl (%2),%0\n\t"
821 "leal 4(%2),%2\n\t"
822 "movl %0,(%1)\n\t"
823 "leal 4(%1),%1\n\t"
824 "decl %3\n\t"
825 "jnz 1b"
826 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
827 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
828 : "memory", "cc");
829 (void) memset (__tmp, '\0', __n - __srclen);
830 return __dest;
831 }
832
833 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
834 size_t __srclen, size_t __n);
835
836 __STRING_INLINE char *
837 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
838 {
839 register char *__tmp = __dest;
840 register int __dummy1, __dummy2;
841 __asm__ __volatile__
842 ("shrl $1,%3\n\t"
843 "jz 2f\n" /* only a word */
844 "1:\n\t"
845 "movl (%2),%0\n\t"
846 "leal 4(%2),%2\n\t"
847 "movl %0,(%1)\n\t"
848 "leal 4(%1),%1\n\t"
849 "decl %3\n\t"
850 "jnz 1b\n"
851 "2:\n\t"
852 "movw (%2),%w0\n\t"
853 "movw %w0,(%1)\n\t"
854 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
855 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
856 : "memory", "cc");
857 (void) memset (__tmp + 2, '\0', __n - __srclen);
858 return __dest;
859 }
860
861 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
862 size_t __srclen, size_t __n);
863
864 __STRING_INLINE char *
865 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
866 {
867 register unsigned long int __d0, __d1;
868 register char *__tmp = __dest;
869 __asm__ __volatile__
870 ("cld\n\t"
871 "shrl $1,%1\n\t"
872 "jnc 1f\n\t"
873 "movsb\n"
874 "1:\n\t"
875 "shrl $1,%1\n\t"
876 "jnc 2f\n\t"
877 "movsw\n"
878 "2:\n\t"
879 "rep; movsl"
880 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
881 : "1" (__srclen), "0" (__tmp),"2" (__src)
882 : "memory", "cc");
883 (void) memset (__tmp, '\0', __n - __srclen);
884 return __dest;
885 }
886
887 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
888 size_t __n);
889
890 __STRING_INLINE char *
891 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
892 {
893 register char *__tmp = __dest;
894 register char __dummy;
895 if (__n > 0)
896 __asm__ __volatile__
897 ("1:\n\t"
898 "movb (%0),%2\n\t"
899 "incl %0\n\t"
900 "movb %2,(%1)\n\t"
901 "incl %1\n\t"
902 "decl %3\n\t"
903 "je 3f\n\t"
904 "testb %2,%2\n\t"
905 "jne 1b\n\t"
906 "2:\n\t"
907 "movb %2,(%1)\n\t"
908 "incl %1\n\t"
909 "decl %3\n\t"
910 "jne 2b\n\t"
911 "3:"
912 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
913 : "0" (__src), "1" (__tmp), "3" (__n)
914 : "memory", "cc");
915
916 return __dest;
917 }
918
919
920 /* Append SRC onto DEST. */
921 #define _HAVE_STRING_ARCH_strcat 1
922 #define strcat(dest, src) \
923 (__extension__ (__builtin_constant_p (src) \
924 ? __strcat_c (dest, src, strlen (src) + 1) \
925 : __strcat_g (dest, src)))
926
927 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
928 size_t __srclen);
929
930 __STRING_INLINE char *
931 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
932 {
933 #ifdef __i686__
934 register unsigned long int __d0;
935 register char *__tmp;
936 __asm__ __volatile__
937 ("repne; scasb"
938 : "=D" (__tmp), "=&c" (__d0)
939 : "0" (__dest), "1" (0xffffffff), "a" (0)
940 : "cc");
941 --__tmp;
942 #else
943 register char *__tmp = __dest - 1;
944 __asm__ __volatile__
945 ("1:\n\t"
946 "incl %0\n\t"
947 "cmpb $0,(%0)\n\t"
948 "jne 1b\n"
949 : "=r" (__tmp)
950 : "0" (__tmp)
951 : "cc");
952 #endif
953 (void) memcpy (__tmp, __src, __srclen);
954 return __dest;
955 }
956
957 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
958
959 __STRING_INLINE char *
960 __strcat_g (char *__dest, __const char *__src)
961 {
962 register char *__tmp = __dest - 1;
963 register char __dummy;
964 __asm__ __volatile__
965 ("1:\n\t"
966 "incl %1\n\t"
967 "cmpb $0,(%1)\n\t"
968 "jne 1b\n"
969 "2:\n\t"
970 "movb (%2),%b0\n\t"
971 "incl %2\n\t"
972 "movb %b0,(%1)\n\t"
973 "incl %1\n\t"
974 "testb %b0,%b0\n\t"
975 "jne 2b\n"
976 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
977 : "1" (__tmp), "2" (__src)
978 : "memory", "cc");
979 return __dest;
980 }
981
982
983 /* Append no more than N characters from SRC onto DEST. */
984 #define _HAVE_STRING_ARCH_strncat 1
985 #define strncat(dest, src, n) \
986 (__extension__ ({ char *__dest = (dest); \
987 __builtin_constant_p (src) && __builtin_constant_p (n) \
988 ? (strlen (src) < ((size_t) (n)) \
989 ? strcat (__dest, src) \
990 : (memcpy (strchr (__dest, '\0'), \
991 (__const char *) src, n), __dest)) \
992 : __strncat_g (__dest, src, n); }))
993
994 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
995 size_t __n);
996
997 __STRING_INLINE char *
998 __strncat_g (char *__dest, __const char __src[], size_t __n)
999 {
1000 register char *__tmp = __dest;
1001 register char __dummy;
1002 #ifdef __i686__
1003 __asm__ __volatile__
1004 ("repne; scasb\n"
1005 "decl %1\n\t"
1006 "1:\n\t"
1007 "decl %3\n\t"
1008 "js 2f\n\t"
1009 "movb (%2),%b0\n\t"
1010 "movsb\n\t"
1011 "testb %b0,%b0\n\t"
1012 "jne 1b\n\t"
1013 "decl %1\n"
1014 "2:\n\t"
1015 "movb $0,(%1)"
1016 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
1017 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
1018 : "memory", "cc");
1019 #else
1020 --__tmp;
1021 __asm__ __volatile__
1022 ("1:\n\t"
1023 "cmpb $0,1(%1)\n\t"
1024 "leal 1(%1),%1\n\t"
1025 "jne 1b\n"
1026 "2:\n\t"
1027 "decl %3\n\t"
1028 "js 3f\n\t"
1029 "movb (%2),%b0\n\t"
1030 "leal 1(%2),%2\n\t"
1031 "movb %b0,(%1)\n\t"
1032 "leal 1(%1),%1\n\t"
1033 "testb %b0,%b0\n\t"
1034 "jne 2b\n\t"
1035 "decl %1\n"
1036 "3:\n\t"
1037 "movb $0,(%1)"
1038 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1039 : "1" (__tmp), "2" (__src), "3" (__n)
1040 : "memory", "cc");
1041 #endif
1042 return __dest;
1043 }
1044
1045
1046 /* Compare S1 and S2. */
1047 #define _HAVE_STRING_ARCH_strcmp 1
1048 #define strcmp(s1, s2) \
1049 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1050 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1051 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1052 ? memcmp ((__const char *) s1, (__const char *) s2, \
1053 (strlen (s1) < strlen (s2) \
1054 ? strlen (s1) : strlen (s2)) + 1) \
1055 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1056 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1057 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1058 ? __strcmp_cc (s1, s2, strlen (s1)) \
1059 : __strcmp_cg (s1, s2, strlen (s1))) \
1060 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1061 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1062 ? (__builtin_constant_p (s1) \
1063 ? __strcmp_cc (s1, s2, strlen (s2)) \
1064 : __strcmp_gc (s1, s2, strlen (s2))) \
1065 : __strcmp_gg (s1, s2)))))
1066
1067 #define __strcmp_cc(s1, s2, l) \
1068 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
1069 - (unsigned char) (s2)[0]); \
1070 if (l > 0 && __result == 0) \
1071 { \
1072 __result = ((unsigned char) (s1)[1] \
1073 - (unsigned char) (s2)[1]); \
1074 if (l > 1 && __result == 0) \
1075 { \
1076 __result = ((unsigned char) (s1)[2] \
1077 - (unsigned char) (s2)[2]); \
1078 if (l > 2 && __result == 0) \
1079 __result = ((unsigned char) (s1)[3] \
1080 - (unsigned char) (s2)[3]); \
1081 } \
1082 } \
1083 __result; }))
1084
1085 #define __strcmp_cg(s1, s2, l1) \
1086 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
1087 register int __result = (unsigned char) (s1)[0] - __s2[0];\
1088 if (l1 > 0 && __result == 0) \
1089 { \
1090 __result = (unsigned char) (s1)[1] - __s2[1]; \
1091 if (l1 > 1 && __result == 0) \
1092 { \
1093 __result = (unsigned char) (s1)[2] - __s2[2]; \
1094 if (l1 > 2 && __result == 0) \
1095 __result = (unsigned char) (s1)[3] - __s2[3]; \
1096 } \
1097 } \
1098 __result; }))
1099
1100 #define __strcmp_gc(s1, s2, l2) \
1101 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
1102 register int __result = __s1[0] - (unsigned char) (s2)[0];\
1103 if (l2 > 0 && __result == 0) \
1104 { \
1105 __result = __s1[1] - (unsigned char) (s2)[1]; \
1106 if (l2 > 1 && __result == 0) \
1107 { \
1108 __result = __s1[2] - (unsigned char) (s2)[2]; \
1109 if (l2 > 2 && __result == 0) \
1110 __result = __s1[3] - (unsigned char) (s2)[3]; \
1111 } \
1112 } \
1113 __result; }))
1114
1115 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1116
1117 __STRING_INLINE int
1118 __strcmp_gg (__const char *__s1, __const char *__s2)
1119 {
1120 register int __res;
1121 __asm__ __volatile__
1122 ("1:\n\t"
1123 "movb (%1),%b0\n\t"
1124 "leal 1(%1),%1\n\t"
1125 "cmpb %b0,(%2)\n\t"
1126 "jne 2f\n\t"
1127 "leal 1(%2),%2\n\t"
1128 "testb %b0,%b0\n\t"
1129 "jne 1b\n\t"
1130 "xorl %0,%0\n\t"
1131 "jmp 3f\n"
1132 "2:\n\t"
1133 "movl $1,%0\n\t"
1134 "jb 3f\n\t"
1135 "negl %0\n"
1136 "3:"
1137 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1138 : "1" (__s1), "2" (__s2)
1139 : "cc");
1140 return __res;
1141 }
1142
1143
1144 /* Compare N characters of S1 and S2. */
1145 #define _HAVE_STRING_ARCH_strncmp 1
1146 #define strncmp(s1, s2, n) \
1147 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1148 ? strcmp (s1, s2) \
1149 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1150 ? strcmp (s1, s2) \
1151 : __strncmp_g (s1, s2, n))))
1152
1153 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1154 size_t __n);
1155
1156 __STRING_INLINE int
1157 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1158 {
1159 register int __res;
1160 __asm__ __volatile__
1161 ("1:\n\t"
1162 "decl %3\n\t"
1163 "js 2f\n\t"
1164 "movb (%1),%b0\n\t"
1165 "incl %1\n\t"
1166 "cmpb %b0,(%2)\n\t"
1167 "jne 3f\n\t"
1168 "incl %2\n\t"
1169 "testb %b0,%b0\n\t"
1170 "jne 1b\n"
1171 "2:\n\t"
1172 "xorl %0,%0\n\t"
1173 "jmp 4f\n"
1174 "3:\n\t"
1175 "movl $1,%0\n\t"
1176 "jb 4f\n\t"
1177 "negl %0\n"
1178 "4:"
1179 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1180 : "1" (__s1), "2" (__s2), "3" (__n)
1181 : "cc");
1182 return __res;
1183 }
1184
1185
1186 /* Find the first occurrence of C in S. */
1187 #define _HAVE_STRING_ARCH_strchr 1
1188 #define strchr(s, c) \
1189 (__extension__ (__builtin_constant_p (c) \
1190 ? ((c) == '\0' \
1191 ? (char *) __rawmemchr (s, c) \
1192 : __strchr_c (s, ((c) & 0xff) << 8)) \
1193 : __strchr_g (s, c)))
1194
1195 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1196
1197 __STRING_INLINE char *
1198 __strchr_c (__const char *__s, int __c)
1199 {
1200 register unsigned long int __d0;
1201 register char *__res;
1202 __asm__ __volatile__
1203 ("1:\n\t"
1204 "movb (%0),%%al\n\t"
1205 "cmpb %%ah,%%al\n\t"
1206 "je 2f\n\t"
1207 "leal 1(%0),%0\n\t"
1208 "testb %%al,%%al\n\t"
1209 "jne 1b\n\t"
1210 "xorl %0,%0\n"
1211 "2:"
1212 : "=r" (__res), "=&a" (__d0)
1213 : "0" (__s), "1" (__c)
1214 : "cc");
1215 return __res;
1216 }
1217
1218 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1219
1220 __STRING_INLINE char *
1221 __strchr_g (__const char *__s, int __c)
1222 {
1223 register unsigned long int __d0;
1224 register char *__res;
1225 __asm__ __volatile__
1226 ("movb %%al,%%ah\n"
1227 "1:\n\t"
1228 "movb (%0),%%al\n\t"
1229 "cmpb %%ah,%%al\n\t"
1230 "je 2f\n\t"
1231 "leal 1(%0),%0\n\t"
1232 "testb %%al,%%al\n\t"
1233 "jne 1b\n\t"
1234 "xorl %0,%0\n"
1235 "2:"
1236 : "=r" (__res), "=&a" (__d0)
1237 : "0" (__s), "1" (__c)
1238 : "cc");
1239 return __res;
1240 }
1241
1242
1243 /* Find the first occurrence of C in S or the final NUL byte. */
1244 #define _HAVE_STRING_ARCH_strchrnul 1
1245 #define __strchrnul(s, c) \
1246 (__extension__ (__builtin_constant_p (c) \
1247 ? ((c) == '\0' \
1248 ? (char *) __rawmemchr (s, c) \
1249 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
1250 : __strchrnul_g (s, c)))
1251
1252 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1253
1254 __STRING_INLINE char *
1255 __strchrnul_c (__const char *__s, int __c)
1256 {
1257 register unsigned long int __d0;
1258 register char *__res;
1259 __asm__ __volatile__
1260 ("1:\n\t"
1261 "movb (%0),%%al\n\t"
1262 "cmpb %%ah,%%al\n\t"
1263 "je 2f\n\t"
1264 "leal 1(%0),%0\n\t"
1265 "testb %%al,%%al\n\t"
1266 "jne 1b\n\t"
1267 "decl %0\n"
1268 "2:"
1269 : "=r" (__res), "=&a" (__d0)
1270 : "0" (__s), "1" (__c)
1271 : "cc");
1272 return __res;
1273 }
1274
1275 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1276
1277 __STRING_INLINE char *
1278 __strchrnul_g (__const char *__s, int __c)
1279 {
1280 register unsigned long int __d0;
1281 register char *__res;
1282 __asm__ __volatile__
1283 ("movb %%al,%%ah\n"
1284 "1:\n\t"
1285 "movb (%0),%%al\n\t"
1286 "cmpb %%ah,%%al\n\t"
1287 "je 2f\n\t"
1288 "leal 1(%0),%0\n\t"
1289 "testb %%al,%%al\n\t"
1290 "jne 1b\n\t"
1291 "decl %0\n"
1292 "2:"
1293 : "=r" (__res), "=&a" (__d0)
1294 : "0" (__s), "1" (__c)
1295 : "cc");
1296 return __res;
1297 }
1298 #ifdef __USE_GNU
1299 # define strchrnul(s, c) __strchrnul (s, c)
1300 #endif
1301
1302
1303 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1304 /* Find the first occurrence of C in S. This is the BSD name. */
1305 # define _HAVE_STRING_ARCH_index 1
1306 # define index(s, c) \
1307 (__extension__ (__builtin_constant_p (c) \
1308 ? __strchr_c (s, ((c) & 0xff) << 8) \
1309 : __strchr_g (s, c)))
1310 #endif
1311
1312
1313 /* Find the last occurrence of C in S. */
1314 #define _HAVE_STRING_ARCH_strrchr 1
1315 #define strrchr(s, c) \
1316 (__extension__ (__builtin_constant_p (c) \
1317 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1318 : __strrchr_g (s, c)))
1319
1320 #ifdef __i686__
1321 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1322
1323 __STRING_INLINE char *
1324 __strrchr_c (__const char *__s, int __c)
1325 {
1326 register unsigned long int __d0, __d1;
1327 register char *__res;
1328 __asm__ __volatile__
1329 ("cld\n"
1330 "1:\n\t"
1331 "lodsb\n\t"
1332 "cmpb %h2,%b2\n\t"
1333 "cmove %1,%0\n\t"
1334 "testb %b2,%b2\n\t"
1335 "jne 1b"
1336 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1337 : "0" (1), "1" (__s), "2" (__c)
1338 : "cc");
1339 return __res - 1;
1340 }
1341
1342 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1343
1344 __STRING_INLINE char *
1345 __strrchr_g (__const char *__s, int __c)
1346 {
1347 register unsigned long int __d0, __d1;
1348 register char *__res;
1349 __asm__ __volatile__
1350 ("movb %b2,%h2\n"
1351 "cld\n\t"
1352 "1:\n\t"
1353 "lodsb\n\t"
1354 "cmpb %h2,%b2\n\t"
1355 "cmove %1,%0\n\t"
1356 "testb %b2,%b2\n\t"
1357 "jne 1b"
1358 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1359 : "0" (1), "1" (__s), "2" (__c)
1360 : "cc");
1361 return __res - 1;
1362 }
1363 #else
1364 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1365
1366 __STRING_INLINE char *
1367 __strrchr_c (__const char *__s, int __c)
1368 {
1369 register unsigned long int __d0, __d1;
1370 register char *__res;
1371 __asm__ __volatile__
1372 ("cld\n"
1373 "1:\n\t"
1374 "lodsb\n\t"
1375 "cmpb %%ah,%%al\n\t"
1376 "jne 2f\n\t"
1377 "leal -1(%%esi),%0\n"
1378 "2:\n\t"
1379 "testb %%al,%%al\n\t"
1380 "jne 1b"
1381 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1382 : "0" (0), "1" (__s), "2" (__c)
1383 : "cc");
1384 return __res;
1385 }
1386
1387 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1388
1389 __STRING_INLINE char *
1390 __strrchr_g (__const char *__s, int __c)
1391 {
1392 register unsigned long int __d0, __d1;
1393 register char *__res;
1394 __asm__ __volatile__
1395 ("movb %%al,%%ah\n"
1396 "cld\n\t"
1397 "1:\n\t"
1398 "lodsb\n\t"
1399 "cmpb %%ah,%%al\n\t"
1400 "jne 2f\n\t"
1401 "leal -1(%%esi),%0\n"
1402 "2:\n\t"
1403 "testb %%al,%%al\n\t"
1404 "jne 1b"
1405 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1406 : "0" (0), "1" (__s), "2" (__c)
1407 : "cc");
1408 return __res;
1409 }
1410 #endif
1411
1412
1413 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1414 /* Find the last occurrence of C in S. This is the BSD name. */
1415 # define _HAVE_STRING_ARCH_rindex 1
1416 # define rindex(s, c) \
1417 (__extension__ (__builtin_constant_p (c) \
1418 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1419 : __strrchr_g (s, c)))
1420 #endif
1421
1422
1423 /* Return the length of the initial segment of S which
1424 consists entirely of characters not in REJECT. */
1425 #define _HAVE_STRING_ARCH_strcspn 1
1426 #define strcspn(s, reject) \
1427 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1428 ? ((reject)[0] == '\0' \
1429 ? strlen (s) \
1430 : ((reject)[1] == '\0' \
1431 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1432 : __strcspn_cg (s, reject, strlen (reject)))) \
1433 : __strcspn_g (s, reject)))
1434
1435 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1436
1437 __STRING_INLINE size_t
1438 __strcspn_c1 (__const char *__s, int __reject)
1439 {
1440 register unsigned long int __d0;
1441 register char *__res;
1442 __asm__ __volatile__
1443 ("1:\n\t"
1444 "movb (%0),%%al\n\t"
1445 "leal 1(%0),%0\n\t"
1446 "cmpb %%ah,%%al\n\t"
1447 "je 2f\n\t"
1448 "testb %%al,%%al\n\t"
1449 "jne 1b\n"
1450 "2:"
1451 : "=r" (__res), "=&a" (__d0)
1452 : "0" (__s), "1" (__reject)
1453 : "cc");
1454 return (__res - 1) - __s;
1455 }
1456
1457 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1458 size_t __reject_len);
1459
1460 __STRING_INLINE size_t
1461 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1462 {
1463 register unsigned long int __d0, __d1, __d2;
1464 register __const char *__res;
1465 __asm__ __volatile__
1466 ("cld\n"
1467 "1:\n\t"
1468 "lodsb\n\t"
1469 "testb %%al,%%al\n\t"
1470 "je 2f\n\t"
1471 "movl %5,%%edi\n\t"
1472 "movl %6,%%ecx\n\t"
1473 "repne; scasb\n\t"
1474 "jne 1b\n"
1475 "2:"
1476 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1477 : "0" (__s), "d" (__reject), "g" (__reject_len)
1478 : "cc");
1479 return (__res - 1) - __s;
1480 }
1481
1482 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1483 #ifdef __PIC__
1484
1485 __STRING_INLINE size_t
1486 __strcspn_g (__const char *__s, __const char *__reject)
1487 {
1488 register unsigned long int __d0, __d1, __d2;
1489 register __const char *__res;
1490 __asm__ __volatile__
1491 ("pushl %%ebx\n\t"
1492 "movl %4,%%edi\n\t"
1493 "cld\n\t"
1494 "repne; scasb\n\t"
1495 "notl %%ecx\n\t"
1496 "leal -1(%%ecx),%%ebx\n"
1497 "1:\n\t"
1498 "lodsb\n\t"
1499 "testb %%al,%%al\n\t"
1500 "je 2f\n\t"
1501 "movl %4,%%edi\n\t"
1502 "movl %%ebx,%%ecx\n\t"
1503 "repne; scasb\n\t"
1504 "jne 1b\n"
1505 "2:\n\t"
1506 "popl %%ebx"
1507 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1508 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1509 : "cc");
1510 return (__res - 1) - __s;
1511 }
1512 #else
1513 __STRING_INLINE size_t
1514 __strcspn_g (__const char *__s, __const char *__reject)
1515 {
1516 register unsigned long int __d0, __d1, __d2, __d3;
1517 register __const char *__res;
1518 __asm__ __volatile__
1519 ("cld\n\t"
1520 "repne; scasb\n\t"
1521 "notl %%ecx\n\t"
1522 "leal -1(%%ecx),%%edx\n"
1523 "1:\n\t"
1524 "lodsb\n\t"
1525 "testb %%al,%%al\n\t"
1526 "je 2f\n\t"
1527 "movl %%ebx,%%edi\n\t"
1528 "movl %%edx,%%ecx\n\t"
1529 "repne; scasb\n\t"
1530 "jne 1b\n"
1531 "2:"
1532 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1533 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1534 : "cc");
1535 return (__res - 1) - __s;
1536 }
1537 #endif
1538
1539
1540 /* Return the length of the initial segment of S which
1541 consists entirely of characters in ACCEPT. */
1542 #define _HAVE_STRING_ARCH_strspn 1
1543 #define strspn(s, accept) \
1544 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1545 ? ((accept)[0] == '\0' \
1546 ? 0 \
1547 : ((accept)[1] == '\0' \
1548 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1549 : __strspn_cg (s, accept, strlen (accept)))) \
1550 : __strspn_g (s, accept)))
1551
1552 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1553
1554 __STRING_INLINE size_t
1555 __strspn_c1 (__const char *__s, int __accept)
1556 {
1557 register unsigned long int __d0;
1558 register char *__res;
1559 /* Please note that __accept never can be '\0'. */
1560 __asm__ __volatile__
1561 ("1:\n\t"
1562 "movb (%0),%b1\n\t"
1563 "leal 1(%0),%0\n\t"
1564 "cmpb %h1,%b1\n\t"
1565 "je 1b"
1566 : "=r" (__res), "=&q" (__d0)
1567 : "0" (__s), "1" (__accept)
1568 : "cc");
1569 return (__res - 1) - __s;
1570 }
1571
1572 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1573 size_t __accept_len);
1574
1575 __STRING_INLINE size_t
1576 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1577 {
1578 register unsigned long int __d0, __d1, __d2;
1579 register __const char *__res;
1580 __asm__ __volatile__
1581 ("cld\n"
1582 "1:\n\t"
1583 "lodsb\n\t"
1584 "testb %%al,%%al\n\t"
1585 "je 2f\n\t"
1586 "movl %1,%%edi\n\t"
1587 "movl %6,%%ecx\n\t"
1588 "repne; scasb\n\t"
1589 "je 1b\n"
1590 "2:"
1591 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1592 : "0" (__s), "1" (__accept), "g" (__accept_len)
1593 : "cc");
1594 return (__res - 1) - __s;
1595 }
1596
1597 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1598 #ifdef __PIC__
1599
1600 __STRING_INLINE size_t
1601 __strspn_g (__const char *__s, __const char *__accept)
1602 {
1603 register unsigned long int __d0, __d1, __d2;
1604 register __const char *__res;
1605 __asm__ __volatile__
1606 ("pushl %%ebx\n\t"
1607 "cld\n\t"
1608 "repne; scasb\n\t"
1609 "notl %%ecx\n\t"
1610 "leal -1(%%ecx),%%ebx\n"
1611 "1:\n\t"
1612 "lodsb\n\t"
1613 "testb %%al,%%al\n\t"
1614 "je 2f\n\t"
1615 "movl %%edx,%%edi\n\t"
1616 "movl %%ebx,%%ecx\n\t"
1617 "repne; scasb\n\t"
1618 "je 1b\n"
1619 "2:\n\t"
1620 "popl %%ebx"
1621 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1622 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1623 : "cc");
1624 return (__res - 1) - __s;
1625 }
1626 #else
1627 __STRING_INLINE size_t
1628 __strspn_g (__const char *__s, __const char *__accept)
1629 {
1630 register unsigned long int __d0, __d1, __d2, __d3;
1631 register __const char *__res;
1632 __asm__ __volatile__
1633 ("cld\n\t"
1634 "repne; scasb\n\t"
1635 "notl %%ecx\n\t"
1636 "leal -1(%%ecx),%%edx\n"
1637 "1:\n\t"
1638 "lodsb\n\t"
1639 "testb %%al,%%al\n\t"
1640 "je 2f\n\t"
1641 "movl %%ebx,%%edi\n\t"
1642 "movl %%edx,%%ecx\n\t"
1643 "repne; scasb\n\t"
1644 "je 1b\n"
1645 "2:"
1646 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1647 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1648 : "cc");
1649 return (__res - 1) - __s;
1650 }
1651 #endif
1652
1653
1654 /* Find the first occurrence in S of any character in ACCEPT. */
1655 #define _HAVE_STRING_ARCH_strpbrk 1
1656 #define strpbrk(s, accept) \
1657 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1658 ? ((accept)[0] == '\0' \
1659 ? NULL \
1660 : ((accept)[1] == '\0' \
1661 ? strchr (s, (accept)[0]) \
1662 : __strpbrk_cg (s, accept, strlen (accept)))) \
1663 : __strpbrk_g (s, accept)))
1664
1665 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1666 size_t __accept_len);
1667
1668 __STRING_INLINE char *
1669 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1670 {
1671 register unsigned long int __d0, __d1, __d2;
1672 register char *__res;
1673 __asm__ __volatile__
1674 ("cld\n"
1675 "1:\n\t"
1676 "lodsb\n\t"
1677 "testb %%al,%%al\n\t"
1678 "je 2f\n\t"
1679 "movl %5,%%edi\n\t"
1680 "movl %6,%%ecx\n\t"
1681 "repne; scasb\n\t"
1682 "jne 1b\n\t"
1683 "decl %0\n\t"
1684 "jmp 3f\n"
1685 "2:\n\t"
1686 "xorl %0,%0\n"
1687 "3:"
1688 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1689 : "0" (__s), "d" (__accept), "g" (__accept_len)
1690 : "cc");
1691 return __res;
1692 }
1693
1694 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1695 #ifdef __PIC__
1696
1697 __STRING_INLINE char *
1698 __strpbrk_g (__const char *__s, __const char *__accept)
1699 {
1700 register unsigned long int __d0, __d1, __d2;
1701 register char *__res;
1702 __asm__ __volatile__
1703 ("pushl %%ebx\n\t"
1704 "movl %%edx,%%edi\n\t"
1705 "cld\n\t"
1706 "repne; scasb\n\t"
1707 "notl %%ecx\n\t"
1708 "leal -1(%%ecx),%%ebx\n"
1709 "1:\n\t"
1710 "lodsb\n\t"
1711 "testb %%al,%%al\n\t"
1712 "je 2f\n\t"
1713 "movl %%edx,%%edi\n\t"
1714 "movl %%ebx,%%ecx\n\t"
1715 "repne; scasb\n\t"
1716 "jne 1b\n\t"
1717 "decl %0\n\t"
1718 "jmp 3f\n"
1719 "2:\n\t"
1720 "xorl %0,%0\n"
1721 "3:\n\t"
1722 "popl %%ebx"
1723 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1724 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1725 : "cc");
1726 return __res;
1727 }
1728 #else
1729 __STRING_INLINE char *
1730 __strpbrk_g (__const char *__s, __const char *__accept)
1731 {
1732 register unsigned long int __d0, __d1, __d2, __d3;
1733 register char *__res;
1734 __asm__ __volatile__
1735 ("movl %%ebx,%%edi\n\t"
1736 "cld\n\t"
1737 "repne; scasb\n\t"
1738 "notl %%ecx\n\t"
1739 "leal -1(%%ecx),%%edx\n"
1740 "1:\n\t"
1741 "lodsb\n\t"
1742 "testb %%al,%%al\n\t"
1743 "je 2f\n\t"
1744 "movl %%ebx,%%edi\n\t"
1745 "movl %%edx,%%ecx\n\t"
1746 "repne; scasb\n\t"
1747 "jne 1b\n\t"
1748 "decl %0\n\t"
1749 "jmp 3f\n"
1750 "2:\n\t"
1751 "xorl %0,%0\n"
1752 "3:"
1753 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1754 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1755 : "cc");
1756 return __res;
1757 }
1758 #endif
1759
1760
1761 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1762 #define _HAVE_STRING_ARCH_strstr 1
1763 #define strstr(haystack, needle) \
1764 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1765 ? ((needle)[0] == '\0' \
1766 ? haystack \
1767 : ((needle)[1] == '\0' \
1768 ? strchr (haystack, (needle)[0]) \
1769 : __strstr_cg (haystack, needle, strlen (needle)))) \
1770 : __strstr_g (haystack, needle)))
1771
1772 /* Please note that this function need not handle NEEDLEs with a
1773 length shorter than two. */
1774 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1775 size_t __needle_len);
1776
1777 __STRING_INLINE char *
1778 __strstr_cg (__const char *__haystack, __const char __needle[],
1779 size_t __needle_len)
1780 {
1781 register unsigned long int __d0, __d1, __d2;
1782 register char *__res;
1783 __asm__ __volatile__
1784 ("cld\n" \
1785 "1:\n\t"
1786 "movl %6,%%edi\n\t"
1787 "movl %5,%%eax\n\t"
1788 "movl %4,%%ecx\n\t"
1789 "repe; cmpsb\n\t"
1790 "je 2f\n\t"
1791 "cmpb $0,-1(%%esi)\n\t"
1792 "leal 1(%%eax),%5\n\t"
1793 "jne 1b\n\t"
1794 "xorl %%eax,%%eax\n"
1795 "2:"
1796 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1797 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1798 : "cc");
1799 return __res;
1800 }
1801
1802 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1803 #ifdef __PIC__
1804
1805 __STRING_INLINE char *
1806 __strstr_g (__const char *__haystack, __const char *__needle)
1807 {
1808 register unsigned long int __d0, __d1, __d2;
1809 register char *__res;
1810 __asm__ __volatile__
1811 ("cld\n\t"
1812 "repne; scasb\n\t"
1813 "notl %%ecx\n\t"
1814 "pushl %%ebx\n\t"
1815 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1816 "movl %%ecx,%%ebx\n"
1817 "1:\n\t"
1818 "movl %%edx,%%edi\n\t"
1819 "movl %%esi,%%eax\n\t"
1820 "movl %%ebx,%%ecx\n\t"
1821 "repe; cmpsb\n\t"
1822 "je 2f\n\t" /* also works for empty string, see above */
1823 "cmpb $0,-1(%%esi)\n\t"
1824 "leal 1(%%eax),%%esi\n\t"
1825 "jne 1b\n\t"
1826 "xorl %%eax,%%eax\n"
1827 "2:\n\t"
1828 "popl %%ebx"
1829 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1830 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1831 "d" (__needle)
1832 : "cc");
1833 return __res;
1834 }
1835 #else
1836 __STRING_INLINE char *
1837 __strstr_g (__const char *__haystack, __const char *__needle)
1838 {
1839 register unsigned long int __d0, __d1, __d2, __d3;
1840 register char *__res;
1841 __asm__ __volatile__
1842 ("cld\n\t"
1843 "repne; scasb\n\t"
1844 "notl %%ecx\n\t"
1845 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1846 "movl %%ecx,%%edx\n"
1847 "1:\n\t"
1848 "movl %%ebx,%%edi\n\t"
1849 "movl %%esi,%%eax\n\t"
1850 "movl %%edx,%%ecx\n\t"
1851 "repe; cmpsb\n\t"
1852 "je 2f\n\t" /* also works for empty string, see above */
1853 "cmpb $0,-1(%%esi)\n\t"
1854 "leal 1(%%eax),%%esi\n\t"
1855 "jne 1b\n\t"
1856 "xorl %%eax,%%eax\n"
1857 "2:"
1858 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1859 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1860 "b" (__needle)
1861 : "cc");
1862 return __res;
1863 }
1864 #endif
1865
1866
1867 /* Bit find functions. We define only the i686 version since for the other
1868 processors gcc generates good code. */
1869 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1870 # ifdef __i686__
1871 # define _HAVE_STRING_ARCH_ffs 1
1872 # define ffs(word) (__builtin_constant_p (word) \
1873 ? __builtin_ffs (word) \
1874 : ({ int __cnt, __tmp; \
1875 __asm__ __volatile__ \
1876 ("bsfl %2,%0\n\t" \
1877 "cmovel %1,%0" \
1878 : "=&r" (__cnt), "=r" (__tmp) \
1879 : "rm" (word), "1" (-1)); \
1880 __cnt + 1; }))
1881
1882 # ifndef ffsl
1883 # define ffsl(word) ffs(word)
1884 # endif
1885 # endif /* i686 */
1886 #endif /* BSD || X/Open */
1887
1888 #ifndef _FORCE_INLINES
1889 # undef __STRING_INLINE
1890 #endif
1891
1892 #endif /* use string inlines && GNU CC */