Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / string / memcpy.c
blob52f716b9275f5d24cedb7d66c41541945d13bfb6
1 /*
2 FUNCTION
3 <<memcpy>>---copy memory regions
5 SYNOPSIS
6 #include <string.h>
7 void* memcpy(void *restrict <[out]>, const void *restrict <[in]>,
8 size_t <[n]>);
10 DESCRIPTION
11 This function copies <[n]> bytes from the memory region
12 pointed to by <[in]> to the memory region pointed to by
13 <[out]>.
15 If the regions overlap, the behavior is undefined.
17 RETURNS
18 <<memcpy>> returns a pointer to the first byte of the <[out]>
19 region.
21 PORTABILITY
22 <<memcpy>> is ANSI C.
24 <<memcpy>> requires no supporting OS subroutines.
26 QUICKREF
27 memcpy ansi pure
30 #include <_ansi.h>
31 #include <string.h>
32 #include "local.h"
34 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
35 #define UNALIGNED(X, Y) \
36 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
38 /* How many bytes are copied each iteration of the 4X unrolled loop. */
39 #define BIGBLOCKSIZE (sizeof (long) << 2)
41 /* How many bytes are copied each iteration of the word copy loop. */
42 #define LITTLEBLOCKSIZE (sizeof (long))
44 /* Threshhold for punting to the byte copier. */
45 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
47 void *
48 __inhibit_loop_to_libcall
49 memcpy (void *__restrict dst0,
50 const void *__restrict src0,
51 size_t len0)
53 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
54 char *dst = (char *) dst0;
55 char *src = (char *) src0;
57 void *save = dst0;
59 while (len0--)
61 *dst++ = *src++;
64 return save;
65 #else
66 char *dst = dst0;
67 const char *src = src0;
68 long *aligned_dst;
69 const long *aligned_src;
71 /* If the size is small, or either SRC or DST is unaligned,
72 then punt into the byte copy loop. This should be rare. */
73 if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
75 aligned_dst = (long*)dst;
76 aligned_src = (long*)src;
78 /* Copy 4X long words at a time if possible. */
79 while (len0 >= BIGBLOCKSIZE)
81 *aligned_dst++ = *aligned_src++;
82 *aligned_dst++ = *aligned_src++;
83 *aligned_dst++ = *aligned_src++;
84 *aligned_dst++ = *aligned_src++;
85 len0 -= BIGBLOCKSIZE;
88 /* Copy one long word at a time if possible. */
89 while (len0 >= LITTLEBLOCKSIZE)
91 *aligned_dst++ = *aligned_src++;
92 len0 -= LITTLEBLOCKSIZE;
95 /* Pick up any residual with a byte copier. */
96 dst = (char*)aligned_dst;
97 src = (char*)aligned_src;
100 while (len0--)
101 *dst++ = *src++;
103 return dst0;
104 #endif /* not PREFER_SIZE_OVER_SPEED */