|
|
1.1 root 1: #ifndef _STRING_H_
2: #define _STRING_H_
3:
4: #ifndef NULL
5: #define NULL ((void *) 0)
6: #endif
7:
8: #ifndef _SIZE_T
9: #define _SIZE_T
10: typedef unsigned int size_t;
11: #endif
12:
13: extern char * strerror(int errno);
14:
15: /*
16: * This string-include defines all string functions as inline
17: * functions. Use gcc. It also assumes ds=es=data space, this should be
18: * normal. Most of the string-functions are rather heavily hand-optimized,
19: * see especially strtok,strstr,str[c]spn. They should work, but are not
20: * very easy to understand. Everything is done entirely within the register
21: * set, making the functions fast and clean. String instructions have been
22: * used through-out, making for "slightly" unclear code :-)
23: *
24: * (C) 1991 Linus Torvalds
25: */
26:
27: extern inline char * strcpy(char * dest,const char *src)
28: {
1.1.1.2 ! root 29: int d0, d1, d2;
! 30: __asm__ __volatile__("cld\n\t"
1.1 root 31: "1:\tlodsb\n\t"
32: "stosb\n\t"
33: "testb %%al,%%al\n\t"
34: "jne 1b"
1.1.1.2 ! root 35: : "=&S" (d0), "=&D" (d1), "=&a" (d2)
! 36: :"0" (src),"1" (dest) : "memory");
1.1 root 37: return dest;
38: }
39:
40: extern inline char * strncpy(char * dest,const char *src,int count)
41: {
1.1.1.2 ! root 42: int d0, d1, d2, d3;
! 43: __asm__ __volatile__("cld\n\t"
1.1 root 44: "1:\tdecl %2\n\t"
45: "js 2f\n\t"
46: "lodsb\n\t"
47: "stosb\n\t"
48: "testb %%al,%%al\n\t"
49: "jne 1b\n\t"
50: "rep\n\t"
51: "stosb\n"
52: "2:"
1.1.1.2 ! root 53: : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
! 54: :"0" (src),"1" (dest),"2" (count) : "memory");
1.1 root 55: return dest;
56: }
57:
58: extern inline char * strcat(char * dest,const char * src)
59: {
1.1.1.2 ! root 60: int d0, d1, d2, d3;
! 61: __asm__ __volatile__("cld\n\t"
1.1 root 62: "repne\n\t"
63: "scasb\n\t"
64: "decl %1\n"
65: "1:\tlodsb\n\t"
66: "stosb\n\t"
67: "testb %%al,%%al\n\t"
68: "jne 1b"
1.1.1.2 ! root 69: : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
! 70: : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu):"memory");
1.1 root 71: return dest;
72: }
73:
74: extern inline char * strncat(char * dest,const char * src,int count)
75: {
1.1.1.2 ! root 76: int d0, d1, d2, d3;
! 77: __asm__ __volatile__("cld\n\t"
1.1 root 78: "repne\n\t"
79: "scasb\n\t"
80: "decl %1\n\t"
1.1.1.2 ! root 81: "movl %8,%3\n"
1.1 root 82: "1:\tdecl %3\n\t"
83: "js 2f\n\t"
84: "lodsb\n\t"
85: "stosb\n\t"
86: "testb %%al,%%al\n\t"
87: "jne 1b\n"
88: "2:\txorl %2,%2\n\t"
89: "stosb"
1.1.1.2 ! root 90: : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
! 91: : "0" (src),"1" (dest),"2" (0),"3" (0xffffffffu), "g" (count)
! 92: : "memory");
1.1 root 93: return dest;
94: }
95:
96: extern inline int strcmp(const char * cs,const char * ct)
97: {
1.1.1.2 ! root 98: int d0, d1;
! 99: register int __res;
! 100: __asm__ __volatile__("cld\n\t"
1.1 root 101: "1:\tlodsb\n\t"
102: "scasb\n\t"
103: "jne 2f\n\t"
104: "testb %%al,%%al\n\t"
105: "jne 1b\n\t"
106: "xorl %%eax,%%eax\n\t"
107: "jmp 3f\n"
1.1.1.2 ! root 108: "2:\tsbbl %%eax,%%eax\n\t"
! 109: "orb $1,%%al\n"
1.1 root 110: "3:"
1.1.1.2 ! root 111: :"=a" (__res), "=&S" (d0), "=&D" (d1)
! 112: :"1" (cs),"2" (ct)
! 113: :"memory");
1.1 root 114: return __res;
115: }
116:
117: extern inline int strncmp(const char * cs,const char * ct,int count)
118: {
1.1.1.2 ! root 119: register int __res;
! 120: int d0, d1, d2;
! 121: __asm__ __volatile__("cld\n\t"
1.1 root 122: "1:\tdecl %3\n\t"
123: "js 2f\n\t"
124: "lodsb\n\t"
125: "scasb\n\t"
126: "jne 3f\n\t"
127: "testb %%al,%%al\n\t"
128: "jne 1b\n"
129: "2:\txorl %%eax,%%eax\n\t"
130: "jmp 4f\n"
1.1.1.2 ! root 131: "3:\tsbbl %%eax,%%eax\n\t"
! 132: "orb $1,%%al\n"
1.1 root 133: "4:"
1.1.1.2 ! root 134: :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
! 135: :"1" (cs),"2" (ct),"3" (count)
! 136: :"memory");
1.1 root 137: return __res;
138: }
139:
1.1.1.2 ! root 140: extern inline char * strchr(const char * s,int c)
1.1 root 141: {
1.1.1.2 ! root 142: int d0;
! 143: register char * __res;
! 144: __asm__ __volatile__(
1.1 root 145: "movb %%al,%%ah\n"
146: "1:\tlodsb\n\t"
147: "cmpb %%ah,%%al\n\t"
148: "je 2f\n\t"
149: "testb %%al,%%al\n\t"
150: "jne 1b\n\t"
151: "movl $1,%1\n"
152: "2:\tmovl %1,%0\n\t"
153: "decl %0"
1.1.1.2 ! root 154: :"=a" (__res), "=&S" (d0)
! 155: :"1" (s),"0" (c)
! 156: :"memory");
1.1 root 157: return __res;
158: }
159:
1.1.1.2 ! root 160: extern inline char * strrchr(const char * s,int c)
1.1 root 161: {
1.1.1.2 ! root 162: int d0, d1;
! 163: register char * __res;
! 164: __asm__ __volatile__("cld\n\t"
1.1 root 165: "movb %%al,%%ah\n"
166: "1:\tlodsb\n\t"
167: "cmpb %%ah,%%al\n\t"
168: "jne 2f\n\t"
1.1.1.2 ! root 169: "leal -1(%%esi),%0\n"
1.1 root 170: "2:\ttestb %%al,%%al\n\t"
171: "jne 1b"
1.1.1.2 ! root 172: :"=g" (__res), "=&S" (d0), "=&a" (d1)
! 173: :"0" (0),"1" (s),"2" (c)
! 174: :"memory");
1.1 root 175: return __res;
176: }
177:
178: extern inline int strspn(const char * cs, const char * ct)
179: {
1.1.1.2 ! root 180: register char * __res;// __asm__("si");
1.1 root 181: __asm__("cld\n\t"
182: "movl %4,%%edi\n\t"
183: "repne\n\t"
184: "scasb\n\t"
185: "notl %%ecx\n\t"
186: "decl %%ecx\n\t"
187: "movl %%ecx,%%edx\n"
188: "1:\tlodsb\n\t"
189: "testb %%al,%%al\n\t"
190: "je 2f\n\t"
191: "movl %4,%%edi\n\t"
192: "movl %%edx,%%ecx\n\t"
193: "repne\n\t"
194: "scasb\n\t"
195: "je 1b\n"
196: "2:\tdecl %0"
197: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root 198: :/*"ax","cx",*/"dx","di"); /* TODO : constraint may be wrong*/
1.1 root 199: return __res-cs;
200: }
201:
202: extern inline int strcspn(const char * cs, const char * ct)
203: {
1.1.1.2 ! root 204: register char * __res;// __asm__("si");
1.1 root 205: __asm__("cld\n\t"
206: "movl %4,%%edi\n\t"
207: "repne\n\t"
208: "scasb\n\t"
209: "notl %%ecx\n\t"
210: "decl %%ecx\n\t"
211: "movl %%ecx,%%edx\n"
212: "1:\tlodsb\n\t"
213: "testb %%al,%%al\n\t"
214: "je 2f\n\t"
215: "movl %4,%%edi\n\t"
216: "movl %%edx,%%ecx\n\t"
217: "repne\n\t"
218: "scasb\n\t"
219: "jne 1b\n"
220: "2:\tdecl %0"
221: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root 222: :/*"ax","cx",*/"dx","di"); /* TODO : constraint may be wrong*/
1.1 root 223: return __res-cs;
224: }
225:
226: extern inline char * strpbrk(const char * cs,const char * ct)
227: {
1.1.1.2 ! root 228: register char * __res;// __asm__("si");
1.1 root 229: __asm__("cld\n\t"
230: "movl %4,%%edi\n\t"
231: "repne\n\t"
232: "scasb\n\t"
233: "notl %%ecx\n\t"
234: "decl %%ecx\n\t"
235: "movl %%ecx,%%edx\n"
236: "1:\tlodsb\n\t"
237: "testb %%al,%%al\n\t"
238: "je 2f\n\t"
239: "movl %4,%%edi\n\t"
240: "movl %%edx,%%ecx\n\t"
241: "repne\n\t"
242: "scasb\n\t"
243: "jne 1b\n\t"
244: "decl %0\n\t"
245: "jmp 3f\n"
246: "2:\txorl %0,%0\n"
247: "3:"
248: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root 249: :/*"ax","cx",*/"dx","di");/* TODO : constraint may be wrong*/
1.1 root 250: return __res;
251: }
252:
253: extern inline char * strstr(const char * cs,const char * ct)
254: {
1.1.1.2 ! root 255: register char * __res;// __asm__("ax");
1.1 root 256: __asm__("cld\n\t" \
257: "movl %4,%%edi\n\t"
258: "repne\n\t"
259: "scasb\n\t"
260: "notl %%ecx\n\t"
261: "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
262: "movl %%ecx,%%edx\n"
263: "1:\tmovl %4,%%edi\n\t"
264: "movl %%esi,%%eax\n\t"
265: "movl %%edx,%%ecx\n\t"
266: "repe\n\t"
267: "cmpsb\n\t"
268: "je 2f\n\t" /* also works for empty string, see above */
269: "xchgl %%eax,%%esi\n\t"
270: "incl %%esi\n\t"
271: "cmpb $0,-1(%%eax)\n\t"
272: "jne 1b\n\t"
273: "xorl %%eax,%%eax\n\t"
274: "2:"
275: :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
1.1.1.2 ! root 276: :/*"cx",*/"dx","di"/*,"si"*/); /* TODO : constraint may be wrong*/
1.1 root 277: return __res;
278: }
279:
280: extern inline int strlen(const char * s)
281: {
1.1.1.2 ! root 282: int d0;
! 283: register int __res;
! 284: __asm__ __volatile__("cld\n\t"
1.1 root 285: "repne\n\t"
286: "scasb\n\t"
287: "notl %0\n\t"
288: "decl %0"
1.1.1.2 ! root 289: :"=c" (__res), "=&D" (d0)
! 290: :"1" (s),"a" (0), "0" (0xffffffffu)
! 291: :"memory");
1.1 root 292: return __res;
293: }
294:
295: extern char * ___strtok;
296:
297: extern inline char * strtok(char * s,const char * ct)
298: {
1.1.1.2 ! root 299: register char * __res;// __asm__("si");
1.1 root 300: __asm__("testl %1,%1\n\t"
301: "jne 1f\n\t"
302: "testl %0,%0\n\t"
303: "je 8f\n\t"
304: "movl %0,%1\n"
305: "1:\txorl %0,%0\n\t"
306: "movl $-1,%%ecx\n\t"
307: "xorl %%eax,%%eax\n\t"
308: "cld\n\t"
309: "movl %4,%%edi\n\t"
310: "repne\n\t"
311: "scasb\n\t"
312: "notl %%ecx\n\t"
313: "decl %%ecx\n\t"
314: "je 7f\n\t" /* empty delimeter-string */
315: "movl %%ecx,%%edx\n"
316: "2:\tlodsb\n\t"
317: "testb %%al,%%al\n\t"
318: "je 7f\n\t"
319: "movl %4,%%edi\n\t"
320: "movl %%edx,%%ecx\n\t"
321: "repne\n\t"
322: "scasb\n\t"
323: "je 2b\n\t"
324: "decl %1\n\t"
325: "cmpb $0,(%1)\n\t"
326: "je 7f\n\t"
327: "movl %1,%0\n"
328: "3:\tlodsb\n\t"
329: "testb %%al,%%al\n\t"
330: "je 5f\n\t"
331: "movl %4,%%edi\n\t"
332: "movl %%edx,%%ecx\n\t"
333: "repne\n\t"
334: "scasb\n\t"
335: "jne 3b\n\t"
336: "decl %1\n\t"
337: "cmpb $0,(%1)\n\t"
338: "je 5f\n\t"
339: "movb $0,(%1)\n\t"
340: "incl %1\n\t"
341: "jmp 6f\n"
342: "5:\txorl %1,%1\n"
343: "6:\tcmpb $0,(%0)\n\t"
344: "jne 7f\n\t"
345: "xorl %0,%0\n"
346: "7:\ttestl %0,%0\n\t"
347: "jne 8f\n\t"
348: "movl %0,%1\n"
349: "8:"
350: :"=b" (__res),"=S" (___strtok)
351: :"0" (___strtok),"1" (s),"g" (ct)
1.1.1.2 ! root 352: :"ax","cx","dx","di"); /* TODO : constraint may be wrong*/
1.1 root 353: return __res;
354: }
355:
356: extern inline void * memcpy(void * dest,const void * src, int n)
357: {
1.1.1.2 ! root 358: int d0,d1,d2;
! 359: __asm__ __volatile("cld\n\t"
1.1 root 360: "rep\n\t"
361: "movsb"
1.1.1.2 ! root 362: :"=&c" (d0), "=&S" (d1), "=&D" (d2)
! 363: :"0" (n),"1" (src),"2" (dest)
! 364: :"memory");
1.1 root 365: return dest;
366: }
367:
368: extern inline void * memmove(void * dest,const void * src, int n)
369: {
1.1.1.2 ! root 370: int d0, d1, d2;
! 371:
! 372: if (dest < src) {
! 373: memcpy(dest,src,n);
! 374: } else {
! 375: __asm__ __volatile__(
! 376: "std\n\t"
! 377: "rep\n\t"
! 378: "movsb\n\t"
! 379: "cld"
! 380: : "=&c" (d0), "=&S" (d1), "=&D" (d2)
! 381: :"0" (n),
! 382: "1" (n-1+(const char *)src),
! 383: "2" (n-1+(char *)dest)
! 384: :"memory");
! 385: }
! 386: return dest;
1.1 root 387: }
388:
389: extern inline int memcmp(const void * cs,const void * ct,int count)
390: {
1.1.1.2 ! root 391: register int __res;// __asm__("ax");
1.1 root 392: __asm__("cld\n\t"
393: "repe\n\t"
394: "cmpsb\n\t"
395: "je 1f\n\t"
396: "movl $1,%%eax\n\t"
397: "jl 1f\n\t"
398: "negl %%eax\n"
399: "1:"
400: :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
1.1.1.2 ! root 401: /*:"si","di","cx"*/); /* TODO : constraint may be wrong*/
1.1 root 402: return __res;
403: }
404:
405: extern inline void * memchr(const void * cs,char c,int count)
406: {
1.1.1.2 ! root 407: int d0;
! 408: register void * __res;
1.1 root 409: if (!count)
410: return NULL;
1.1.1.2 ! root 411: __asm__ __volatile__("cld\n\t"
1.1 root 412: "repne\n\t"
413: "scasb\n\t"
414: "je 1f\n\t"
415: "movl $1,%0\n"
416: "1:\tdecl %0"
1.1.1.2 ! root 417: :"=D" (__res), "=&c" (d0)
! 418: :"a" (c),"0" (cs),"1" (count)
! 419: :"memory");
1.1 root 420: return __res;
421: }
422:
1.1.1.2 ! root 423: extern inline void * memset(void * s,int c,int count)
1.1 root 424: {
1.1.1.2 ! root 425: int d0, d1;
! 426: __asm__ __volatile__("cld\n\t"
1.1 root 427: "rep\n\t"
428: "stosb"
1.1.1.2 ! root 429: : "=&c" (d0), "=&D" (d1)
! 430: :"a" (c),"1" (s),"0" (count)
! 431: :"memory");
1.1 root 432: return s;
433: }
434:
435: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.