Rev 4874 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4874 | Rev 4921 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | FUNCTION |
2 | FUNCTION |
3 | < |
3 | < |
4 | 4 | ||
5 | ANSI_SYNOPSIS |
5 | ANSI_SYNOPSIS |
6 | #include |
6 | #include |
7 | void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>); |
7 | void* memcpy(void *restrict <[out]>, const void *restrict <[in]>, |
- | 8 | size_t <[n]>); |
|
8 | 9 | ||
9 | TRAD_SYNOPSIS |
10 | TRAD_SYNOPSIS |
10 | #include |
11 | #include |
11 | void *memcpy(<[out]>, <[in]>, <[n]> |
12 | void *memcpy(<[out]>, <[in]>, <[n]> |
12 | void *<[out]>; |
13 | void *<[out]>; |
13 | void *<[in]>; |
14 | void *<[in]>; |
14 | size_t <[n]>; |
15 | size_t <[n]>; |
15 | 16 | ||
16 | DESCRIPTION |
17 | DESCRIPTION |
17 | This function copies <[n]> bytes from the memory region |
18 | This function copies <[n]> bytes from the memory region |
18 | pointed to by <[in]> to the memory region pointed to by |
19 | pointed to by <[in]> to the memory region pointed to by |
19 | <[out]>. |
20 | <[out]>. |
20 | 21 | ||
21 | If the regions overlap, the behavior is undefined. |
22 | If the regions overlap, the behavior is undefined. |
22 | 23 | ||
23 | RETURNS |
24 | RETURNS |
24 | < |
25 | < |
25 | region. |
26 | region. |
26 | 27 | ||
27 | PORTABILITY |
28 | PORTABILITY |
28 | < |
29 | < |
29 | 30 | ||
30 | < |
31 | < |
31 | 32 | ||
32 | QUICKREF |
33 | QUICKREF |
33 | memcpy ansi pure |
34 | memcpy ansi pure |
34 | */ |
35 | */ |
35 | 36 | ||
36 | #include <_ansi.h> |
37 | #include <_ansi.h> |
37 | #include |
38 | #include |
38 | 39 | ||
39 | /* Nonzero if either X or Y is not aligned on a "long" boundary. */ |
40 | /* Nonzero if either X or Y is not aligned on a "long" boundary. */ |
40 | #define UNALIGNED(X, Y) \ |
41 | #define UNALIGNED(X, Y) \ |
41 | (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) |
42 | (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) |
42 | 43 | ||
43 | /* How many bytes are copied each iteration of the 4X unrolled loop. */ |
44 | /* How many bytes are copied each iteration of the 4X unrolled loop. */ |
44 | #define BIGBLOCKSIZE (sizeof (long) << 2) |
45 | #define BIGBLOCKSIZE (sizeof (long) << 2) |
45 | 46 | ||
46 | /* How many bytes are copied each iteration of the word copy loop. */ |
47 | /* How many bytes are copied each iteration of the word copy loop. */ |
47 | #define LITTLEBLOCKSIZE (sizeof (long)) |
48 | #define LITTLEBLOCKSIZE (sizeof (long)) |
48 | 49 | ||
49 | /* Threshhold for punting to the byte copier. */ |
50 | /* Threshhold for punting to the byte copier. */ |
50 | #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE) |
51 | #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE) |
51 | 52 | ||
52 | _PTR |
53 | _PTR |
53 | _DEFUN (memcpy, (dst0, src0, len0), |
54 | _DEFUN (memcpy, (dst0, src0, len0), |
54 | _PTR dst0 _AND |
55 | _PTR __restrict dst0 _AND |
55 | _CONST _PTR src0 _AND |
56 | _CONST _PTR __restrict src0 _AND |
56 | size_t len0) |
57 | size_t len0) |
57 | { |
58 | { |
58 | #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) |
59 | #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) |
59 | char *dst = (char *) dst0; |
60 | char *dst = (char *) dst0; |
60 | char *src = (char *) src0; |
61 | char *src = (char *) src0; |
61 | 62 | ||
62 | _PTR save = dst0; |
63 | _PTR save = dst0; |
63 | 64 | ||
64 | while (len0--) |
65 | while (len0--) |
65 | { |
66 | { |
66 | *dst++ = *src++; |
67 | *dst++ = *src++; |
67 | } |
68 | } |
68 | 69 | ||
69 | return save; |
70 | return save; |
70 | #else |
71 | #else |
71 | char *dst = dst0; |
72 | char *dst = dst0; |
72 | _CONST char *src = src0; |
73 | _CONST char *src = src0; |
73 | long *aligned_dst; |
74 | long *aligned_dst; |
74 | _CONST long *aligned_src; |
75 | _CONST long *aligned_src; |
75 | 76 | ||
76 | /* If the size is small, or either SRC or DST is unaligned, |
77 | /* If the size is small, or either SRC or DST is unaligned, |
77 | then punt into the byte copy loop. This should be rare. */ |
78 | then punt into the byte copy loop. This should be rare. */ |
78 | if (!TOO_SMALL(len0) && !UNALIGNED (src, dst)) |
79 | if (!TOO_SMALL(len0) && !UNALIGNED (src, dst)) |
79 | { |
80 | { |
80 | aligned_dst = (long*)dst; |
81 | aligned_dst = (long*)dst; |
81 | aligned_src = (long*)src; |
82 | aligned_src = (long*)src; |
82 | 83 | ||
83 | /* Copy 4X long words at a time if possible. */ |
84 | /* Copy 4X long words at a time if possible. */ |
84 | while (len0 >= BIGBLOCKSIZE) |
85 | while (len0 >= BIGBLOCKSIZE) |
85 | { |
86 | { |
86 | *aligned_dst++ = *aligned_src++; |
87 | *aligned_dst++ = *aligned_src++; |
87 | *aligned_dst++ = *aligned_src++; |
88 | *aligned_dst++ = *aligned_src++; |
88 | *aligned_dst++ = *aligned_src++; |
89 | *aligned_dst++ = *aligned_src++; |
89 | *aligned_dst++ = *aligned_src++; |
90 | *aligned_dst++ = *aligned_src++; |
90 | len0 -= BIGBLOCKSIZE; |
91 | len0 -= BIGBLOCKSIZE; |
91 | } |
92 | } |
92 | 93 | ||
93 | /* Copy one long word at a time if possible. */ |
94 | /* Copy one long word at a time if possible. */ |
94 | while (len0 >= LITTLEBLOCKSIZE) |
95 | while (len0 >= LITTLEBLOCKSIZE) |
95 | { |
96 | { |
96 | *aligned_dst++ = *aligned_src++; |
97 | *aligned_dst++ = *aligned_src++; |
97 | len0 -= LITTLEBLOCKSIZE; |
98 | len0 -= LITTLEBLOCKSIZE; |
98 | } |
99 | } |
99 | 100 | ||
100 | /* Pick up any residual with a byte copier. */ |
101 | /* Pick up any residual with a byte copier. */ |
101 | dst = (char*)aligned_dst; |
102 | dst = (char*)aligned_dst; |
102 | src = (char*)aligned_src; |
103 | src = (char*)aligned_src; |
103 | } |
104 | } |
104 | 105 | ||
105 | while (len0--) |
106 | while (len0--) |
106 | *dst++ = *src++; |
107 | *dst++ = *src++; |
107 | 108 | ||
108 | return dst0; |
109 | return dst0; |
109 | #endif /* not PREFER_SIZE_OVER_SPEED */ |
110 | #endif /* not PREFER_SIZE_OVER_SPEED */ |
110 | }>><> |
111 | }>><> |