source: trunk/libs/newlib/src/newlib/libc/string/memcpy.c @ 543

Last change on this file since 543 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 2.5 KB
Line 
1/*
2FUNCTION
3        <<memcpy>>---copy memory regions
4
5SYNOPSIS
6        #include <string.h>
7        void* memcpy(void *restrict <[out]>, const void *restrict <[in]>,
8                     size_t <[n]>);
9
10DESCRIPTION
11        This function copies <[n]> bytes from the memory region
12        pointed to by <[in]> to the memory region pointed to by
13        <[out]>.
14
15        If the regions overlap, the behavior is undefined.
16
17RETURNS
18        <<memcpy>> returns a pointer to the first byte of the <[out]>
19        region.
20
21PORTABILITY
22<<memcpy>> is ANSI C.
23
24<<memcpy>> requires no supporting OS subroutines.
25
26QUICKREF
27        memcpy ansi pure
28        */
29
30#include <_ansi.h>
31#include <string.h>
32
33/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
34#define UNALIGNED(X, Y) \
35  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
36
37/* How many bytes are copied each iteration of the 4X unrolled loop.  */
38#define BIGBLOCKSIZE    (sizeof (long) << 2)
39
40/* How many bytes are copied each iteration of the word copy loop.  */
41#define LITTLEBLOCKSIZE (sizeof (long))
42
43/* Threshhold for punting to the byte copier.  */
44#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
45
46void *
47memcpy (void *__restrict dst0,
48        const void *__restrict src0,
49        size_t len0)
50{
51#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
52  char *dst = (char *) dst0;
53  char *src = (char *) src0;
54
55  void *save = dst0;
56
57  while (len0--)
58    {
59      *dst++ = *src++;
60    }
61
62  return save;
63#else
64  char *dst = dst0;
65  const char *src = src0;
66  long *aligned_dst;
67  const long *aligned_src;
68
69  /* If the size is small, or either SRC or DST is unaligned,
70     then punt into the byte copy loop.  This should be rare.  */
71  if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
72    {
73      aligned_dst = (long*)dst;
74      aligned_src = (long*)src;
75
76      /* Copy 4X long words at a time if possible.  */
77      while (len0 >= BIGBLOCKSIZE)
78        {
79          *aligned_dst++ = *aligned_src++;
80          *aligned_dst++ = *aligned_src++;
81          *aligned_dst++ = *aligned_src++;
82          *aligned_dst++ = *aligned_src++;
83          len0 -= BIGBLOCKSIZE;
84        }
85
86      /* Copy one long word at a time if possible.  */
87      while (len0 >= LITTLEBLOCKSIZE)
88        {
89          *aligned_dst++ = *aligned_src++;
90          len0 -= LITTLEBLOCKSIZE;
91        }
92
93       /* Pick up any residual with a byte copier.  */
94      dst = (char*)aligned_dst;
95      src = (char*)aligned_src;
96    }
97
98  while (len0--)
99    *dst++ = *src++;
100
101  return dst0;
102#endif /* not PREFER_SIZE_OVER_SPEED */
103}
Note: See TracBrowser for help on using the repository browser.