This source file includes following definitions.
- strcpy
- strncpy
- strcat
- strncat
- strcmp
- strncmp
- strchr
- strrchr
- strspn
- strcspn
- strpbrk
- strstr
- strlen
- strtok
- __memcpy
- __constant_memcpy
- memmove
- memchr
- __memset_generic
- __constant_c_memset
- strnlen
- __constant_c_and_count_memset
- memscan
1 #ifndef _I386_STRING_H_
2 #define _I386_STRING_H_
3
4
5
6
7
8
9
10
11
12
13 #if FIXED_486_STRING && (CPU == 486 || CPU == 586)
14 #include <asm/string-486.h>
15 #else
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #define __HAVE_ARCH_STRCPY
30 extern inline char * strcpy(char * dest,const char *src)
31 {
32 __asm__ __volatile__(
33 "cld\n"
34 "1:\tlodsb\n\t"
35 "stosb\n\t"
36 "testb %%al,%%al\n\t"
37 "jne 1b"
38 :
39 :"S" (src),"D" (dest):"si","di","ax","memory");
40 return dest;
41 }
42
43 #define __HAVE_ARCH_STRNCPY
44 extern inline char * strncpy(char * dest,const char *src,size_t count)
45 {
46 __asm__ __volatile__(
47 "cld\n"
48 "1:\tdecl %2\n\t"
49 "js 2f\n\t"
50 "lodsb\n\t"
51 "stosb\n\t"
52 "testb %%al,%%al\n\t"
53 "jne 1b\n\t"
54 "rep\n\t"
55 "stosb\n"
56 "2:"
57 :
58 :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
59 return dest;
60 }
61
62 #define __HAVE_ARCH_STRCAT
63 extern inline char * strcat(char * dest,const char * src)
64 {
65 __asm__ __volatile__(
66 "cld\n\t"
67 "repne\n\t"
68 "scasb\n\t"
69 "decl %1\n"
70 "1:\tlodsb\n\t"
71 "stosb\n\t"
72 "testb %%al,%%al\n\t"
73 "jne 1b"
74 :
75 :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
76 return dest;
77 }
78
79 #define __HAVE_ARCH_STRNCAT
80 extern inline char * strncat(char * dest,const char * src,size_t count)
81 {
82 __asm__ __volatile__(
83 "cld\n\t"
84 "repne\n\t"
85 "scasb\n\t"
86 "decl %1\n\t"
87 "movl %4,%3\n"
88 "1:\tdecl %3\n\t"
89 "js 2f\n\t"
90 "lodsb\n\t"
91 "stosb\n\t"
92 "testb %%al,%%al\n\t"
93 "jne 1b\n"
94 "2:\txorl %2,%2\n\t"
95 "stosb"
96 :
97 :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
98 :"si","di","ax","cx","memory");
99 return dest;
100 }
101
102 #define __HAVE_ARCH_STRCMP
103 extern inline int strcmp(const char * cs,const char * ct)
104 {
105 register int __res;
106 __asm__ __volatile__(
107 "cld\n"
108 "1:\tlodsb\n\t"
109 "scasb\n\t"
110 "jne 2f\n\t"
111 "testb %%al,%%al\n\t"
112 "jne 1b\n\t"
113 "xorl %%eax,%%eax\n\t"
114 "jmp 3f\n"
115 "2:\tsbbl %%eax,%%eax\n\t"
116 "orb $1,%%eax\n"
117 "3:"
118 :"=a" (__res):"S" (cs),"D" (ct):"si","di");
119 return __res;
120 }
121
122 #define __HAVE_ARCH_STRNCMP
123 extern inline int strncmp(const char * cs,const char * ct,size_t count)
124 {
125 register int __res;
126 __asm__ __volatile__(
127 "cld\n"
128 "1:\tdecl %3\n\t"
129 "js 2f\n\t"
130 "lodsb\n\t"
131 "scasb\n\t"
132 "jne 3f\n\t"
133 "testb %%al,%%al\n\t"
134 "jne 1b\n"
135 "2:\txorl %%eax,%%eax\n\t"
136 "jmp 4f\n"
137 "3:\tsbbl %%eax,%%eax\n\t"
138 "orb $1,%%al\n"
139 "4:"
140 :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
141 return __res;
142 }
143
144 #define __HAVE_ARCH_STRCHR
145 extern inline char * strchr(const char * s, int c)
146 {
147 register char * __res;
148 __asm__ __volatile__(
149 "cld\n\t"
150 "movb %%al,%%ah\n"
151 "1:\tlodsb\n\t"
152 "cmpb %%ah,%%al\n\t"
153 "je 2f\n\t"
154 "testb %%al,%%al\n\t"
155 "jne 1b\n\t"
156 "movl $1,%1\n"
157 "2:\tmovl %1,%0\n\t"
158 "decl %0"
159 :"=a" (__res):"S" (s),"0" (c):"si");
160 return __res;
161 }
162
163 #define __HAVE_ARCH_STRRCHR
164 extern inline char * strrchr(const char * s, int c)
165 {
166 register char * __res;
167 __asm__ __volatile__(
168 "cld\n\t"
169 "movb %%al,%%ah\n"
170 "1:\tlodsb\n\t"
171 "cmpb %%ah,%%al\n\t"
172 "jne 2f\n\t"
173 "leal -1(%%esi),%0\n"
174 "2:\ttestb %%al,%%al\n\t"
175 "jne 1b"
176 :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
177 return __res;
178 }
179
180 #define __HAVE_ARCH_STRSPN
181 extern inline size_t strspn(const char * cs, const char * ct)
182 {
183 register char * __res;
184 __asm__ __volatile__(
185 "cld\n\t"
186 "movl %4,%%edi\n\t"
187 "repne\n\t"
188 "scasb\n\t"
189 "notl %%ecx\n\t"
190 "decl %%ecx\n\t"
191 "movl %%ecx,%%edx\n"
192 "1:\tlodsb\n\t"
193 "testb %%al,%%al\n\t"
194 "je 2f\n\t"
195 "movl %4,%%edi\n\t"
196 "movl %%edx,%%ecx\n\t"
197 "repne\n\t"
198 "scasb\n\t"
199 "je 1b\n"
200 "2:\tdecl %0"
201 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
202 :"ax","cx","dx","di");
203 return __res-cs;
204 }
205
206 #define __HAVE_ARCH_STRCSPN
207 extern inline size_t strcspn(const char * cs, const char * ct)
208 {
209 register char * __res;
210 __asm__ __volatile__(
211 "cld\n\t"
212 "movl %4,%%edi\n\t"
213 "repne\n\t"
214 "scasb\n\t"
215 "notl %%ecx\n\t"
216 "decl %%ecx\n\t"
217 "movl %%ecx,%%edx\n"
218 "1:\tlodsb\n\t"
219 "testb %%al,%%al\n\t"
220 "je 2f\n\t"
221 "movl %4,%%edi\n\t"
222 "movl %%edx,%%ecx\n\t"
223 "repne\n\t"
224 "scasb\n\t"
225 "jne 1b\n"
226 "2:\tdecl %0"
227 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
228 :"ax","cx","dx","di");
229 return __res-cs;
230 }
231
232 #define __HAVE_ARCH_STRPBRK
233 extern inline char * strpbrk(const char * cs,const char * ct)
234 {
235 register char * __res;
236 __asm__ __volatile__(
237 "cld\n\t"
238 "movl %4,%%edi\n\t"
239 "repne\n\t"
240 "scasb\n\t"
241 "notl %%ecx\n\t"
242 "decl %%ecx\n\t"
243 "movl %%ecx,%%edx\n"
244 "1:\tlodsb\n\t"
245 "testb %%al,%%al\n\t"
246 "je 2f\n\t"
247 "movl %4,%%edi\n\t"
248 "movl %%edx,%%ecx\n\t"
249 "repne\n\t"
250 "scasb\n\t"
251 "jne 1b\n\t"
252 "decl %0\n\t"
253 "jmp 3f\n"
254 "2:\txorl %0,%0\n"
255 "3:"
256 :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
257 :"ax","cx","dx","di");
258 return __res;
259 }
260
261 #define __HAVE_ARCH_STRSTR
262 extern inline char * strstr(const char * cs,const char * ct)
263 {
264 register char * __res;
265 __asm__ __volatile__(
266 "cld\n\t" \
267 "movl %4,%%edi\n\t"
268 "repne\n\t"
269 "scasb\n\t"
270 "notl %%ecx\n\t"
271 "decl %%ecx\n\t"
272 "movl %%ecx,%%edx\n"
273 "1:\tmovl %4,%%edi\n\t"
274 "movl %%esi,%%eax\n\t"
275 "movl %%edx,%%ecx\n\t"
276 "repe\n\t"
277 "cmpsb\n\t"
278 "je 2f\n\t"
279 "xchgl %%eax,%%esi\n\t"
280 "incl %%esi\n\t"
281 "cmpb $0,-1(%%eax)\n\t"
282 "jne 1b\n\t"
283 "xorl %%eax,%%eax\n\t"
284 "2:"
285 :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
286 :"cx","dx","di","si");
287 return __res;
288 }
289
290 #define __HAVE_ARCH_STRLEN
291 extern inline size_t strlen(const char * s)
292 {
293 register int __res;
294 __asm__ __volatile__(
295 "cld\n\t"
296 "repne\n\t"
297 "scasb\n\t"
298 "notl %0\n\t"
299 "decl %0"
300 :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
301 return __res;
302 }
303
304 #define __HAVE_ARCH_STRTOK
305 extern inline char * strtok(char * s,const char * ct)
306 {
307 register char * __res;
308 __asm__ __volatile__(
309 "testl %1,%1\n\t"
310 "jne 1f\n\t"
311 "testl %0,%0\n\t"
312 "je 8f\n\t"
313 "movl %0,%1\n"
314 "1:\txorl %0,%0\n\t"
315 "movl $-1,%%ecx\n\t"
316 "xorl %%eax,%%eax\n\t"
317 "cld\n\t"
318 "movl %4,%%edi\n\t"
319 "repne\n\t"
320 "scasb\n\t"
321 "notl %%ecx\n\t"
322 "decl %%ecx\n\t"
323 "je 7f\n\t"
324 "movl %%ecx,%%edx\n"
325 "2:\tlodsb\n\t"
326 "testb %%al,%%al\n\t"
327 "je 7f\n\t"
328 "movl %4,%%edi\n\t"
329 "movl %%edx,%%ecx\n\t"
330 "repne\n\t"
331 "scasb\n\t"
332 "je 2b\n\t"
333 "decl %1\n\t"
334 "cmpb $0,(%1)\n\t"
335 "je 7f\n\t"
336 "movl %1,%0\n"
337 "3:\tlodsb\n\t"
338 "testb %%al,%%al\n\t"
339 "je 5f\n\t"
340 "movl %4,%%edi\n\t"
341 "movl %%edx,%%ecx\n\t"
342 "repne\n\t"
343 "scasb\n\t"
344 "jne 3b\n\t"
345 "decl %1\n\t"
346 "cmpb $0,(%1)\n\t"
347 "je 5f\n\t"
348 "movb $0,(%1)\n\t"
349 "incl %1\n\t"
350 "jmp 6f\n"
351 "5:\txorl %1,%1\n"
352 "6:\tcmpb $0,(%0)\n\t"
353 "jne 7f\n\t"
354 "xorl %0,%0\n"
355 "7:\ttestl %0,%0\n\t"
356 "jne 8f\n\t"
357 "movl %0,%1\n"
358 "8:"
359 :"=b" (__res),"=S" (___strtok)
360 :"0" (___strtok),"1" (s),"g" (ct)
361 :"ax","cx","dx","di","memory");
362 return __res;
363 }
364
365 extern inline void * __memcpy(void * to, const void * from, size_t n)
366 {
367 __asm__ __volatile__(
368 "cld\n\t"
369 "rep ; movsl\n\t"
370 "testb $2,%b1\n\t"
371 "je 1f\n\t"
372 "movsw\n"
373 "1:\ttestb $1,%b1\n\t"
374 "je 2f\n\t"
375 "movsb\n"
376 "2:"
377 :
378 :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from)
379 : "cx","di","si","memory");
380 return (to);
381 }
382
383
384
385
386
387 extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
388 {
389 switch (n) {
390 case 0:
391 return to;
392 case 1:
393 *(unsigned char *)to = *(const unsigned char *)from;
394 return to;
395 case 2:
396 *(unsigned short *)to = *(const unsigned short *)from;
397 return to;
398 case 3:
399 *(unsigned short *)to = *(const unsigned short *)from;
400 *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
401 return to;
402 case 4:
403 *(unsigned long *)to = *(const unsigned long *)from;
404 return to;
405 }
406 #define COMMON(x) \
407 __asm__("cld\n\t" \
408 "rep ; movsl" \
409 x \
410 : \
411 : "c" (n/4),"D" ((long) to),"S" ((long) from) \
412 : "cx","di","si","memory");
413
414 switch (n % 4) {
415 case 0: COMMON(""); return to;
416 case 1: COMMON("\n\tmovsb"); return to;
417 case 2: COMMON("\n\tmovsw"); return to;
418 case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
419 }
420 #undef COMMON
421 }
422
423 #define __HAVE_ARCH_MEMCPY
424 #define memcpy(t, f, n) \
425 (__builtin_constant_p(n) ? \
426 __constant_memcpy((t),(f),(n)) : \
427 __memcpy((t),(f),(n)))
428
429 #define __HAVE_ARCH_MEMMOVE
430 extern inline void * memmove(void * dest,const void * src, size_t n)
431 {
432 if (dest<src)
433 __asm__ __volatile__(
434 "cld\n\t"
435 "rep\n\t"
436 "movsb"
437 :
438 :"c" (n),"S" (src),"D" (dest)
439 :"cx","si","di");
440 else
441 __asm__ __volatile__(
442 "std\n\t"
443 "rep\n\t"
444 "movsb\n\t"
445 "cld"
446 :
447 :"c" (n),
448 "S" (n-1+(const char *)src),
449 "D" (n-1+(char *)dest)
450 :"cx","si","di","memory");
451 return dest;
452 }
453
454 #define memcmp __builtin_memcmp
455
456 #define __HAVE_ARCH_MEMCHR
457 extern inline void * memchr(const void * cs,int c,size_t count)
458 {
459 register void * __res;
460 if (!count)
461 return NULL;
462 __asm__ __volatile__(
463 "cld\n\t"
464 "repne\n\t"
465 "scasb\n\t"
466 "je 1f\n\t"
467 "movl $1,%0\n"
468 "1:\tdecl %0"
469 :"=D" (__res):"a" (c),"D" (cs),"c" (count)
470 :"cx");
471 return __res;
472 }
473
474 extern inline void * __memset_generic(void * s, char c,size_t count)
475 {
476 __asm__ __volatile__(
477 "cld\n\t"
478 "rep\n\t"
479 "stosb"
480 :
481 :"a" (c),"D" (s),"c" (count)
482 :"cx","di","memory");
483 return s;
484 }
485
486
487 #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
488
489
490
491
492
493
494 extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
495 {
496 __asm__ __volatile__(
497 "cld\n\t"
498 "rep ; stosl\n\t"
499 "testb $2,%b1\n\t"
500 "je 1f\n\t"
501 "stosw\n"
502 "1:\ttestb $1,%b1\n\t"
503 "je 2f\n\t"
504 "stosb\n"
505 "2:"
506 :
507 :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
508 :"cx","di","memory");
509 return (s);
510 }
511
512
513 #define __HAVE_ARCH_STRNLEN
514 extern inline size_t strnlen(const char * s, size_t count)
515 {
516 register int __res;
517 __asm__ __volatile__(
518 "movl %1,%0\n\t"
519 "jmp 2f\n"
520 "1:\tcmpb $0,(%0)\n\t"
521 "je 3f\n\t"
522 "incl %0\n"
523 "2:\tdecl %2\n\t"
524 "cmpl $-1,%2\n\t"
525 "jne 1b\n"
526 "3:\tsubl %1,%0"
527 :"=a" (__res):"c" (s),"d" (count));
528 return __res;
529 }
530
531
532
533
534
535
536 extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
537 {
538 switch (count) {
539 case 0:
540 return s;
541 case 1:
542 *(unsigned char *)s = pattern;
543 return s;
544 case 2:
545 *(unsigned short *)s = pattern;
546 return s;
547 case 3:
548 *(unsigned short *)s = pattern;
549 *(2+(unsigned char *)s) = pattern;
550 return s;
551 case 4:
552 *(unsigned long *)s = pattern;
553 return s;
554 }
555 #define COMMON(x) \
556 __asm__("cld\n\t" \
557 "rep ; stosl" \
558 x \
559 : \
560 : "a" (pattern),"c" (count/4),"D" ((long) s) \
561 : "cx","di","memory")
562
563 switch (count % 4) {
564 case 0: COMMON(""); return s;
565 case 1: COMMON("\n\tstosb"); return s;
566 case 2: COMMON("\n\tstosw"); return s;
567 case 3: COMMON("\n\tstosw\n\tstosb"); return s;
568 }
569 #undef COMMON
570 }
571
572 #define __constant_c_x_memset(s, c, count) \
573 (__builtin_constant_p(count) ? \
574 __constant_c_and_count_memset((s),(c),(count)) : \
575 __constant_c_memset((s),(c),(count)))
576
577 #define __memset(s, c, count) \
578 (__builtin_constant_p(count) ? \
579 __constant_count_memset((s),(c),(count)) : \
580 __memset_generic((s),(c),(count)))
581
582 #define __HAVE_ARCH_MEMSET
583 #define memset(s, c, count) \
584 (__builtin_constant_p(c) ? \
585 __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
586 __memset((s),(c),(count)))
587
588
589
590
591 #define __HAVE_ARCH_MEMSCAN
592 extern inline void * memscan(void * addr, int c, size_t size)
593 {
594 if (!size)
595 return addr;
596 __asm__("cld
597 repnz; scasb
598 jnz 1f
599 dec %%edi
600 1: "
601 : "=D" (addr), "=c" (size)
602 : "0" (addr), "1" (size), "a" (c));
603 return addr;
604 }
605
606 #endif
607 #endif