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