fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / string / memmove.c
blob2528e27d40f12b4bda5fd94b1a279b500a00dfaa
1 /*
2 FUNCTION
3 <<memmove>>---move possibly overlapping memory
5 INDEX
6 memmove
8 ANSI_SYNOPSIS
9 #include <string.h>
10 void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
12 TRAD_SYNOPSIS
13 #include <string.h>
14 void *memmove(<[dst]>, <[src]>, <[length]>)
15 void *<[dst]>;
16 void *<[src]>;
17 size_t <[length]>;
19 DESCRIPTION
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.
26 RETURNS
27 The function returns <[dst]> as passed.
29 PORTABILITY
30 <<memmove>> is ANSI C.
32 <<memmove>> requires no supporting OS subroutines.
34 QUICKREF
35 memmove ansi pure
38 #include <string.h>
39 #include <_ansi.h>
40 #include <stddef.h>
41 #include <limits.h>
43 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
44 #define UNALIGNED(X, Y) \
45 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
47 /* How many bytes are copied each iteration of the 4X unrolled loop. */
48 #define BIGBLOCKSIZE (sizeof (long) << 2)
50 /* How many bytes are copied each iteration of the word copy loop. */
51 #define LITTLEBLOCKSIZE (sizeof (long))
53 /* Threshhold for punting to the byte copier. */
54 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
56 /*SUPPRESS 20*/
57 _PTR
58 _DEFUN (memmove, (dst_void, src_void, length),
59 _PTR dst_void _AND
60 _CONST _PTR src_void _AND
61 size_t length)
63 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
64 char *dst = dst_void;
65 _CONST char *src = src_void;
67 if (src < dst && dst < src + length)
69 /* Have to copy backwards */
70 src += length;
71 dst += length;
72 while (length--)
74 *--dst = *--src;
77 else
79 while (length--)
81 *dst++ = *src++;
85 return dst_void;
86 #else
87 char *dst = dst_void;
88 _CONST char *src = src_void;
89 long *aligned_dst;
90 _CONST long *aligned_src;
91 int len = length;
93 if (src < dst && dst < src + len)
95 /* Destructive overlap...have to copy backwards */
96 src += len;
97 dst += len;
98 while (len--)
100 *--dst = *--src;
103 else
105 /* Use optimizing algorithm for a non-destructive copy to closely
106 match memcpy. If the size is small or either SRC or DST is unaligned,
107 then punt into the byte copy loop. This should be rare. */
108 if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
110 aligned_dst = (long*)dst;
111 aligned_src = (long*)src;
113 /* Copy 4X long words at a time if possible. */
114 while (len >= BIGBLOCKSIZE)
116 *aligned_dst++ = *aligned_src++;
117 *aligned_dst++ = *aligned_src++;
118 *aligned_dst++ = *aligned_src++;
119 *aligned_dst++ = *aligned_src++;
120 len -= BIGBLOCKSIZE;
123 /* Copy one long word at a time if possible. */
124 while (len >= LITTLEBLOCKSIZE)
126 *aligned_dst++ = *aligned_src++;
127 len -= LITTLEBLOCKSIZE;
130 /* Pick up any residual with a byte copier. */
131 dst = (char*)aligned_dst;
132 src = (char*)aligned_src;
135 while (len--)
137 *dst++ = *src++;
141 return dst_void;
142 #endif /* not PREFER_SIZE_OVER_SPEED */