| 122 | */ |
| 123 | #ifndef RT_KLIBC_USING_USER_MEMCPY |
| 124 | void *rt_memcpy(void *dst, const void *src, rt_ubase_t count) |
| 125 | { |
| 126 | #if defined(RT_KLIBC_USING_LIBC_MEMCPY) |
| 127 | return memcpy(dst, src, count); |
| 128 | #elif defined(RT_KLIBC_USING_TINY_MEMCPY) |
| 129 | char *tmp = (char *)dst, *s = (char *)src; |
| 130 | rt_ubase_t len = 0; |
| 131 | |
| 132 | if (tmp <= s || tmp > (s + count)) |
| 133 | { |
| 134 | while (count--) |
| 135 | *tmp ++ = *s ++; |
| 136 | } |
| 137 | else |
| 138 | { |
| 139 | for (len = count; len > 0; len --) |
| 140 | tmp[len - 1] = s[len - 1]; |
| 141 | } |
| 142 | |
| 143 | return dst; |
| 144 | #else |
| 145 | |
| 146 | #define UNALIGNED(X, Y) \ |
| 147 | (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1))) |
| 148 | #define BIGBLOCKSIZE (sizeof (long) << 2) |
| 149 | #define LITTLEBLOCKSIZE (sizeof (long)) |
| 150 | #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE) |
| 151 | |
| 152 | char *dst_ptr = (char *)dst; |
| 153 | char *src_ptr = (char *)src; |
| 154 | long *aligned_dst = RT_NULL; |
| 155 | long *aligned_src = RT_NULL; |
| 156 | rt_ubase_t len = count; |
| 157 | |
| 158 | /* If the size is small, or either SRC or DST is unaligned, |
| 159 | then punt into the byte copy loop. This should be rare. */ |
| 160 | if (!TOO_SMALL(len) && !UNALIGNED(src_ptr, dst_ptr)) |
| 161 | { |
| 162 | aligned_dst = (long *)dst_ptr; |
| 163 | aligned_src = (long *)src_ptr; |
| 164 | |
| 165 | /* Copy 4X long words at a time if possible. */ |
| 166 | while (len >= BIGBLOCKSIZE) |
| 167 | { |
| 168 | *aligned_dst++ = *aligned_src++; |
| 169 | *aligned_dst++ = *aligned_src++; |
| 170 | *aligned_dst++ = *aligned_src++; |
| 171 | *aligned_dst++ = *aligned_src++; |
| 172 | len -= BIGBLOCKSIZE; |
| 173 | } |
| 174 | |
| 175 | /* Copy one long word at a time if possible. */ |
| 176 | while (len >= LITTLEBLOCKSIZE) |
| 177 | { |
| 178 | *aligned_dst++ = *aligned_src++; |
| 179 | len -= LITTLEBLOCKSIZE; |
| 180 | } |
| 181 |
no outgoing calls