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