3 <<memmove>>---move possibly overlapping memory
10 void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
14 void *memmove(<[dst]>, <[src]>, <[length]>)
20 This function moves <[length]> characters from the block of
21 memory starting at <<*<[src]>>> to the memory starting at
22 <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
23 at <<*<[dst]>>> even if the two areas overlap.
27 The function returns <[dst]> as passed.
30 <<memmove>> is ANSI C.
32 <<memmove>> requires no supporting OS subroutines.
42 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
43 #define UNALIGNED(X, Y) \
44 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
46 /* How many bytes are copied each iteration of the 4X unrolled loop. */
47 #define BIGBLOCKSIZE (sizeof (long) << 2)
49 /* How many bytes are copied each iteration of the word copy loop. */
50 #define LITTLEBLOCKSIZE (sizeof (long))
52 /* Threshhold for punting to the byte copier. */
53 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
56 _DEFUN (memmove
, (dst_void
, src_void
, length
),
58 _CONST _PTR src_void _AND
59 size_t length
) ICODE_ATTR
;
62 _DEFUN (memmove
, (dst_void
, src_void
, length
),
64 _CONST _PTR src_void _AND
67 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
69 _CONST
char *src
= src_void
;
71 if (src
< dst
&& dst
< src
+ length
)
73 /* Have to copy backwards */
92 _CONST
char *src
= src_void
;
94 _CONST
long *aligned_src
;
95 unsigned int len
= length
;
97 if (src
< dst
&& dst
< src
+ len
)
99 /* Destructive overlap...have to copy backwards */
109 /* Use optimizing algorithm for a non-destructive copy to closely
110 match memcpy. If the size is small or either SRC or DST is unaligned,
111 then punt into the byte copy loop. This should be rare. */
112 if (!TOO_SMALL(len
) && !UNALIGNED (src
, dst
))
114 aligned_dst
= (long*)dst
;
115 aligned_src
= (long*)src
;
117 /* Copy 4X long words at a time if possible. */
118 while (len
>= BIGBLOCKSIZE
)
120 *aligned_dst
++ = *aligned_src
++;
121 *aligned_dst
++ = *aligned_src
++;
122 *aligned_dst
++ = *aligned_src
++;
123 *aligned_dst
++ = *aligned_src
++;
127 /* Copy one long word at a time if possible. */
128 while (len
>= LITTLEBLOCKSIZE
)
130 *aligned_dst
++ = *aligned_src
++;
131 len
-= LITTLEBLOCKSIZE
;
134 /* Pick up any residual with a byte copier. */
135 dst
= (char*)aligned_dst
;
136 src
= (char*)aligned_src
;
146 #endif /* not PREFER_SIZE_OVER_SPEED */