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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [orp/] [orp_soc/] [sw.old/] [mad-xess/] [memmove.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 782 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
#ifdef HAVE_CONFIG_H
38
# include "config.h"
39
#endif 
40
 
41
#ifdef EMBED
42
#include <string.h>
43
#include <_ansi.h>
44
#include <stddef.h>
45
#include <limits.h>
46
 
47
/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
48
#define UNALIGNED(X, Y) \
49
  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
50
 
51
/* How many bytes are copied each iteration of the 4X unrolled loop.  */
52
#define BIGBLOCKSIZE    (sizeof (long) << 2)
53
 
54
/* How many bytes are copied each iteration of the word copy loop.  */
55
#define LITTLEBLOCKSIZE (sizeof (long))
56
 
57
/* Threshhold for punting to the byte copier.  */
58
#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
59
 
60
/*SUPPRESS 20*/
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
{
67
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
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
  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
}
148
#endif

powered by: WebSVN 2.1.0

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