Subversion Repositories Kolibri OS

Rev

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

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