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