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
- __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 extern char * ___strtok;
292
293 #define __HAVE_ARCH_STRTOK
294 extern inline char * strtok(char * s,const char * ct)
295 {
296 register char * __res;
297 __asm__ __volatile__(
298 "testl %1,%1\n\t"
299 "jne 1f\n\t"
300 "testl %0,%0\n\t"
301 "je 8f\n\t"
302 "movl %0,%1\n"
303 "1:\txorl %0,%0\n\t"
304 "movl $-1,%%ecx\n\t"
305 "xorl %%eax,%%eax\n\t"
306 "cld\n\t"
307 "movl %4,%%edi\n\t"
308 "repne\n\t"
309 "scasb\n\t"
310 "notl %%ecx\n\t"
311 "decl %%ecx\n\t"
312 "je 7f\n\t"
313 "movl %%ecx,%%edx\n"
314 "2:\tlodsb\n\t"
315 "testb %%al,%%al\n\t"
316 "je 7f\n\t"
317 "movl %4,%%edi\n\t"
318 "movl %%edx,%%ecx\n\t"
319 "repne\n\t"
320 "scasb\n\t"
321 "je 2b\n\t"
322 "decl %1\n\t"
323 "cmpb $0,(%1)\n\t"
324 "je 7f\n\t"
325 "movl %1,%0\n"
326 "3:\tlodsb\n\t"
327 "testb %%al,%%al\n\t"
328 "je 5f\n\t"
329 "movl %4,%%edi\n\t"
330 "movl %%edx,%%ecx\n\t"
331 "repne\n\t"
332 "scasb\n\t"
333 "jne 3b\n\t"
334 "decl %1\n\t"
335 "cmpb $0,(%1)\n\t"
336 "je 5f\n\t"
337 "movb $0,(%1)\n\t"
338 "incl %1\n\t"
339 "jmp 6f\n"
340 "5:\txorl %1,%1\n"
341 "6:\tcmpb $0,(%0)\n\t"
342 "jne 7f\n\t"
343 "xorl %0,%0\n"
344 "7:\ttestl %0,%0\n\t"
345 "jne 8f\n\t"
346 "movl %0,%1\n"
347 "8:"
348 :"=b" (__res),"=S" (___strtok)
349 :"0" (___strtok),"1" (s),"g" (ct)
350 :"ax","cx","dx","di","memory");
351 return __res;
352 }
353
354 extern inline void * __memcpy(void * to, const void * from, size_t n)
355 {
356 __asm__ __volatile__(
357 "cld\n\t"
358 "rep ; movsl\n\t"
359 "testb $2,%b1\n\t"
360 "je 1f\n\t"
361 "movsw\n"
362 "1:\ttestb $1,%b1\n\t"
363 "je 2f\n\t"
364 "movsb\n"
365 "2:"
366 :
367 :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from)
368 : "cx","di","si","memory");
369 return (to);
370 }
371
372
373
374
375
376 extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
377 {
378 switch (n) {
379 case 0:
380 return to;
381 case 1:
382 *(unsigned char *)to = *(const unsigned char *)from;
383 return to;
384 case 2:
385 *(unsigned short *)to = *(const unsigned short *)from;
386 return to;
387 case 3:
388 *(unsigned short *)to = *(const unsigned short *)from;
389 *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
390 return to;
391 case 4:
392 *(unsigned long *)to = *(const unsigned long *)from;
393 return to;
394 }
395 #define COMMON(x) \
396 __asm__("cld\n\t" \
397 "rep ; movsl" \
398 x \
399 : \
400 : "c" (n/4),"D" ((long) to),"S" ((long) from) \
401 : "cx","di","si","memory");
402
403 switch (n % 4) {
404 case 0: COMMON(""); return to;
405 case 1: COMMON("\n\tmovsb"); return to;
406 case 2: COMMON("\n\tmovsw"); return to;
407 case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
408 }
409 #undef COMMON
410 }
411
412 #define __HAVE_ARCH_MEMCPY
413 #define memcpy(t, f, n) \
414 (__builtin_constant_p(n) ? \
415 __constant_memcpy((t),(f),(n)) : \
416 __memcpy((t),(f),(n)))
417
418 #define __HAVE_ARCH_MEMMOVE
419 extern inline void * memmove(void * dest,const void * src, size_t n)
420 {
421 if (dest<src)
422 __asm__ __volatile__(
423 "cld\n\t"
424 "rep\n\t"
425 "movsb"
426 :
427 :"c" (n),"S" (src),"D" (dest)
428 :"cx","si","di");
429 else
430 __asm__ __volatile__(
431 "std\n\t"
432 "rep\n\t"
433 "movsb\n\t"
434 "cld"
435 :
436 :"c" (n),
437 "S" (n-1+(const char *)src),
438 "D" (n-1+(char *)dest)
439 :"cx","si","di","memory");
440 return dest;
441 }
442
443 #define memcmp __builtin_memcmp
444
445 #define __HAVE_ARCH_MEMCHR
446 extern inline void * memchr(const void * cs,int c,size_t count)
447 {
448 register void * __res;
449 if (!count)
450 return NULL;
451 __asm__ __volatile__(
452 "cld\n\t"
453 "repne\n\t"
454 "scasb\n\t"
455 "je 1f\n\t"
456 "movl $1,%0\n"
457 "1:\tdecl %0"
458 :"=D" (__res):"a" (c),"D" (cs),"c" (count)
459 :"cx");
460 return __res;
461 }
462
463 extern inline void * __memset_generic(void * s, char c,size_t count)
464 {
465 __asm__ __volatile__(
466 "cld\n\t"
467 "rep\n\t"
468 "stosb"
469 :
470 :"a" (c),"D" (s),"c" (count)
471 :"cx","di","memory");
472 return s;
473 }
474
475
476 #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
477
478
479
480
481
482
483 extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
484 {
485 __asm__ __volatile__(
486 "cld\n\t"
487 "rep ; stosl\n\t"
488 "testb $2,%b1\n\t"
489 "je 1f\n\t"
490 "stosw\n"
491 "1:\ttestb $1,%b1\n\t"
492 "je 2f\n\t"
493 "stosb\n"
494 "2:"
495 :
496 :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
497 :"cx","di","memory");
498 return (s);
499 }
500
501
502
503
504
505
506 extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
507 {
508 switch (count) {
509 case 0:
510 return s;
511 case 1:
512 *(unsigned char *)s = pattern;
513 return s;
514 case 2:
515 *(unsigned short *)s = pattern;
516 return s;
517 case 3:
518 *(unsigned short *)s = pattern;
519 *(2+(unsigned char *)s) = pattern;
520 return s;
521 case 4:
522 *(unsigned long *)s = pattern;
523 return s;
524 }
525 #define COMMON(x) \
526 __asm__("cld\n\t" \
527 "rep ; stosl" \
528 x \
529 : \
530 : "a" (pattern),"c" (count/4),"D" ((long) s) \
531 : "cx","di","memory")
532
533 switch (count % 4) {
534 case 0: COMMON(""); return s;
535 case 1: COMMON("\n\tstosb"); return s;
536 case 2: COMMON("\n\tstosw"); return s;
537 case 3: COMMON("\n\tstosw\n\tstosb"); return s;
538 }
539 #undef COMMON
540 }
541
542 #define __constant_c_x_memset(s, c, count) \
543 (__builtin_constant_p(count) ? \
544 __constant_c_and_count_memset((s),(c),(count)) : \
545 __constant_c_memset((s),(c),(count)))
546
547 #define __memset(s, c, count) \
548 (__builtin_constant_p(count) ? \
549 __constant_count_memset((s),(c),(count)) : \
550 __memset_generic((s),(c),(count)))
551
552 #define __HAVE_ARCH_MEMSET
553 #define memset(s, c, count) \
554 (__builtin_constant_p(c) ? \
555 __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
556 __memset((s),(c),(count)))
557
558
559
560
561 #define __HAVE_ARCH_MEMSCAN
562 extern inline void * memscan(void * addr, int c, size_t size)
563 {
564 if (!size)
565 return addr;
566 __asm__("cld
567 repnz; scasb
568 jnz 1f
569 dec %%edi
570 1: "
571 : "=D" (addr), "=c" (size)
572 : "0" (addr), "1" (size), "a" (c));
573 return addr;
574 }
575
576 #endif