Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1693 serge 1
/*
2
FUNCTION
3
	<>---move possibly overlapping memory
4
 
5
INDEX
6
	memmove
7
 
8
ANSI_SYNOPSIS
9
	#include 
10
	void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
11
 
12
TRAD_SYNOPSIS
13
	#include 
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]>>>. <> 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
<> is ANSI C.
31
 
32
<> requires no supporting OS subroutines.
33
 
34
QUICKREF
35
	memmove ansi pure
36
*/
37
 
38
#include 
39
#include <_ansi.h>
40
#include 
41
#include 
42
 
43
/* 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
/*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
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
64
  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
#else
87
  char *dst = dst_void;
88
  _CONST char *src = src_void;
89
  long *aligned_dst;
90
  _CONST long *aligned_src;
91
 
92
  if (src < dst && dst < src + length)
93
    {
94
      /* Destructive overlap...have to copy backwards */
95
      src += length;
96
      dst += length;
97
      while (length--)
98
	{
99
	  *--dst = *--src;
100
	}
101
    }
102
  else
103
    {
104
      /* Use optimizing algorithm for a non-destructive copy to closely
105
         match memcpy. If the size is small or either SRC or DST is unaligned,
106
         then punt into the byte copy loop.  This should be rare.  */
107
      if (!TOO_SMALL(length) && !UNALIGNED (src, dst))
108
        {
109
          aligned_dst = (long*)dst;
110
          aligned_src = (long*)src;
111
 
112
          /* Copy 4X long words at a time if possible.  */
113
          while (length >= BIGBLOCKSIZE)
114
            {
115
              *aligned_dst++ = *aligned_src++;
116
              *aligned_dst++ = *aligned_src++;
117
              *aligned_dst++ = *aligned_src++;
118
              *aligned_dst++ = *aligned_src++;
119
              length -= BIGBLOCKSIZE;
120
            }
121
 
122
          /* Copy one long word at a time if possible.  */
123
          while (length >= LITTLEBLOCKSIZE)
124
            {
125
              *aligned_dst++ = *aligned_src++;
126
              length -= LITTLEBLOCKSIZE;
127
            }
128
 
129
          /* Pick up any residual with a byte copier.  */
130
          dst = (char*)aligned_dst;
131
          src = (char*)aligned_src;
132
        }
133
 
134
      while (length--)
135
        {
136
          *dst++ = *src++;
137
        }
138
    }
139
 
140
  return dst_void;
141
#endif /* not PREFER_SIZE_OVER_SPEED */
142
}