Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / string / memmove.c
blobda5dfdbdd68a97a23863945709195d70e98c3267
1 /*
2 FUNCTION
3 <<memmove>>---move possibly overlapping memory
5 INDEX
6 memmove
8 SYNOPSIS
9 #include <string.h>
10 void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
12 DESCRIPTION
13 This function moves <[length]> characters from the block of
14 memory starting at <<*<[src]>>> to the memory starting at
15 <<*<[dst]>>>. <<memmove>> reproduces the characters correctly
16 at <<*<[dst]>>> even if the two areas overlap.
19 RETURNS
20 The function returns <[dst]> as passed.
22 PORTABILITY
23 <<memmove>> is ANSI C.
25 <<memmove>> requires no supporting OS subroutines.
27 QUICKREF
28 memmove ansi pure
31 #include <string.h>
32 #include <_ansi.h>
33 #include <stddef.h>
34 #include <limits.h>
35 #include "local.h"
37 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
38 #define UNALIGNED(X, Y) \
39 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
41 /* How many bytes are copied each iteration of the 4X unrolled loop. */
42 #define BIGBLOCKSIZE (sizeof (long) << 2)
44 /* How many bytes are copied each iteration of the word copy loop. */
45 #define LITTLEBLOCKSIZE (sizeof (long))
47 /* Threshhold for punting to the byte copier. */
48 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
50 /*SUPPRESS 20*/
51 void *
52 __inhibit_loop_to_libcall
53 memmove (void *dst_void,
54 const void *src_void,
55 size_t length)
57 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
58 char *dst = dst_void;
59 const char *src = src_void;
61 if (src < dst && dst < src + length)
63 /* Have to copy backwards */
64 src += length;
65 dst += length;
66 while (length--)
68 *--dst = *--src;
71 else
73 while (length--)
75 *dst++ = *src++;
79 return dst_void;
80 #else
81 char *dst = dst_void;
82 const char *src = src_void;
83 long *aligned_dst;
84 const long *aligned_src;
86 if (src < dst && dst < src + length)
88 /* Destructive overlap...have to copy backwards */
89 src += length;
90 dst += length;
91 while (length--)
93 *--dst = *--src;
96 else
98 /* Use optimizing algorithm for a non-destructive copy to closely
99 match memcpy. If the size is small or either SRC or DST is unaligned,
100 then punt into the byte copy loop. This should be rare. */
101 if (!TOO_SMALL(length) && !UNALIGNED (src, dst))
103 aligned_dst = (long*)dst;
104 aligned_src = (long*)src;
106 /* Copy 4X long words at a time if possible. */
107 while (length >= BIGBLOCKSIZE)
109 *aligned_dst++ = *aligned_src++;
110 *aligned_dst++ = *aligned_src++;
111 *aligned_dst++ = *aligned_src++;
112 *aligned_dst++ = *aligned_src++;
113 length -= BIGBLOCKSIZE;
116 /* Copy one long word at a time if possible. */
117 while (length >= LITTLEBLOCKSIZE)
119 *aligned_dst++ = *aligned_src++;
120 length -= LITTLEBLOCKSIZE;
123 /* Pick up any residual with a byte copier. */
124 dst = (char*)aligned_dst;
125 src = (char*)aligned_src;
128 while (length--)
130 *dst++ = *src++;
134 return dst_void;
135 #endif /* not PREFER_SIZE_OVER_SPEED */