revert between 56095 -> 55830 in arch
[AROS.git] / rom / exec / copymem.c
blobe4834bf88103492d263c33582bdf1b267dd61baa
1 /*
2 Copyright © 1995-2012, 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(IPTR, 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
47 64-bit sizes are not handled yet.
49 ******************************************************************************/
51 AROS_LIBFUNC_INIT
53 UBYTE *src,*dst;
54 ULONG mis,low,high;
57 I try to fall back to copying LONGs if possible. To do this I copy
58 the misaligned leading bytes of the source first. I use sizeof(LONG)
59 instead of LONGALIGN because it is sometimes faster.
62 if (!size) return;
64 src = (UBYTE *)source;
65 dst = (UBYTE *)dest;
67 #if 0 /* stegerg: this is the wrong way round??? */
68 mis =(IPTR)src&(sizeof(LONG)-1);
69 #else
70 mis = (sizeof(LONG) - 1) - (((IPTR)src - 1) & (sizeof(LONG) - 1));
71 #endif
72 if(mis>size)
73 mis=size;
74 size-=mis;
76 if(mis)
78 *dst++=*src++;
79 while(--mis);
82 The source has the right alignment now. All I need to do is to
83 check if this is true for the destination, too.
85 if(!((IPTR)dst&(AROS_LONGALIGN-1)))
87 /* Yes. I may copy LONGs. */
88 LONG *s=(LONG *)src,*d=(LONG *)dst;
89 ULONG longs;
91 /* How many of them? */
92 longs=size/sizeof(LONG);
95 To minimize the loop overhead I copy more than one (eight) LONG per
96 iteration. Therefore I need to split size into size/8 and the rest.
98 low =longs&7;
99 high=longs/8;
101 /* Then copy for both parts */
102 if(low)
104 *d++=*s++;
105 while(--low);
107 if(high)
110 *d++=*s++;
111 *d++=*s++;
112 *d++=*s++;
113 *d++=*s++;
114 *d++=*s++;
115 *d++=*s++;
116 *d++=*s++;
117 *d++=*s++;
118 }while(--high);
120 /* Get the rest. */
122 size&=sizeof(LONG)-1;
124 src=(UBYTE *)s;
125 dst=(UBYTE *)d;
128 /* The remaining job can only be done by copying single bytes. */
129 low =size&7;
130 high=size/8;
132 /* Copy for both parts */
133 if(low)
135 *dst++=*src++;
136 while(--low);
139 Partly unrolled copying loop. The predecrement helps the compiler to
140 find the best possible loop. The if is necessary to do this.
142 if(high)
145 *dst++=*src++;
146 *dst++=*src++;
147 *dst++=*src++;
148 *dst++=*src++;
149 *dst++=*src++;
150 *dst++=*src++;
151 *dst++=*src++;
152 *dst++=*src++;
153 }while(--high);
154 AROS_LIBFUNC_EXIT
155 } /* CopyMem */