exec.library: Prevent recursive build
[AROS.git] / rom / exec / copymem.c
blob0cfa08e0fcf6f028d98d36447eb73acae0fa410b
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Copy memory.
6 Lang: english
7 */
8 #include <aros/libcall.h>
9 #include <proto/exec.h>
11 /*****************************************************************************
13 NAME */
15 AROS_LH3I(void, CopyMem,
17 /* SYNOPSIS */
18 AROS_LHA(CONST_APTR, source, A0),
19 AROS_LHA(APTR, dest, A1),
20 AROS_LHA(ULONG, size, D0),
22 /* LOCATION */
23 struct ExecBase *, SysBase, 104, Exec)
25 /* FUNCTION
26 Copy some memory from one destination in memory to another using
27 a fast copying method.
29 INPUTS
30 source - Pointer to source area
31 dest - Pointer to destination
32 size - number of bytes to copy (may be zero)
34 RESULT
36 NOTES
37 The source and destination area are not allowed to overlap.
39 EXAMPLE
41 BUGS
43 SEE ALSO
44 CopyMemQuick()
46 INTERNALS
48 ******************************************************************************/
50 AROS_LIBFUNC_INIT
52 UBYTE *src,*dst;
53 ULONG mis,low,high;
56 I try to fall back to copying LONGs if possible. To do this I copy
57 the misaligned leading bytes of the source first. I use sizeof(LONG)
58 instead of LONGALIGN because it is sometimes faster.
61 if (!size) return;
63 src = (UBYTE *)source;
64 dst = (UBYTE *)dest;
66 #if 0 /* stegerg: this is the wrong way round??? */
67 mis =(IPTR)src&(sizeof(LONG)-1);
68 #else
69 mis = (sizeof(LONG) - 1) - (((IPTR)src - 1) & (sizeof(LONG) - 1));
70 #endif
71 if(mis>size)
72 mis=size;
73 size-=mis;
75 if(mis)
77 *dst++=*src++;
78 while(--mis);
81 The source has the right alignment now. All I need to do is to
82 check if this is true for the destination, too.
84 if(!((IPTR)dst&(AROS_LONGALIGN-1)))
86 /* Yes. I may copy LONGs. */
87 LONG *s=(LONG *)src,*d=(LONG *)dst;
88 ULONG longs;
90 /* How many of them? */
91 longs=size/sizeof(LONG);
94 To minimize the loop overhead I copy more than one (eight) LONG per
95 iteration. Therefore I need to split size into size/8 and the rest.
97 low =longs&7;
98 high=longs/8;
100 /* Then copy for both parts */
101 if(low)
103 *d++=*s++;
104 while(--low);
106 if(high)
109 *d++=*s++;
110 *d++=*s++;
111 *d++=*s++;
112 *d++=*s++;
113 *d++=*s++;
114 *d++=*s++;
115 *d++=*s++;
116 *d++=*s++;
117 }while(--high);
119 /* Get the rest. */
121 size&=sizeof(LONG)-1;
123 src=(UBYTE *)s;
124 dst=(UBYTE *)d;
127 /* The remaining job can only be done by copying single bytes. */
128 low =size&7;
129 high=size/8;
131 /* Copy for both parts */
132 if(low)
134 *dst++=*src++;
135 while(--low);
138 Partly unrolled copying loop. The predecrement helps the compiler to
139 find the best possible loop. The if is necessary to do this.
141 if(high)
144 *dst++=*src++;
145 *dst++=*src++;
146 *dst++=*src++;
147 *dst++=*src++;
148 *dst++=*src++;
149 *dst++=*src++;
150 *dst++=*src++;
151 *dst++=*src++;
152 }while(--high);
153 AROS_LIBFUNC_EXIT
154 } /* CopyMem */