|
|
1.1 root 1: #ifndef _I386_STRING_I486_H_
2: #define _I386_STRING_I486_H_
3:
4: /*
5: * This string-include defines all string functions as inline
6: * functions. Use gcc. It also assumes ds=es=data space, this should be
7: * normal. Most of the string-functions are rather heavily hand-optimized,
8: * see especially strtok,strstr,str[c]spn. They should work, but are not
9: * very easy to understand. Everything is done entirely within the register
10: * set, making the functions fast and clean.
11: *
12: * Copyright (C) 1991, 1992 Linus Torvalds
13: * Revised and optimized for i486/pentium
14: * 1994/03/15 by Alberto Vignani/Davide Parodi @crf.it
15: *
16: * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down.
17: */
18:
19: #define __HAVE_ARCH_STRCPY
20: extern inline char * strcpy(char * dest,const char *src)
21: {
22: register char *tmp= (char *)dest;
23: register char dummy;
24: __asm__ __volatile__(
25: "\n1:\t"
26: "movb (%0),%b2\n\t"
27: "incl %0\n\t"
28: "movb %b2,(%1)\n\t"
29: "incl %1\n\t"
30: "testb %b2,%b2\n\t"
31: "jne 1b"
32: :"=r" (src), "=r" (tmp), "=q" (dummy)
33: :"0" (src), "1" (tmp)
34: :"memory");
35: return dest;
36: }
37:
38: #define __HAVE_ARCH_STRNCPY
39: extern inline char * strncpy(char * dest,const char *src,size_t count)
40: {
41: register char *tmp= (char *)dest;
42: register char dummy;
43: if (count) {
44: __asm__ __volatile__(
45: "\n1:\t"
46: "movb (%0),%b2\n\t"
47: "incl %0\n\t"
48: "movb %b2,(%1)\n\t"
49: "incl %1\n\t"
50: "decl %3\n\t"
51: "je 3f\n\t"
52: "testb %b2,%b2\n\t"
53: "jne 1b\n\t"
54: "2:\tmovb %b2,(%1)\n\t"
55: "incl %1\n\t"
56: "decl %3\n\t"
57: "jne 2b\n\t"
58: "3:"
59: :"=r" (src), "=r" (tmp), "=q" (dummy), "=r" (count)
60: :"0" (src), "1" (tmp), "3" (count)
61: :"memory");
62: } /* if (count) */
63: return dest;
64: }
65:
66: #define __HAVE_ARCH_STRCAT
67: extern inline char * strcat(char * dest,const char * src)
68: {
69: register char *tmp = (char *)(dest-1);
70: register char dummy;
71: __asm__ __volatile__(
72: "\n1:\tincl %1\n\t"
73: "cmpb $0,(%1)\n\t"
74: "jne 1b\n"
75: "2:\tmovb (%2),%b0\n\t"
76: "incl %2\n\t"
77: "movb %b0,(%1)\n\t"
78: "incl %1\n\t"
79: "testb %b0,%b0\n\t"
80: "jne 2b\n"
81: :"=q" (dummy), "=r" (tmp), "=r" (src)
82: :"1" (tmp), "2" (src)
83: :"memory");
84: return dest;
85: }
86:
87: #define __HAVE_ARCH_STRNCAT
88: extern inline char * strncat(char * dest,const char * src,size_t count)
89: {
90: register char *tmp = (char *)(dest-1);
91: register char dummy;
92: __asm__ __volatile__(
93: "\n1:\tincl %1\n\t"
94: "cmpb $0,(%1)\n\t"
95: "jne 1b\n"
96: "2:\tdecl %3\n\t"
97: "js 3f\n\t"
98: "movb (%2),%b0\n\t"
99: "incl %2\n\t"
100: "movb %b0,(%1)\n\t"
101: "incl %1\n\t"
102: "testb %b0,%b0\n\t"
103: "jne 2b\n"
104: "3:\txorb %b0,%b0\n\t"
105: "movb %b0,(%1)\n\t"
106: :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count)
107: :"1" (tmp), "2" (src), "3" (count)
108: :"memory");
109: return dest;
110: }
111:
112: #define __HAVE_ARCH_STRCMP
113: extern inline int strcmp(const char * cs,const char * ct)
114: {
115: register int __res;
116: __asm__ __volatile__(
117: "\n1:\tmovb (%1),%b0\n\t"
118: "incl %1\n\t"
119: "cmpb %b0,(%2)\n\t"
120: "jne 2f\n\t"
121: "incl %2\n\t"
122: "testb %b0,%b0\n\t"
123: "jne 1b\n\t"
124: "xorl %k0,%k0\n\t"
125: "jmp 3f\n"
126: "2:\tmovl $1,%k0\n\t"
127: "jb 3f\n\t"
128: "negl %k0\n"
129: "3:"
130: :"=q" (__res), "=r" (cs), "=r" (ct)
131: :"1" (cs), "2" (ct)
132: : "memory" );
133: return __res;
134: }
135:
136: #define __HAVE_ARCH_STRNCMP
137: extern inline int strncmp(const char * cs,const char * ct,size_t count)
138: {
139: register int __res;
140: __asm__ __volatile__(
141: "\n1:\tdecl %3\n\t"
142: "js 2f\n\t"
143: "movb (%1),%b0\n\t"
144: "incl %1\n\t"
145: "cmpb %b0,(%2)\n\t"
146: "jne 3f\n\t"
147: "incl %2\n\t"
148: "testb %b0,%b0\n\t"
149: "jne 1b\n"
150: "2:\txorl %k0,%k0\n\t"
151: "jmp 4f\n"
152: "3:\tmovl $1,%k0\n\t"
153: "jb 4f\n\t"
154: "negl %k0\n"
155: "4:"
156: :"=q" (__res), "=r" (cs), "=r" (ct), "=r" (count)
157: :"1" (cs), "2" (ct), "3" (count));
158: return __res;
159: }
160:
161: #define __HAVE_ARCH_STRCHR
162: extern inline char * strchr(const char * s, int c)
163: {
164: register char * __res;
165: __asm__ __volatile__(
166: "movb %%al,%%ah\n"
167: "1:\tmovb (%1),%%al\n\t"
168: "cmpb %%ah,%%al\n\t"
169: "je 2f\n\t"
170: "incl %1\n\t"
171: "testb %%al,%%al\n\t"
172: "jne 1b\n\t"
173: "xorl %1,%1\n"
174: "2:\tmovl %1,%0\n\t"
175: :"=a" (__res), "=r" (s)
176: :"0" (c), "1" (s));
177: return __res;
178: }
179:
180: #define __HAVE_ARCH_STRRCHR
181: extern inline char * strrchr(const char * s, int c)
182: {
183: register char * __res;
184: __asm__ __volatile__(
185: "cld\n\t"
186: "movb %%al,%%ah\n"
187: "1:\tlodsb\n\t"
188: "cmpb %%ah,%%al\n\t"
189: "jne 2f\n\t"
190: "leal -1(%%esi),%0\n"
191: "2:\ttestb %%al,%%al\n\t"
192: "jne 1b"
193: :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
194: return __res;
195: }
196:
197: #define __HAVE_ARCH_STRSPN
198: extern inline size_t strspn(const char * cs, const char * ct)
199: {
200: register char * __res;
201: __asm__ __volatile__(
202: "cld\n\t"
203: "movl %4,%%edi\n\t"
204: "repne\n\t"
205: "scasb\n\t"
206: "notl %%ecx\n\t"
207: "decl %%ecx\n\t"
208: "movl %%ecx,%%edx\n"
209: "1:\tlodsb\n\t"
210: "testb %%al,%%al\n\t"
211: "je 2f\n\t"
212: "movl %4,%%edi\n\t"
213: "movl %%edx,%%ecx\n\t"
214: "repne\n\t"
215: "scasb\n\t"
216: "je 1b\n"
217: "2:\tdecl %0"
218: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
219: :"ax","cx","dx","di");
220: return __res-cs;
221: }
222:
223: #define __HAVE_ARCH_STRCSPN
224: extern inline size_t strcspn(const char * cs, const char * ct)
225: {
226: register char * __res;
227: __asm__ __volatile__(
228: "cld\n\t"
229: "movl %4,%%edi\n\t"
230: "repne\n\t"
231: "scasb\n\t"
232: "notl %%ecx\n\t"
233: "decl %%ecx\n\t"
234: "movl %%ecx,%%edx\n"
235: "1:\tlodsb\n\t"
236: "testb %%al,%%al\n\t"
237: "je 2f\n\t"
238: "movl %4,%%edi\n\t"
239: "movl %%edx,%%ecx\n\t"
240: "repne\n\t"
241: "scasb\n\t"
242: "jne 1b\n"
243: "2:\tdecl %0"
244: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
245: :"ax","cx","dx","di");
246: return __res-cs;
247: }
248:
249: #define __HAVE_ARCH_STRPBRK
250: extern inline char * strpbrk(const char * cs,const char * ct)
251: {
252: register char * __res;
253: __asm__ __volatile__(
254: "cld\n\t"
255: "movl %4,%%edi\n\t"
256: "repne\n\t"
257: "scasb\n\t"
258: "notl %%ecx\n\t"
259: "decl %%ecx\n\t"
260: "movl %%ecx,%%edx\n"
261: "1:\tlodsb\n\t"
262: "testb %%al,%%al\n\t"
263: "je 2f\n\t"
264: "movl %4,%%edi\n\t"
265: "movl %%edx,%%ecx\n\t"
266: "repne\n\t"
267: "scasb\n\t"
268: "jne 1b\n\t"
269: "decl %0\n\t"
270: "jmp 3f\n"
271: "2:\txorl %0,%0\n"
272: "3:"
273: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
274: :"ax","cx","dx","di");
275: return __res;
276: }
277:
278: #define __HAVE_ARCH_STRSTR
279: extern inline char * strstr(const char * cs,const char * ct)
280: {
281: register char * __res;
282: __asm__ __volatile__(
283: "cld\n\t" \
284: "movl %4,%%edi\n\t"
285: "repne\n\t"
286: "scasb\n\t"
287: "notl %%ecx\n\t"
288: "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
289: "movl %%ecx,%%edx\n"
290: "1:\tmovl %4,%%edi\n\t"
291: "movl %%esi,%%eax\n\t"
292: "movl %%edx,%%ecx\n\t"
293: "repe\n\t"
294: "cmpsb\n\t"
295: "je 2f\n\t" /* also works for empty string, see above */
296: "xchgl %%eax,%%esi\n\t"
297: "incl %%esi\n\t"
298: "cmpb $0,-1(%%eax)\n\t"
299: "jne 1b\n\t"
300: "xorl %%eax,%%eax\n\t"
301: "2:"
302: :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
303: :"cx","dx","di","si");
304: return __res;
305: }
306:
307: #define __HAVE_ARCH_STRLEN
308: extern inline size_t strlen(const char * s)
309: {
310: /*
311: * slightly slower on a 486, but with better chances of
312: * register allocation
313: */
314: register char dummy, *tmp= (char *)s;
315: __asm__ __volatile__(
316: "\n1:\t"
317: "movb\t(%0),%1\n\t"
318: "incl\t%0\n\t"
319: "testb\t%1,%1\n\t"
320: "jne\t1b"
321: :"=r" (tmp),"=q" (dummy)
322: :"0" (s)
323: : "memory" );
324: return (tmp-s-1);
325: }
326:
327: /* Added by Gertjan van Wingerde to make minix and sysv module work */
328: #define __HAVE_ARCH_STRNLEN
329: extern inline size_t strnlen(const char * s, size_t count)
330: {
331: register int __res;
332: __asm__ __volatile__(
333: "movl %1,%0\n\t"
334: "jmp 2f\n"
335: "1:\tcmpb $0,(%0)\n\t"
336: "je 3f\n\t"
337: "incl %0\n"
338: "2:\tdecl %2\n\t"
339: "cmpl $-1,%2\n\t"
340: "jne 1b\n"
341: "3:\tsubl %1,%0"
342: :"=a" (__res)
343: :"c" (s),"d" (count)
344: :"dx");
345: return __res;
346: }
347: /* end of additional stuff */
348:
349: #define __HAVE_ARCH_STRTOK
350: extern inline char * strtok(char * s,const char * ct)
351: {
352: register char * __res;
353: __asm__ __volatile__(
354: "testl %1,%1\n\t"
355: "jne 1f\n\t"
356: "testl %0,%0\n\t"
357: "je 8f\n\t"
358: "movl %0,%1\n"
359: "1:\txorl %0,%0\n\t"
360: "movl $-1,%%ecx\n\t"
361: "xorl %%eax,%%eax\n\t"
362: "cld\n\t"
363: "movl %4,%%edi\n\t"
364: "repne\n\t"
365: "scasb\n\t"
366: "notl %%ecx\n\t"
367: "decl %%ecx\n\t"
368: "je 7f\n\t" /* empty delimiter-string */
369: "movl %%ecx,%%edx\n"
370: "2:\tlodsb\n\t"
371: "testb %%al,%%al\n\t"
372: "je 7f\n\t"
373: "movl %4,%%edi\n\t"
374: "movl %%edx,%%ecx\n\t"
375: "repne\n\t"
376: "scasb\n\t"
377: "je 2b\n\t"
378: "decl %1\n\t"
379: "cmpb $0,(%1)\n\t"
380: "je 7f\n\t"
381: "movl %1,%0\n"
382: "3:\tlodsb\n\t"
383: "testb %%al,%%al\n\t"
384: "je 5f\n\t"
385: "movl %4,%%edi\n\t"
386: "movl %%edx,%%ecx\n\t"
387: "repne\n\t"
388: "scasb\n\t"
389: "jne 3b\n\t"
390: "decl %1\n\t"
391: "cmpb $0,(%1)\n\t"
392: "je 5f\n\t"
393: "movb $0,(%1)\n\t"
394: "incl %1\n\t"
395: "jmp 6f\n"
396: "5:\txorl %1,%1\n"
397: "6:\tcmpb $0,(%0)\n\t"
398: "jne 7f\n\t"
399: "xorl %0,%0\n"
400: "7:\ttestl %0,%0\n\t"
401: "jne 8f\n\t"
402: "movl %0,%1\n"
403: "8:"
404: :"=b" (__res),"=S" (___strtok)
405: :"0" (___strtok),"1" (s),"g" (ct)
406: :"ax","cx","dx","di","memory");
407: return __res;
408: }
409:
410: #define __memcpy_c(d,s,count) \
411: ((count%4==0) ? \
412: __memcpy_by4((d),(s),(count)) : \
413: ((count%2==0) ? \
414: __memcpy_by2((d),(s),(count)) : \
415: __memcpy_g((d),(s),(count))))
416:
417: #define __HAVE_ARCH_MEMCPY
418: #define memcpy(d,s,count) \
419: (count == 0 \
420: ? d \
421: : __builtin_constant_p(count) \
422: ? __memcpy_c((d),(s),(count)) \
423: : __memcpy_g((d),(s),(count)))
424:
425: /*
426: * These ought to get tweaked to do some cache priming.
427: */
428:
429: extern inline void * __memcpy_by4(void * to, const void * from, size_t n)
430: {
431: register void *tmp = (void *)to;
432: register int dummy1,dummy2;
433: __asm__ __volatile__ (
434: "\n1:\tmovl (%2),%0\n\t"
435: "addl $4,%2\n\t"
436: "movl %0,(%1)\n\t"
437: "addl $4,%1\n\t"
438: "decl %3\n\t"
439: "jnz 1b"
440: :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2)
441: :"1" (tmp), "2" (from), "3" (n/4)
442: :"memory");
443: return to;
444: }
445:
446: extern inline void * __memcpy_by2(void * to, const void * from, size_t n)
447: {
448: register void *tmp = (void *)to;
449: register int dummy1,dummy2;
450: __asm__ __volatile__ (
451: "shrl $1,%3\n\t"
452: "jz 2f\n" /* only a word */
453: "1:\tmovl (%2),%0\n\t"
454: "addl $4,%2\n\t"
455: "movl %0,(%1)\n\t"
456: "addl $4,%1\n\t"
457: "decl %3\n\t"
458: "jnz 1b\n"
459: "2:\tmovw (%2),%w0\n\t"
460: "movw %w0,(%1)"
461: :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2)
462: :"1" (tmp), "2" (from), "3" (n/2)
463: :"memory");
464: return to;
465: }
466:
467: extern inline void * __memcpy_g(void * to, const void * from, size_t n)
468: {
469: register void *tmp = (void *)to;
470: __asm__ __volatile__ (
471: "cld\n\t"
472: "shrl $1,%%ecx\n\t"
473: "jnc 1f\n\t"
474: "movsb\n"
475: "1:\tshrl $1,%%ecx\n\t"
476: "jnc 2f\n\t"
477: "movsw\n"
478: "2:\trep\n\t"
479: "movsl"
480: : /* no output */
481: :"c" (n),"D" ((long) tmp),"S" ((long) from)
482: :"cx","di","si","memory");
483: return to;
484: }
485:
486:
487: #define __HAVE_ARCH_MEMMOVE
488: extern inline void * memmove(void * dest,const void * src, size_t n)
489: {
490: register void *tmp = (void *)dest;
491: if (dest<src)
492: __asm__ __volatile__ (
493: "cld\n\t"
494: "rep\n\t"
495: "movsb"
496: : /* no output */
497: :"c" (n),"S" (src),"D" (tmp)
498: :"cx","si","di");
499: else
500: __asm__ __volatile__ (
501: "std\n\t"
502: "rep\n\t"
503: "movsb\n\t"
504: "cld\n\t"
505: : /* no output */
506: :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp)
507: :"cx","si","di","memory");
508: return dest;
509: }
510:
511: extern inline int memcmp(const void * cs,const void * ct,size_t count)
512: {
513: register int __res;
514: __asm__ __volatile__(
515: "cld\n\t"
516: "repe\n\t"
517: "cmpsb\n\t"
518: "je 1f\n\t"
519: "sbbl %0,%0\n\t"
520: "orb $1,%b0\n"
521: "1:"
522: :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
523: :"si","di","cx");
524: return __res;
525: }
526:
527: #define __HAVE_ARCH_MEMCHR
528: extern inline void * memchr(const void * cs,int c,size_t count)
529: {
530: register void * __res;
531: if (!count)
532: return NULL;
533: __asm__ __volatile__(
534: "cld\n\t"
535: "repne\n\t"
536: "scasb\n\t"
537: "je 1f\n\t"
538: "movl $1,%0\n"
539: "1:\tdecl %0"
540: :"=D" (__res):"a" (c),"D" (cs),"c" (count)
541: :"cx");
542: return __res;
543: }
544:
545: #define __memset_cc(s,c,count) \
546: ((count%4==0) ? \
547: __memset_cc_by4((s),(c),(count)) : \
548: ((count%2==0) ? \
549: __memset_cc_by2((s),(c),(count)) : \
550: __memset_cg((s),(c),(count))))
551:
552: #define __memset_gc(s,c,count) \
553: ((count%4==0) ? \
554: __memset_gc_by4((s),(c),(count)) : \
555: ((count%2==0) ? \
556: __memset_gc_by2((s),(c),(count)) : \
557: __memset_gg((s),(c),(count))))
558:
559: #define __HAVE_ARCH_MEMSET
560: #define memset(s,c,count) \
561: (count == 0 \
562: ? s \
563: : __builtin_constant_p(c) \
564: ? __builtin_constant_p(count) \
565: ? __memset_cc((s),(c),(count)) \
566: : __memset_cg((s),(c),(count)) \
567: : __builtin_constant_p(count) \
568: ? __memset_gc((s),(c),(count)) \
569: : __memset_gg((s),(c),(count)))
570:
571: extern inline void * __memset_cc_by4(void * s, char c, size_t count)
572: {
573: /*
574: * register char *tmp = s;
575: */
576: register char *tmp = (char *)s;
577: register int dummy;
578: __asm__ __volatile__ (
579: "\n1:\tmovl %2,(%0)\n\t"
580: "addl $4,%0\n\t"
581: "decl %1\n\t"
582: "jnz 1b"
583: :"=r" (tmp), "=r" (dummy)
584: :"r" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/4)
585: :"memory");
586: return s;
587: }
588:
589: extern inline void * __memset_cc_by2(void * s, char c, size_t count)
590: {
591: register void *tmp = (void *)s;
592: register int dummy;
593: __asm__ __volatile__ (
594: "shrl $1,%1\n\t" /* may be divisible also by 4 */
595: "jz 2f\n"
596: "\n1:\tmovl %2,(%0)\n\t"
597: "addl $4,%0\n\t"
598: "decl %1\n\t"
599: "jnz 1b\n"
600: "2:\tmovw %w2,(%0)"
601: :"=r" (tmp), "=r" (dummy)
602: :"r" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/2)
603: :"memory");
604: return s;
605: }
606:
607: extern inline void * __memset_gc_by4(void * s, char c, size_t count)
608: {
609: register void *tmp = (void *)s;
610: register int dummy;
611: __asm__ __volatile__ (
612: "movb %b0,%h0\n"
613: "pushw %w0\n\t"
614: "shll $16,%k0\n\t"
615: "popw %w0\n"
616: "1:\tmovl %k0,(%1)\n\t"
617: "addl $4,%1\n\t"
618: "decl %2\n\t"
619: "jnz 1b\n"
620: :"=q" (c), "=r" (tmp), "=r" (dummy)
621: :"0" ((unsigned) c), "1" (tmp), "2" (count/4)
622: :"memory");
623: return s;
624: }
625:
626: extern inline void * __memset_gc_by2(void * s, char c, size_t count)
627: {
628: register void *tmp = (void *)s;
629: register int dummy1,dummy2;
630: __asm__ __volatile__ (
631: "movb %b0,%h0\n\t"
632: "shrl $1,%2\n\t" /* may be divisible also by 4 */
633: "jz 2f\n\t"
634: "pushw %w0\n\t"
635: "shll $16,%k0\n\t"
636: "popw %w0\n"
637: "1:\tmovl %k0,(%1)\n\t"
638: "addl $4,%1\n\t"
639: "decl %2\n\t"
640: "jnz 1b\n"
641: "2:\tmovw %w0,(%1)"
642: :"=q" (dummy1), "=r" (tmp), "=r" (dummy2)
643: :"0" ((unsigned) c), "1" (tmp), "2" (count/2)
644: :"memory");
645: return s;
646: }
647:
648: extern inline void * __memset_cg(void * s, char c, size_t count)
649: {
650: register void *tmp = (void *)s;
651: __asm__ __volatile__ (
652: "shrl $1,%%ecx\n\t"
653: "cld\n\t"
654: "rep\n\t"
655: "stosw\n\t"
656: "jnc 1f\n\t"
657: "movb %%al,(%%edi)\n"
658: "1:"
659: : /* no output */
660: :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c)
661: :"cx","di","memory");
662: return s;
663: }
664:
665: extern inline void * __memset_gg(void * s,char c,size_t count)
666: {
667: register void *tmp = (void *)s;
668: __asm__ __volatile__ (
669: "movb %%al,%%ah\n\t"
670: "shrl $1,%%ecx\n\t"
671: "cld\n\t"
672: "rep\n\t"
673: "stosw\n\t"
674: "jnc 1f\n\t"
675: "movb %%al,(%%edi)\n"
676: "1:"
677: : /* no output */
678: :"c" (count),"D" (tmp), "a" (c)
679: :"cx","di","memory");
680: return s;
681: }
682:
683:
684: /*
685: * find the first occurrence of byte 'c', or 1 past the area if none
686: */
687: #define __HAVE_ARCH_MEMSCAN
688: extern inline void * memscan(void * addr, int c, size_t size)
689: {
690: if (!size)
691: return addr;
692: __asm__("cld
693: repnz; scasb
694: jnz 1f
695: dec %%edi
696: 1: "
697: : "=D" (addr), "=c" (size)
698: : "0" (addr), "1" (size), "a" (c));
699: return addr;
700: }
701:
702: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.