OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [string/] [memmove.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
/*
2
FUNCTION
3
        <<memmove>>---move possibly overlapping memory
4
 
5
INDEX
6
        memmove
7
 
8
ANSI_SYNOPSIS
9
        #include <string.h>
10
        void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
11
 
12
TRAD_SYNOPSIS
13
        #include <string.h>
14
        void *memmove(<[dst]>, <[src]>, <[length]>)
15
        void *<[dst]>;
16
        void *<[src]>;
17
        size_t <[length]>;
18
 
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.
24
 
25
 
26
RETURNS
27
        The function returns <[dst]> as passed.
28
 
29
PORTABILITY
30
<<memmove>> is ANSI C.
31
 
32
<<memmove>> requires no supporting OS subroutines.
33
 
34
QUICKREF
35
        memmove ansi pure
36
*/
37
 
38
#include <string.h>
39 56 joel
#include <_ansi.h>
40
#include <stddef.h>
41
#include <limits.h>
42 39 lampret
 
43 56 joel
/* 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)))
46
 
47
/* How many bytes are copied each iteration of the 4X unrolled loop.  */
48
#define BIGBLOCKSIZE    (sizeof (long) << 2)
49
 
50
/* How many bytes are copied each iteration of the word copy loop.  */
51
#define LITTLEBLOCKSIZE (sizeof (long))
52
 
53
/* Threshhold for punting to the byte copier.  */
54
#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
55
 
56 39 lampret
/*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)
62
{
63 56 joel
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
64 39 lampret
  char *dst = dst_void;
65
  _CONST char *src = src_void;
66
 
67
  if (src < dst && dst < src + length)
68
    {
69
      /* Have to copy backwards */
70
      src += length;
71
      dst += length;
72
      while (length--)
73
        {
74
          *--dst = *--src;
75
        }
76
    }
77
  else
78
    {
79
      while (length--)
80
        {
81
          *dst++ = *src++;
82
        }
83
    }
84
 
85
  return dst_void;
86 56 joel
#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;
92
 
93
  if (src < dst && dst < src + len)
94
    {
95
      /* Destructive overlap...have to copy backwards */
96
      src += len;
97
      dst += len;
98
      while (len--)
99
        {
100
          *--dst = *--src;
101
        }
102
    }
103
  else
104
    {
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))
109
        {
110
          aligned_dst = (long*)dst;
111
          aligned_src = (long*)src;
112
 
113
          /* Copy 4X long words at a time if possible.  */
114
          while (len >= BIGBLOCKSIZE)
115
            {
116
              *aligned_dst++ = *aligned_src++;
117
              *aligned_dst++ = *aligned_src++;
118
              *aligned_dst++ = *aligned_src++;
119
              *aligned_dst++ = *aligned_src++;
120
              len -= BIGBLOCKSIZE;
121
            }
122
 
123
          /* Copy one long word at a time if possible.  */
124
          while (len >= LITTLEBLOCKSIZE)
125
            {
126
              *aligned_dst++ = *aligned_src++;
127
              len -= LITTLEBLOCKSIZE;
128
            }
129
 
130
          /* Pick up any residual with a byte copier.  */
131
          dst = (char*)aligned_dst;
132
          src = (char*)aligned_src;
133
        }
134
 
135
      while (len--)
136
        {
137
          *dst++ = *src++;
138
        }
139
    }
140
 
141
  return dst_void;
142
#endif /* not PREFER_SIZE_OVER_SPEED */
143 39 lampret
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.