1 /* Copy memory to memory until the specified number of bytes
2 has been copied. Overlap is handled correctly.
3 Copyright (C) 1991, 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Torbjorn Granlund (tege@sics.se).
6
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301 USA */
21
22 /*
23 * August 2006. For Gawk: Borrowed from GLIBC and hacked unmercifully.
24 * DON'T steal this for your own code, go straight to the GLIBC
25 * source for the original versions.
26 */
27
28
29 /* This stuff from libc/sysdeps/generic/memcopy.h */
30 typedef unsigned char byte;
31
32 /* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
33 without any assumptions about alignment of the pointers. */
34 #define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
35 do \
36 { \
37 size_t __nbytes = (nbytes); \
38 while (__nbytes > 0) \
39 { \
40 byte __x = ((byte *) src_bp)[0]; \
41 src_bp += 1; \
42 __nbytes -= 1; \
43 ((byte *) dst_bp)[0] = __x; \
44 dst_bp += 1; \
45 } \
46 } while (0)
47
48 /* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
49 beginning at the bytes right before the pointers and continuing towards
50 smaller addresses. Don't assume anything about alignment of the
51 pointers. */
52 #define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
53 do \
54 { \
55 size_t __nbytes = (nbytes); \
56 while (__nbytes > 0) \
57 { \
58 byte __x; \
59 src_ep -= 1; \
60 __x = ((byte *) src_ep)[0]; \
61 dst_ep -= 1; \
62 __nbytes -= 1; \
63 ((byte *) dst_ep)[0] = __x; \
64 } \
65 } while (0)
66
67 /* end of stuff from memcopy.h */
68
69 void *
70 memmove (dest, src, len)
71 void *dest;
72 const void *src;
73 size_t len;
74 {
75 unsigned long int dstp = (long int) dest;
76 unsigned long int srcp = (long int) src;
77
78 /* This test makes the forward copying code be used whenever possible.
79 Reduces the working set. */
80 if (dstp - srcp >= len) /* *Unsigned* compare! */
81 {
82 /* Copy from the beginning to the end. */
83 #if 0 /* screw all this */
84 /* If there not too few bytes to copy, use word copy. */
85 if (len >= OP_T_THRES)
86 {
87 /* Copy just a few bytes to make DSTP aligned. */
88 len -= (-dstp) % OPSIZ;
89 BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
90
91 /* Copy whole pages from SRCP to DSTP by virtual address
92 manipulation, as much as possible. */
93
94 PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
95
96 /* Copy from SRCP to DSTP taking advantage of the known
97 alignment of DSTP. Number of bytes remaining is put
98 in the third argument, i.e. in LEN. This number may
99 vary from machine to machine. */
100
101 WORD_COPY_FWD (dstp, srcp, len, len);
102
103 /* Fall out and copy the tail. */
104 }
105
106 /* There are just a few bytes to copy. Use byte memory operations. */
107 #endif
108 BYTE_COPY_FWD (dstp, srcp, len);
109 }
110 else
111 {
112 /* Copy from the end to the beginning. */
113 srcp += len;
114 dstp += len;
115
116 #if 0 /* ditto */
117 /* If there not too few bytes to copy, use word copy. */
118 if (len >= OP_T_THRES)
119 {
120 /* Copy just a few bytes to make DSTP aligned. */
121 len -= dstp % OPSIZ;
122 BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
123
124 /* Copy from SRCP to DSTP taking advantage of the known
125 alignment of DSTP. Number of bytes remaining is put
126 in the third argument, i.e. in LEN. This number may
127 vary from machine to machine. */
128
129 WORD_COPY_BWD (dstp, srcp, len, len);
130
131 /* Fall out and copy the tail. */
132 }
133 #endif
134 /* There are just a few bytes to copy. Use byte memory operations. */
135 BYTE_COPY_BWD (dstp, srcp, len);
136 }
137
138 return (dest);
139 }