source: trunk/libs/newlib/src/newlib/libc/string/memmove.c @ 559

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

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

File size: 3.1 KB
Line 
1/*
2FUNCTION
3        <<memmove>>---move possibly overlapping memory
4
5INDEX
6        memmove
7
8SYNOPSIS
9        #include <string.h>
10        void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
11
12DESCRIPTION
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.
17
18
19RETURNS
20        The function returns <[dst]> as passed.
21
22PORTABILITY
23<<memmove>> is ANSI C.
24
25<<memmove>> requires no supporting OS subroutines.
26
27QUICKREF
28        memmove ansi pure
29*/
30
31#include <string.h>
32#include <_ansi.h>
33#include <stddef.h>
34#include <limits.h>
35#include "local.h"
36
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)))
40
41/* How many bytes are copied each iteration of the 4X unrolled loop.  */
42#define BIGBLOCKSIZE    (sizeof (long) << 2)
43
44/* How many bytes are copied each iteration of the word copy loop.  */
45#define LITTLEBLOCKSIZE (sizeof (long))
46
47/* Threshhold for punting to the byte copier.  */
48#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
49
50/*SUPPRESS 20*/
51void *
52__inhibit_loop_to_libcall
53memmove (void *dst_void,
54        const void *src_void,
55        size_t length)
56{
57#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
58  char *dst = dst_void;
59  const char *src = src_void;
60
61  if (src < dst && dst < src + length)
62    {
63      /* Have to copy backwards */
64      src += length;
65      dst += length;
66      while (length--)
67        {
68          *--dst = *--src;
69        }
70    }
71  else
72    {
73      while (length--)
74        {
75          *dst++ = *src++;
76        }
77    }
78
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;
85
86  if (src < dst && dst < src + length)
87    {
88      /* Destructive overlap...have to copy backwards */
89      src += length;
90      dst += length;
91      while (length--)
92        {
93          *--dst = *--src;
94        }
95    }
96  else
97    {
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))
102        {
103          aligned_dst = (long*)dst;
104          aligned_src = (long*)src;
105
106          /* Copy 4X long words at a time if possible.  */
107          while (length >= BIGBLOCKSIZE)
108            {
109              *aligned_dst++ = *aligned_src++;
110              *aligned_dst++ = *aligned_src++;
111              *aligned_dst++ = *aligned_src++;
112              *aligned_dst++ = *aligned_src++;
113              length -= BIGBLOCKSIZE;
114            }
115
116          /* Copy one long word at a time if possible.  */
117          while (length >= LITTLEBLOCKSIZE)
118            {
119              *aligned_dst++ = *aligned_src++;
120              length -= LITTLEBLOCKSIZE;
121            }
122
123          /* Pick up any residual with a byte copier.  */
124          dst = (char*)aligned_dst;
125          src = (char*)aligned_src;
126        }
127
128      while (length--)
129        {
130          *dst++ = *src++;
131        }
132    }
133
134  return dst_void;
135#endif /* not PREFER_SIZE_OVER_SPEED */
136}
Note: See TracBrowser for help on using the repository browser.