|
|
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: {
29: __asm__("cld\n"
30: "1:\tlodsb\n\t"
31: "stosb\n\t"
32: "testb %%al,%%al\n\t"
33: "jne 1b"
34: ::"S" (src),"D" (dest):"si","di","ax");
35: return dest;
36: }
37:
1.1.1.2 ! root 38: extern inline char * strncpy(char * dest,const char *src,size_t count)
1.1 root 39: {
40: __asm__("cld\n"
41: "1:\tdecl %2\n\t"
42: "js 2f\n\t"
43: "lodsb\n\t"
44: "stosb\n\t"
45: "testb %%al,%%al\n\t"
46: "jne 1b\n\t"
47: "rep\n\t"
48: "stosb\n"
49: "2:"
50: ::"S" (src),"D" (dest),"c" (count):"si","di","ax","cx");
51: return dest;
52: }
53:
54: extern inline char * strcat(char * dest,const char * src)
55: {
56: __asm__("cld\n\t"
57: "repne\n\t"
58: "scasb\n\t"
59: "decl %1\n"
60: "1:\tlodsb\n\t"
61: "stosb\n\t"
62: "testb %%al,%%al\n\t"
63: "jne 1b"
64: ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
65: return dest;
66: }
67:
1.1.1.2 ! root 68: extern inline char * strncat(char * dest,const char * src,size_t count)
1.1 root 69: {
70: __asm__("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: ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
84: :"si","di","ax","cx");
85: return dest;
86: }
87:
88: extern inline int strcmp(const char * cs,const char * ct)
89: {
90: register int __res __asm__("ax");
91: __asm__("cld\n"
92: "1:\tlodsb\n\t"
93: "scasb\n\t"
94: "jne 2f\n\t"
95: "testb %%al,%%al\n\t"
96: "jne 1b\n\t"
97: "xorl %%eax,%%eax\n\t"
98: "jmp 3f\n"
99: "2:\tmovl $1,%%eax\n\t"
100: "jl 3f\n\t"
101: "negl %%eax\n"
102: "3:"
103: :"=a" (__res):"D" (cs),"S" (ct):"si","di");
104: return __res;
105: }
106:
1.1.1.2 ! root 107: extern inline int strncmp(const char * cs,const char * ct,size_t count)
1.1 root 108: {
109: register int __res __asm__("ax");
110: __asm__("cld\n"
111: "1:\tdecl %3\n\t"
112: "js 2f\n\t"
113: "lodsb\n\t"
114: "scasb\n\t"
115: "jne 3f\n\t"
116: "testb %%al,%%al\n\t"
117: "jne 1b\n"
118: "2:\txorl %%eax,%%eax\n\t"
119: "jmp 4f\n"
120: "3:\tmovl $1,%%eax\n\t"
121: "jl 4f\n\t"
122: "negl %%eax\n"
123: "4:"
124: :"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");
125: return __res;
126: }
127:
128: extern inline char * strchr(const char * s,char c)
129: {
130: register char * __res __asm__("ax");
131: __asm__("cld\n\t"
132: "movb %%al,%%ah\n"
133: "1:\tlodsb\n\t"
134: "cmpb %%ah,%%al\n\t"
135: "je 2f\n\t"
136: "testb %%al,%%al\n\t"
137: "jne 1b\n\t"
138: "movl $1,%1\n"
139: "2:\tmovl %1,%0\n\t"
140: "decl %0"
141: :"=a" (__res):"S" (s),"0" (c):"si");
142: return __res;
143: }
144:
145: extern inline char * strrchr(const char * s,char c)
146: {
147: register char * __res __asm__("dx");
148: __asm__("cld\n\t"
149: "movb %%al,%%ah\n"
150: "1:\tlodsb\n\t"
151: "cmpb %%ah,%%al\n\t"
152: "jne 2f\n\t"
153: "movl %%esi,%0\n\t"
154: "decl %0\n"
155: "2:\ttestb %%al,%%al\n\t"
156: "jne 1b"
157: :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
158: return __res;
159: }
160:
1.1.1.2 ! root 161: extern inline size_t strspn(const char * cs, const char * ct)
1.1 root 162: {
163: register char * __res __asm__("si");
164: __asm__("cld\n\t"
165: "movl %4,%%edi\n\t"
166: "repne\n\t"
167: "scasb\n\t"
168: "notl %%ecx\n\t"
169: "decl %%ecx\n\t"
170: "movl %%ecx,%%edx\n"
171: "1:\tlodsb\n\t"
172: "testb %%al,%%al\n\t"
173: "je 2f\n\t"
174: "movl %4,%%edi\n\t"
175: "movl %%edx,%%ecx\n\t"
176: "repne\n\t"
177: "scasb\n\t"
178: "je 1b\n"
179: "2:\tdecl %0"
180: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
181: :"ax","cx","dx","di");
182: return __res-cs;
183: }
184:
1.1.1.2 ! root 185: extern inline size_t strcspn(const char * cs, const char * ct)
1.1 root 186: {
187: register char * __res __asm__("si");
188: __asm__("cld\n\t"
189: "movl %4,%%edi\n\t"
190: "repne\n\t"
191: "scasb\n\t"
192: "notl %%ecx\n\t"
193: "decl %%ecx\n\t"
194: "movl %%ecx,%%edx\n"
195: "1:\tlodsb\n\t"
196: "testb %%al,%%al\n\t"
197: "je 2f\n\t"
198: "movl %4,%%edi\n\t"
199: "movl %%edx,%%ecx\n\t"
200: "repne\n\t"
201: "scasb\n\t"
202: "jne 1b\n"
203: "2:\tdecl %0"
204: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
205: :"ax","cx","dx","di");
206: return __res-cs;
207: }
208:
209: extern inline char * strpbrk(const char * cs,const char * ct)
210: {
211: register char * __res __asm__("si");
212: __asm__("cld\n\t"
213: "movl %4,%%edi\n\t"
214: "repne\n\t"
215: "scasb\n\t"
216: "notl %%ecx\n\t"
217: "decl %%ecx\n\t"
218: "movl %%ecx,%%edx\n"
219: "1:\tlodsb\n\t"
220: "testb %%al,%%al\n\t"
221: "je 2f\n\t"
222: "movl %4,%%edi\n\t"
223: "movl %%edx,%%ecx\n\t"
224: "repne\n\t"
225: "scasb\n\t"
226: "jne 1b\n\t"
227: "decl %0\n\t"
228: "jmp 3f\n"
229: "2:\txorl %0,%0\n"
230: "3:"
231: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
232: :"ax","cx","dx","di");
233: return __res;
234: }
235:
236: extern inline char * strstr(const char * cs,const char * ct)
237: {
238: register char * __res __asm__("ax");
239: __asm__("cld\n\t" \
240: "movl %4,%%edi\n\t"
241: "repne\n\t"
242: "scasb\n\t"
243: "notl %%ecx\n\t"
244: "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
245: "movl %%ecx,%%edx\n"
246: "1:\tmovl %4,%%edi\n\t"
247: "movl %%esi,%%eax\n\t"
248: "movl %%edx,%%ecx\n\t"
249: "repe\n\t"
250: "cmpsb\n\t"
251: "je 2f\n\t" /* also works for empty string, see above */
252: "xchgl %%eax,%%esi\n\t"
253: "incl %%esi\n\t"
254: "cmpb $0,-1(%%eax)\n\t"
255: "jne 1b\n\t"
256: "xorl %%eax,%%eax\n\t"
257: "2:"
258: :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
259: :"cx","dx","di","si");
260: return __res;
261: }
262:
1.1.1.2 ! root 263: extern inline size_t strlen(const char * s)
1.1 root 264: {
265: register int __res __asm__("cx");
266: __asm__("cld\n\t"
267: "repne\n\t"
268: "scasb\n\t"
269: "notl %0\n\t"
270: "decl %0"
271: :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
272: return __res;
273: }
274:
275: extern char * ___strtok;
276:
277: extern inline char * strtok(char * s,const char * ct)
278: {
279: register char * __res __asm__("si");
280: __asm__("testl %1,%1\n\t"
281: "jne 1f\n\t"
282: "testl %0,%0\n\t"
283: "je 8f\n\t"
284: "movl %0,%1\n"
285: "1:\txorl %0,%0\n\t"
286: "movl $-1,%%ecx\n\t"
287: "xorl %%eax,%%eax\n\t"
288: "cld\n\t"
289: "movl %4,%%edi\n\t"
290: "repne\n\t"
291: "scasb\n\t"
292: "notl %%ecx\n\t"
293: "decl %%ecx\n\t"
294: "je 7f\n\t" /* empty delimeter-string */
295: "movl %%ecx,%%edx\n"
296: "2:\tlodsb\n\t"
297: "testb %%al,%%al\n\t"
298: "je 7f\n\t"
299: "movl %4,%%edi\n\t"
300: "movl %%edx,%%ecx\n\t"
301: "repne\n\t"
302: "scasb\n\t"
303: "je 2b\n\t"
304: "decl %1\n\t"
305: "cmpb $0,(%1)\n\t"
306: "je 7f\n\t"
307: "movl %1,%0\n"
308: "3:\tlodsb\n\t"
309: "testb %%al,%%al\n\t"
310: "je 5f\n\t"
311: "movl %4,%%edi\n\t"
312: "movl %%edx,%%ecx\n\t"
313: "repne\n\t"
314: "scasb\n\t"
315: "jne 3b\n\t"
316: "decl %1\n\t"
317: "cmpb $0,(%1)\n\t"
318: "je 5f\n\t"
319: "movb $0,(%1)\n\t"
320: "incl %1\n\t"
321: "jmp 6f\n"
322: "5:\txorl %1,%1\n"
323: "6:\tcmpb $0,(%0)\n\t"
324: "jne 7f\n\t"
325: "xorl %0,%0\n"
326: "7:\ttestl %0,%0\n\t"
327: "jne 8f\n\t"
328: "movl %0,%1\n"
329: "8:"
1.1.1.2 ! root 330: #if __GNUC__ == 2
! 331: :"=r" (__res)
! 332: #else
! 333: :"=b" (__res)
! 334: #endif
! 335: ,"=S" (___strtok)
1.1 root 336: :"0" (___strtok),"1" (s),"g" (ct)
337: :"ax","cx","dx","di");
338: return __res;
339: }
340:
1.1.1.2 ! root 341: extern inline void * memcpy(void * dest,const void * src, size_t n)
1.1 root 342: {
343: __asm__("cld\n\t"
344: "rep\n\t"
345: "movsb"
346: ::"c" (n),"S" (src),"D" (dest)
347: :"cx","si","di");
348: return dest;
349: }
350:
1.1.1.2 ! root 351: extern inline void * memmove(void * dest,const void * src, size_t n)
1.1 root 352: {
353: if (dest<src)
354: __asm__("cld\n\t"
355: "rep\n\t"
356: "movsb"
357: ::"c" (n),"S" (src),"D" (dest)
358: :"cx","si","di");
359: else
360: __asm__("std\n\t"
361: "rep\n\t"
1.1.1.2 ! root 362: "movsb\n\t"
! 363: "cld"
1.1 root 364: ::"c" (n),"S" (src+n-1),"D" (dest+n-1)
365: :"cx","si","di");
366: return dest;
367: }
368:
1.1.1.2 ! root 369: extern inline int memcmp(const void * cs,const void * ct,size_t count)
1.1 root 370: {
371: register int __res __asm__("ax");
372: __asm__("cld\n\t"
373: "repe\n\t"
374: "cmpsb\n\t"
375: "je 1f\n\t"
376: "movl $1,%%eax\n\t"
377: "jl 1f\n\t"
378: "negl %%eax\n"
379: "1:"
380: :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
381: :"si","di","cx");
382: return __res;
383: }
384:
1.1.1.2 ! root 385: extern inline void * memchr(const void * cs,char c,size_t count)
1.1 root 386: {
387: register void * __res __asm__("di");
388: if (!count)
389: return NULL;
390: __asm__("cld\n\t"
391: "repne\n\t"
392: "scasb\n\t"
393: "je 1f\n\t"
394: "movl $1,%0\n"
395: "1:\tdecl %0"
396: :"=D" (__res):"a" (c),"D" (cs),"c" (count)
397: :"cx");
398: return __res;
399: }
400:
1.1.1.2 ! root 401: extern inline void * memset(void * s,char c,size_t count)
1.1 root 402: {
403: __asm__("cld\n\t"
404: "rep\n\t"
405: "stosb"
406: ::"a" (c),"D" (s),"c" (count)
407: :"cx","di");
408: return s;
409: }
410:
411: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.