Subversion Repositories freemyipod

Rev

Rev 424 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
71 theseven 1
/*
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 "global.h"
113 theseven 39
#include "include/string.h"
40
#include "include/_ansi.h"
71 theseven 41
 
42
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
43
#define UNALIGNED(X, Y) \
44
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
45
 
46
/* How many bytes are copied each iteration of the 4X unrolled loop.  */
47
#define BIGBLOCKSIZE    (sizeof (long) << 2)
48
 
49
/* How many bytes are copied each iteration of the word copy loop.  */
50
#define LITTLEBLOCKSIZE (sizeof (long))
51
 
52
/* Threshhold for punting to the byte copier.  */
53
#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
54
 
55
_PTR
56
_DEFUN (memmove, (dst_void, src_void, length),
57
        _PTR dst_void _AND
58
        _CONST _PTR src_void _AND
59
        size_t length) ICODE_ATTR;
60
 
61
_PTR
62
_DEFUN (memmove, (dst_void, src_void, length),
63
        _PTR dst_void _AND
64
        _CONST _PTR src_void _AND
65
        size_t length)
66
{
248 theseven 67
#if defined(PREFER_SIZE_OVER_SPEED)
71 theseven 68
  char *dst = dst_void;
69
  _CONST char *src = src_void;
70
 
71
  if (src < dst && dst < src + length)
72
    {
73
      /* Have to copy backwards */
74
      src += length;
75
      dst += length;
76
      while (length--)
77
        {
78
          *--dst = *--src;
79
        }
80
    }
81
  else
82
    {
83
      while (length--)
84
        {
85
          *dst++ = *src++;
86
        }
87
    }
88
 
89
  return dst_void;
90
#else
91
  char *dst = dst_void;
92
  _CONST char *src = src_void;
93
  long *aligned_dst;
94
  _CONST long *aligned_src;
95
  unsigned int   len =  length;
96
 
97
  if (src < dst && dst < src + len)
98
    {
99
      /* Destructive overlap...have to copy backwards */
100
      src += len;
101
      dst += len;
102
      while (len--)
103
        {
104
          *--dst = *--src;
105
        }
106
    }
107
  else
108
    {
109
      /* Use optimizing algorithm for a non-destructive copy to closely 
110
         match memcpy. If the size is small or either SRC or DST is unaligned,
111
         then punt into the byte copy loop.  This should be rare.  */
112
      if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
113
        {
114
          aligned_dst = (long*)dst;
115
          aligned_src = (long*)src;
116
 
117
          /* Copy 4X long words at a time if possible.  */
118
          while (len >= BIGBLOCKSIZE)
119
            {
120
              *aligned_dst++ = *aligned_src++;
121
              *aligned_dst++ = *aligned_src++;
122
              *aligned_dst++ = *aligned_src++;
123
              *aligned_dst++ = *aligned_src++;
124
              len -= BIGBLOCKSIZE;
125
            }
126
 
127
          /* Copy one long word at a time if possible.  */
128
          while (len >= LITTLEBLOCKSIZE)
129
            {
130
              *aligned_dst++ = *aligned_src++;
131
              len -= LITTLEBLOCKSIZE;
132
            }
133
 
134
          /* Pick up any residual with a byte copier.  */
135
          dst = (char*)aligned_dst;
136
          src = (char*)aligned_src;
137
        }
138
 
139
      while (len--)
140
        {
141
          *dst++ = *src++;
142
        }
143
    }
144
 
145
  return dst_void;
146
#endif /* not PREFER_SIZE_OVER_SPEED */
147
}