1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#include "config.h"
#include <ctype.h>
#include "genlib.h"
#include "stddefs.h"
#ifndef MEMCPY_CHUNK
#define MEMCPY_CHUNK (256*1024)
#endif
/* memcpy():
* Copy n bytes from 'from' to 'to'; return 'to'.
* This version of memcpy() tries to take advantage of address alignment.
* The goal is to do as many of the copies on 4-byte aligned addresses,
* falling back to 2-byte alignment, and finally, if there is no other
* way, simple byte-by-byte copy.
* Note that there is some point where the amount of overhead may exceed
* the byte count; hence, this will take longer for small byte counts.
* The assumption here is that small byte count memcpy() calls don't really
* care.
*/
char *
memcpy(char *to,char *from,int count)
{
char *to_copy, *end;
#if INCLUDE_QUICKMEMCPY
char *tend;
#endif
to_copy = to;
#if INCLUDE_QUICKMEMCPY
/* If count is greater than 8, get fancy, else just do byte-copy... */
if(count > 8) {
/* Attempt to optimize the transfer here... */
if(((int)to & 3) && ((int)from & 3)) {
/* If from and to pointers are both unaligned to the
* same degree then we can do a few char copies to get them
* 4-byte aligned and then do a lot of 4-byte aligned copies.
*/
if(((int)to & 3) == ((int)from & 3)) {
while((int)to & 3) {
*to++ = *from++;
count--;
}
}
/* If from and to pointers are both odd, but different, then
* we can increment them both by 1 and do a bunch of 2-byte
* aligned copies...
*/
else if(((int)to & 1) && ((int)from & 1)) {
*to++ = *from++;
count--;
}
}
/* If both pointers are now 4-byte aligned or 2-byte aligned,
* take advantage of that here...
*/
if(!((int)to & 3) && !((int)from & 3)) {
tend = end = to + (count & ~3);
count = count & 3;
#ifdef WATCHDOG_ENABLED
do {
tend = (end - to <= MEMCPY_CHUNK) ? end : to + MEMCPY_CHUNK;
#endif
while(to < tend) {
*(ulong *)to = *(ulong *)from;
from += 4;
to += 4;
}
#ifdef WATCHDOG_ENABLED
WATCHDOG_MACRO;
} while(tend != end);
#endif
} else if(!((int)to & 1) && !((int)from & 1)) {
tend = end = to + (count & ~1);
count = count & 1;
#ifdef WATCHDOG_ENABLED
do {
tend = (end - to <= MEMCPY_CHUNK) ? end : to + MEMCPY_CHUNK;
#endif
while(to < tend) {
*(ushort *)to = *(ushort *)from;
from += 2;
to += 2;
}
#ifdef WATCHDOG_ENABLED
WATCHDOG_MACRO;
} while(tend != end);
#endif
}
}
#endif
if(count) {
end = to + count;
while(to < end) {
*to++ = *from++;
}
}
return(to_copy);
}
void
bcopy(char *from, char *to, int size)
{
memcpy(to,from,size);
}
|