Remove building with NOCRYPTO option
[minix3.git] / lib / libc / gdtoa / misc.c
blob9f3d4c008d2c51c86c417da633a588b50e632b13
1 /* $NetBSD: misc.c,v 1.11 2011/11/21 09:46:19 mlelstv Exp $ */
3 /****************************************************************
5 The author of this software is David M. Gay.
7 Copyright (C) 1998, 1999 by Lucent Technologies
8 All Rights Reserved
10 Permission to use, copy, modify, and distribute this software and
11 its documentation for any purpose and without fee is hereby
12 granted, provided that the above copyright notice appear in all
13 copies and that both that the copyright notice and this
14 permission notice and warranty disclaimer appear in supporting
15 documentation, and that the name of Lucent or any of its entities
16 not be used in advertising or publicity pertaining to
17 distribution of the software without specific, written prior
18 permission.
20 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
21 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
22 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
23 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
24 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
25 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
26 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
27 THIS SOFTWARE.
29 ****************************************************************/
31 /* Please send bug reports to David M. Gay (dmg at acm dot org,
32 * with " at " changed at "@" and " dot " changed to "."). */
34 #include "gdtoaimp.h"
36 static Bigint *freelist[Kmax+1];
37 #ifndef Omit_Private_Memory
38 #ifndef PRIVATE_MEM
39 #define PRIVATE_MEM 2304
40 #endif
41 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
42 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
43 #endif
45 Bigint *
46 Balloc
47 #ifdef KR_headers
48 (k) int k;
49 #else
50 (int k)
51 #endif
53 int x;
54 Bigint *rv;
55 #ifndef Omit_Private_Memory
56 size_t len;
57 #endif
59 ACQUIRE_DTOA_LOCK(0);
60 /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */
61 /* but this case seems very unlikely. */
62 if ((size_t)k <= Kmax && (rv = freelist[k]) !=0) {
63 freelist[k] = rv->next;
65 else {
66 x = 1 << k;
67 #ifdef Omit_Private_Memory
68 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
69 #else
70 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
71 /sizeof(double);
72 if ((size_t)k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
73 rv = (Bigint*)(void *)pmem_next;
74 pmem_next += len;
76 else
77 rv = (Bigint*)MALLOC(len*sizeof(double));
78 #endif
79 if (rv == NULL) {
80 FREE_DTOA_LOCK(0);
81 return NULL;
83 rv->k = k;
84 rv->maxwds = x;
86 FREE_DTOA_LOCK(0);
87 rv->sign = rv->wds = 0;
88 return rv;
91 void
92 Bfree
93 #ifdef KR_headers
94 (v) Bigint *v;
95 #else
96 (Bigint *v)
97 #endif
99 if (v) {
100 if ((size_t)v->k > Kmax)
101 #ifdef FREE
102 FREE((void*)v);
103 #else
104 free((void*)v);
105 #endif
106 else {
107 ACQUIRE_DTOA_LOCK(0);
108 v->next = freelist[v->k];
109 freelist[v->k] = v;
110 FREE_DTOA_LOCK(0);
116 lo0bits
117 #ifdef KR_headers
118 (y) ULong *y;
119 #else
120 (ULong *y)
121 #endif
123 int k;
124 ULong x = *y;
126 if (x & 7) {
127 if (x & 1)
128 return 0;
129 if (x & 2) {
130 *y = x >> 1;
131 return 1;
133 *y = x >> 2;
134 return 2;
136 k = 0;
137 if (!(x & 0xffff)) {
138 k = 16;
139 x >>= 16;
141 if (!(x & 0xff)) {
142 k += 8;
143 x >>= 8;
145 if (!(x & 0xf)) {
146 k += 4;
147 x >>= 4;
149 if (!(x & 0x3)) {
150 k += 2;
151 x >>= 2;
153 if (!(x & 1)) {
154 k++;
155 x >>= 1;
156 if (!x)
157 return 32;
159 *y = x;
160 return k;
163 Bigint *
164 multadd
165 #ifdef KR_headers
166 (b, m, a) Bigint *b; int m, a;
167 #else
168 (Bigint *b, int m, int a) /* multiply by m and add a */
169 #endif
171 int i, wds;
172 #ifdef ULLong
173 ULong *x;
174 ULLong carry, y;
175 #else
176 ULong carry, *x, y;
177 #ifdef Pack_32
178 ULong xi, z;
179 #endif
180 #endif
181 Bigint *b1;
183 wds = b->wds;
184 x = b->x;
185 i = 0;
186 carry = a;
187 do {
188 #ifdef ULLong
189 y = *x * (ULLong)m + carry;
190 carry = y >> 32;
191 /* LINTED conversion */
192 *x++ = y & 0xffffffffUL;
193 #else
194 #ifdef Pack_32
195 xi = *x;
196 y = (xi & 0xffff) * m + carry;
197 z = (xi >> 16) * m + (y >> 16);
198 carry = z >> 16;
199 *x++ = (z << 16) + (y & 0xffff);
200 #else
201 y = *x * m + carry;
202 carry = y >> 16;
203 *x++ = y & 0xffff;
204 #endif
205 #endif
207 while(++i < wds);
208 if (carry) {
209 if (wds >= b->maxwds) {
210 b1 = Balloc(b->k+1);
211 if (b1 == NULL) {
212 Bfree(b);
213 return NULL;
215 Bcopy(b1, b);
216 Bfree(b);
217 b = b1;
219 /* LINTED conversion */
220 b->x[wds++] = carry;
221 b->wds = wds;
223 return b;
227 hi0bits_D2A
228 #ifdef KR_headers
229 (x) ULong x;
230 #else
231 (ULong x)
232 #endif
234 int k = 0;
236 if (!(x & 0xffff0000)) {
237 k = 16;
238 x <<= 16;
240 if (!(x & 0xff000000)) {
241 k += 8;
242 x <<= 8;
244 if (!(x & 0xf0000000)) {
245 k += 4;
246 x <<= 4;
248 if (!(x & 0xc0000000)) {
249 k += 2;
250 x <<= 2;
252 if (!(x & 0x80000000)) {
253 k++;
254 if (!(x & 0x40000000))
255 return 32;
257 return k;
260 Bigint *
262 #ifdef KR_headers
263 (i) int i;
264 #else
265 (int i)
266 #endif
268 Bigint *b;
270 b = Balloc(1);
271 if (b == NULL)
272 return NULL;
273 b->x[0] = i;
274 b->wds = 1;
275 return b;
278 Bigint *
279 mult
280 #ifdef KR_headers
281 (a, b) Bigint *a, *b;
282 #else
283 (Bigint *a, Bigint *b)
284 #endif
286 Bigint *c;
287 int k, wa, wb, wc;
288 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
289 ULong y;
290 #ifdef ULLong
291 ULLong carry, z;
292 #else
293 ULong carry, z;
294 #ifdef Pack_32
295 ULong z2;
296 #endif
297 #endif
299 if (a->wds < b->wds) {
300 c = a;
301 a = b;
302 b = c;
304 k = a->k;
305 wa = a->wds;
306 wb = b->wds;
307 wc = wa + wb;
308 if (wc > a->maxwds)
309 k++;
310 c = Balloc(k);
311 if (c == NULL)
312 return NULL;
313 for(x = c->x, xa = x + wc; x < xa; x++)
314 *x = 0;
315 xa = a->x;
316 xae = xa + wa;
317 xb = b->x;
318 xbe = xb + wb;
319 xc0 = c->x;
320 #ifdef ULLong
321 for(; xb < xbe; xc0++) {
322 if ( (y = *xb++) !=0) {
323 x = xa;
324 xc = xc0;
325 carry = 0;
326 do {
327 z = *x++ * (ULLong)y + *xc + carry;
328 carry = z >> 32;
329 /* LINTED conversion */
330 *xc++ = z & 0xffffffffUL;
332 while(x < xae);
333 /* LINTED conversion */
334 *xc = carry;
337 #else
338 #ifdef Pack_32
339 for(; xb < xbe; xb++, xc0++) {
340 if ( (y = *xb & 0xffff) !=0) {
341 x = xa;
342 xc = xc0;
343 carry = 0;
344 do {
345 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
346 carry = z >> 16;
347 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
348 carry = z2 >> 16;
349 Storeinc(xc, z2, z);
351 while(x < xae);
352 *xc = carry;
354 if ( (y = *xb >> 16) !=0) {
355 x = xa;
356 xc = xc0;
357 carry = 0;
358 z2 = *xc;
359 do {
360 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
361 carry = z >> 16;
362 Storeinc(xc, z, z2);
363 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
364 carry = z2 >> 16;
366 while(x < xae);
367 *xc = z2;
370 #else
371 for(; xb < xbe; xc0++) {
372 if ( (y = *xb++) !=0) {
373 x = xa;
374 xc = xc0;
375 carry = 0;
376 do {
377 z = *x++ * y + *xc + carry;
378 carry = z >> 16;
379 *xc++ = z & 0xffff;
381 while(x < xae);
382 *xc = carry;
385 #endif
386 #endif
387 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
388 c->wds = wc;
389 return c;
392 static Bigint *p5s;
394 Bigint *
395 pow5mult
396 #ifdef KR_headers
397 (b, k) Bigint *b; int k;
398 #else
399 (Bigint *b, int k)
400 #endif
402 Bigint *b1, *p5, *p51;
403 int i;
404 static CONST int p05[3] = { 5, 25, 125 };
406 if ( (i = k & 3) !=0) {
407 b = multadd(b, p05[i-1], 0);
408 if (b == NULL)
409 return NULL;
412 if (!(k = (unsigned int)k >> 2))
413 return b;
414 if ((p5 = p5s) == 0) {
415 /* first time */
416 #ifdef MULTIPLE_THREADS
417 ACQUIRE_DTOA_LOCK(1);
418 if (!(p5 = p5s)) {
419 p5 = p5s = i2b(625);
420 if (p5 == NULL) {
421 FREE_DTOA_LOCK(1);
422 return NULL;
424 p5->next = 0;
426 FREE_DTOA_LOCK(1);
427 #else
428 p5 = p5s = i2b(625);
429 if (p5 == NULL)
430 return NULL;
431 p5->next = 0;
432 #endif
434 for(;;) {
435 if (k & 1) {
436 b1 = mult(b, p5);
437 if (b1 == NULL)
438 return NULL;
439 Bfree(b);
440 b = b1;
442 if (!(k = (unsigned int)k >> 1))
443 break;
444 if ((p51 = p5->next) == 0) {
445 #ifdef MULTIPLE_THREADS
446 ACQUIRE_DTOA_LOCK(1);
447 if (!(p51 = p5->next)) {
448 p51 = p5->next = mult(p5,p5);
449 if (p51 == NULL) {
450 FREE_DTOA_LOCK(1);
451 return NULL;
453 p51->next = 0;
455 FREE_DTOA_LOCK(1);
456 #else
457 p51 = p5->next = mult(p5,p5);
458 if (p51 == NULL)
459 return NULL;
460 p51->next = 0;
461 #endif
463 p5 = p51;
465 return b;
468 Bigint *
469 lshift
470 #ifdef KR_headers
471 (b, k) Bigint *b; int k;
472 #else
473 (Bigint *b, int k)
474 #endif
476 int i, k1, n, n1;
477 Bigint *b1;
478 ULong *x, *x1, *xe, z;
480 n = (unsigned int)k >> kshift;
481 k1 = b->k;
482 n1 = n + b->wds + 1;
483 for(i = b->maxwds; n1 > i; i <<= 1)
484 k1++;
485 b1 = Balloc(k1);
486 if (b1 == NULL)
487 return NULL;
488 x1 = b1->x;
489 for(i = 0; i < n; i++)
490 *x1++ = 0;
491 x = b->x;
492 xe = x + b->wds;
493 if (k &= kmask) {
494 #ifdef Pack_32
495 k1 = 32 - k;
496 z = 0;
497 do {
498 *x1++ = *x << k | z;
499 z = *x++ >> k1;
501 while(x < xe);
502 if ((*x1 = z) !=0)
503 ++n1;
504 #else
505 k1 = 16 - k;
506 z = 0;
507 do {
508 *x1++ = *x << k & 0xffff | z;
509 z = *x++ >> k1;
511 while(x < xe);
512 if (*x1 = z)
513 ++n1;
514 #endif
516 else do
517 *x1++ = *x++;
518 while(x < xe);
519 b1->wds = n1 - 1;
520 Bfree(b);
521 return b1;
526 #ifdef KR_headers
527 (a, b) Bigint *a, *b;
528 #else
529 (Bigint *a, Bigint *b)
530 #endif
532 ULong *xa, *xa0, *xb, *xb0;
533 int i, j;
535 i = a->wds;
536 j = b->wds;
537 #ifdef DEBUG
538 if (i > 1 && !a->x[i-1])
539 Bug("cmp called with a->x[a->wds-1] == 0");
540 if (j > 1 && !b->x[j-1])
541 Bug("cmp called with b->x[b->wds-1] == 0");
542 #endif
543 if (i -= j)
544 return i;
545 xa0 = a->x;
546 xa = xa0 + j;
547 xb0 = b->x;
548 xb = xb0 + j;
549 for(;;) {
550 if (*--xa != *--xb)
551 return *xa < *xb ? -1 : 1;
552 if (xa <= xa0)
553 break;
555 return 0;
558 Bigint *
559 diff
560 #ifdef KR_headers
561 (a, b) Bigint *a, *b;
562 #else
563 (Bigint *a, Bigint *b)
564 #endif
566 Bigint *c;
567 int i, wa, wb;
568 ULong *xa, *xae, *xb, *xbe, *xc;
569 #ifdef ULLong
570 ULLong borrow, y;
571 #else
572 ULong borrow, y;
573 #ifdef Pack_32
574 ULong z;
575 #endif
576 #endif
578 i = cmp(a,b);
579 if (!i) {
580 c = Balloc(0);
581 if (c == NULL)
582 return NULL;
583 c->wds = 1;
584 c->x[0] = 0;
585 return c;
587 if (i < 0) {
588 c = a;
589 a = b;
590 b = c;
591 i = 1;
593 else
594 i = 0;
595 c = Balloc(a->k);
596 if (c == NULL)
597 return NULL;
598 c->sign = i;
599 wa = a->wds;
600 xa = a->x;
601 xae = xa + wa;
602 wb = b->wds;
603 xb = b->x;
604 xbe = xb + wb;
605 xc = c->x;
606 borrow = 0;
607 #ifdef ULLong
608 do {
609 y = (ULLong)*xa++ - *xb++ - borrow;
610 borrow = y >> 32 & 1UL;
611 /* LINTED conversion */
612 *xc++ = y & 0xffffffffUL;
614 while(xb < xbe);
615 while(xa < xae) {
616 y = *xa++ - borrow;
617 borrow = y >> 32 & 1UL;
618 /* LINTED conversion */
619 *xc++ = y & 0xffffffffUL;
621 #else
622 #ifdef Pack_32
623 do {
624 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
625 borrow = (y & 0x10000) >> 16;
626 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
627 borrow = (z & 0x10000) >> 16;
628 Storeinc(xc, z, y);
630 while(xb < xbe);
631 while(xa < xae) {
632 y = (*xa & 0xffff) - borrow;
633 borrow = (y & 0x10000) >> 16;
634 z = (*xa++ >> 16) - borrow;
635 borrow = (z & 0x10000) >> 16;
636 Storeinc(xc, z, y);
638 #else
639 do {
640 y = *xa++ - *xb++ - borrow;
641 borrow = (y & 0x10000) >> 16;
642 *xc++ = y & 0xffff;
644 while(xb < xbe);
645 while(xa < xae) {
646 y = *xa++ - borrow;
647 borrow = (y & 0x10000) >> 16;
648 *xc++ = y & 0xffff;
650 #endif
651 #endif
652 while(!*--xc)
653 wa--;
654 c->wds = wa;
655 return c;
658 double
660 #ifdef KR_headers
661 (a, e) Bigint *a; int *e;
662 #else
663 (Bigint *a, int *e)
664 #endif
666 ULong *xa, *xa0, w, y, z;
667 int k;
668 U d;
669 #ifdef VAX
670 ULong d0, d1;
671 #else
672 #define d0 word0(&d)
673 #define d1 word1(&d)
674 #endif
676 xa0 = a->x;
677 xa = xa0 + a->wds;
678 y = *--xa;
679 #ifdef DEBUG
680 if (!y) Bug("zero y in b2d");
681 #endif
682 k = hi0bits(y);
683 *e = 32 - k;
684 #ifdef Pack_32
685 if (k < Ebits) {
686 d0 = Exp_1 | y >> (Ebits - k);
687 w = xa > xa0 ? *--xa : 0;
688 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
689 goto ret_d;
691 z = xa > xa0 ? *--xa : 0;
692 if (k -= Ebits) {
693 d0 = Exp_1 | y << k | z >> (32 - k);
694 y = xa > xa0 ? *--xa : 0;
695 d1 = z << k | y >> (32 - k);
697 else {
698 d0 = Exp_1 | y;
699 d1 = z;
701 #else
702 if (k < Ebits + 16) {
703 z = xa > xa0 ? *--xa : 0;
704 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
705 w = xa > xa0 ? *--xa : 0;
706 y = xa > xa0 ? *--xa : 0;
707 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
708 goto ret_d;
710 z = xa > xa0 ? *--xa : 0;
711 w = xa > xa0 ? *--xa : 0;
712 k -= Ebits + 16;
713 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
714 y = xa > xa0 ? *--xa : 0;
715 d1 = w << k + 16 | y << k;
716 #endif
717 ret_d:
718 #ifdef VAX
719 word0(&d) = d0 >> 16 | d0 << 16;
720 word1(&d) = d1 >> 16 | d1 << 16;
721 #endif
722 return dval(&d);
724 #undef d0
725 #undef d1
727 Bigint *
729 #ifdef KR_headers
730 (dd, e, bits) double dd; int *e, *bits;
731 #else
732 (double dd, int *e, int *bits)
733 #endif
735 Bigint *b;
736 U d;
737 #ifndef Sudden_Underflow
738 int i;
739 #endif
740 int de, k;
741 ULong *x, y, z;
742 #ifdef VAX
743 ULong d0, d1;
744 #else
745 #define d0 word0(&d)
746 #define d1 word1(&d)
747 #endif
748 d.d = dd;
749 #ifdef VAX
750 d0 = word0(&d) >> 16 | word0(&d) << 16;
751 d1 = word1(&d) >> 16 | word1(&d) << 16;
752 #endif
754 #ifdef Pack_32
755 b = Balloc(1);
756 #else
757 b = Balloc(2);
758 #endif
759 if (b == NULL)
760 return NULL;
761 x = b->x;
763 z = d0 & Frac_mask;
764 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
765 #ifdef Sudden_Underflow
766 de = (int)(d0 >> Exp_shift);
767 #ifndef IBM
768 z |= Exp_msk11;
769 #endif
770 #else
771 if ( (de = (int)(d0 >> Exp_shift)) !=0)
772 z |= Exp_msk1;
773 #endif
774 #ifdef Pack_32
775 if ( (y = d1) !=0) {
776 if ( (k = lo0bits(&y)) !=0) {
777 x[0] = y | z << (32 - k);
778 z >>= k;
780 else
781 x[0] = y;
782 #ifndef Sudden_Underflow
784 #endif
785 b->wds = (x[1] = z) !=0 ? 2 : 1;
787 else {
788 k = lo0bits(&z);
789 x[0] = z;
790 #ifndef Sudden_Underflow
792 #endif
793 b->wds = 1;
794 k += 32;
796 #else
797 if ( (y = d1) !=0) {
798 if ( (k = lo0bits(&y)) !=0)
799 if (k >= 16) {
800 x[0] = y | z << 32 - k & 0xffff;
801 x[1] = z >> k - 16 & 0xffff;
802 x[2] = z >> k;
803 i = 2;
805 else {
806 x[0] = y & 0xffff;
807 x[1] = y >> 16 | z << 16 - k & 0xffff;
808 x[2] = z >> k & 0xffff;
809 x[3] = z >> k+16;
810 i = 3;
812 else {
813 x[0] = y & 0xffff;
814 x[1] = y >> 16;
815 x[2] = z & 0xffff;
816 x[3] = z >> 16;
817 i = 3;
820 else {
821 #ifdef DEBUG
822 if (!z)
823 Bug("Zero passed to d2b");
824 #endif
825 k = lo0bits(&z);
826 if (k >= 16) {
827 x[0] = z;
828 i = 0;
830 else {
831 x[0] = z & 0xffff;
832 x[1] = z >> 16;
833 i = 1;
835 k += 32;
837 while(!x[i])
838 --i;
839 b->wds = i + 1;
840 #endif
841 #ifndef Sudden_Underflow
842 if (de) {
843 #endif
844 #ifdef IBM
845 *e = (de - Bias - (P-1) << 2) + k;
846 *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask);
847 #else
848 *e = de - Bias - (P-1) + k;
849 *bits = P - k;
850 #endif
851 #ifndef Sudden_Underflow
853 else {
854 *e = de - Bias - (P-1) + 1 + k;
855 #ifdef Pack_32
856 *bits = 32*i - hi0bits(x[i-1]);
857 #else
858 *bits = (i+2)*16 - hi0bits(x[i]);
859 #endif
861 #endif
862 return b;
864 #undef d0
865 #undef d1
867 CONST double
868 #ifdef IEEE_Arith
869 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
870 CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
872 #else
873 #ifdef IBM
874 bigtens[] = { 1e16, 1e32, 1e64 };
875 CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
876 #else
877 bigtens[] = { 1e16, 1e32 };
878 CONST double tinytens[] = { 1e-16, 1e-32 };
879 #endif
880 #endif
882 CONST double
883 tens[] = {
884 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
885 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
886 1e20, 1e21, 1e22
887 #ifdef VAX
888 , 1e23, 1e24
889 #endif
892 char *
893 #ifdef KR_headers
894 strcp_D2A(a, b) char *a; char *b;
895 #else
896 strcp_D2A(char *a, CONST char *b)
897 #endif
899 while((*a = *b++))
900 a++;
901 return a;
904 #ifdef NO_STRING_H
906 Char *
907 #ifdef KR_headers
908 memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
909 #else
910 memcpy_D2A(void *a1, void *b1, size_t len)
911 #endif
913 char *a = (char*)a1, *ae = a + len;
914 char *b = (char*)b1, *a0 = a;
915 while(a < ae)
916 *a++ = *b++;
917 return a0;
920 #endif /* NO_STRING_H */