1*1bb92983SJerome Forissier // SPDX-License-Identifier: BSD-3-Clause 2b0104773SPascal Brand /* 3b0104773SPascal Brand * Copyright (c) 1994-2009 Red Hat, Inc. 4b0104773SPascal Brand * All rights reserved. 5b0104773SPascal Brand * 6b0104773SPascal Brand * Redistribution and use in source and binary forms, with or without 7b0104773SPascal Brand * modification, are permitted provided that the following conditions are met: 8b0104773SPascal Brand * 9b0104773SPascal Brand * 1. Redistributions of source code must retain the above copyright notice, 10b0104773SPascal Brand * this list of conditions and the following disclaimer. 11b0104773SPascal Brand * 12b0104773SPascal Brand * 2. Redistributions in binary form must reproduce the above copyright notice, 13b0104773SPascal Brand * this list of conditions and the following disclaimer in the documentation 14b0104773SPascal Brand * and/or other materials provided with the distribution. 15b0104773SPascal Brand * 16b0104773SPascal Brand * 3. Neither the name of the copyright holder nor the names of its 17b0104773SPascal Brand * contributors may be used to endorse or promote products derived from this 18b0104773SPascal Brand * software without specific prior written permission. 19b0104773SPascal Brand * 20b0104773SPascal Brand * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21b0104773SPascal Brand * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22b0104773SPascal Brand * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23b0104773SPascal Brand * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24b0104773SPascal Brand * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25b0104773SPascal Brand * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26b0104773SPascal Brand * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27b0104773SPascal Brand * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28b0104773SPascal Brand * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29b0104773SPascal Brand * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30b0104773SPascal Brand * POSSIBILITY OF SUCH DAMAGE. 31b0104773SPascal Brand */ 32b0104773SPascal Brand 33b0104773SPascal Brand /* 34b0104773SPascal Brand FUNCTION 35b0104773SPascal Brand <<memcpy>>---copy memory regions 36b0104773SPascal Brand 37b0104773SPascal Brand ANSI_SYNOPSIS 38b0104773SPascal Brand #include <string.h> 39b0104773SPascal Brand void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>); 40b0104773SPascal Brand 41b0104773SPascal Brand TRAD_SYNOPSIS 42b0104773SPascal Brand #include <string.h> 43b0104773SPascal Brand void *memcpy(<[out]>, <[in]>, <[n]> 44b0104773SPascal Brand void *<[out]>; 45b0104773SPascal Brand void *<[in]>; 46b0104773SPascal Brand size_t <[n]>; 47b0104773SPascal Brand 48b0104773SPascal Brand DESCRIPTION 49b0104773SPascal Brand This function copies <[n]> bytes from the memory region 50b0104773SPascal Brand pointed to by <[in]> to the memory region pointed to by 51b0104773SPascal Brand <[out]>. 52b0104773SPascal Brand 53b0104773SPascal Brand If the regions overlap, the behavior is undefined. 54b0104773SPascal Brand 55b0104773SPascal Brand RETURNS 56b0104773SPascal Brand <<memcpy>> returns a pointer to the first byte of the <[out]> 57b0104773SPascal Brand region. 58b0104773SPascal Brand 59b0104773SPascal Brand PORTABILITY 60b0104773SPascal Brand <<memcpy>> is ANSI C. 61b0104773SPascal Brand 62b0104773SPascal Brand <<memcpy>> requires no supporting OS subroutines. 63b0104773SPascal Brand 64b0104773SPascal Brand QUICKREF 65b0104773SPascal Brand memcpy ansi pure 66b0104773SPascal Brand */ 67b0104773SPascal Brand 68b0104773SPascal Brand #include "_ansi.h" 69b0104773SPascal Brand #include <string.h> 70b0104773SPascal Brand 71b0104773SPascal Brand /* Nonzero if either X or Y is not aligned on a "long" boundary. */ 72b0104773SPascal Brand #define UNALIGNED(X, Y) \ 73b0104773SPascal Brand (((long)X & (sizeof(long) - 1)) | ((long)Y & (sizeof(long) - 1))) 74b0104773SPascal Brand 75b0104773SPascal Brand /* How many bytes are copied each iteration of the 4X unrolled loop. */ 76b0104773SPascal Brand #define BIGBLOCKSIZE (sizeof(long) << 2) 77b0104773SPascal Brand 78b0104773SPascal Brand /* How many bytes are copied each iteration of the word copy loop. */ 79b0104773SPascal Brand #define LITTLEBLOCKSIZE (sizeof(long)) 80b0104773SPascal Brand 81b0104773SPascal Brand /* Threshhold for punting to the byte copier. */ 82b0104773SPascal Brand #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE) 83b0104773SPascal Brand 84b0104773SPascal Brand _PTR 85b0104773SPascal Brand _DEFUN(memcpy, (dst0, src0, len0), _PTR dst0 _AND _CONST _PTR src0 _AND 86b0104773SPascal Brand size_t len0) 87b0104773SPascal Brand { 88b0104773SPascal Brand #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) 89b0104773SPascal Brand char *dst = (char *)dst0; 90b0104773SPascal Brand char *src = (char *)src0; 91b0104773SPascal Brand 92b0104773SPascal Brand _PTR save = dst0; 93b0104773SPascal Brand 94b0104773SPascal Brand while (len0--) 95b0104773SPascal Brand *dst++ = *src++; 96b0104773SPascal Brand 97b0104773SPascal Brand return save; 98b0104773SPascal Brand #else 99b0104773SPascal Brand char *dst = dst0; 100b0104773SPascal Brand _CONST char *src = src0; 101b0104773SPascal Brand long *aligned_dst; 102b0104773SPascal Brand _CONST long *aligned_src; 103b0104773SPascal Brand 104b0104773SPascal Brand /* If the size is small, or either SRC or DST is unaligned, 105b0104773SPascal Brand then punt into the byte copy loop. This should be rare. */ 106b0104773SPascal Brand if (!TOO_SMALL(len0) && !UNALIGNED(src, dst)) { 107b0104773SPascal Brand aligned_dst = (long *)dst; 108b0104773SPascal Brand aligned_src = (long *)src; 109b0104773SPascal Brand 110b0104773SPascal Brand /* Copy 4X long words at a time if possible. */ 111b0104773SPascal Brand while (len0 >= BIGBLOCKSIZE) { 112b0104773SPascal Brand *aligned_dst++ = *aligned_src++; 113b0104773SPascal Brand *aligned_dst++ = *aligned_src++; 114b0104773SPascal Brand *aligned_dst++ = *aligned_src++; 115b0104773SPascal Brand *aligned_dst++ = *aligned_src++; 116b0104773SPascal Brand len0 -= BIGBLOCKSIZE; 117b0104773SPascal Brand } 118b0104773SPascal Brand 119b0104773SPascal Brand /* Copy one long word at a time if possible. */ 120b0104773SPascal Brand while (len0 >= LITTLEBLOCKSIZE) { 121b0104773SPascal Brand *aligned_dst++ = *aligned_src++; 122b0104773SPascal Brand len0 -= LITTLEBLOCKSIZE; 123b0104773SPascal Brand } 124b0104773SPascal Brand 125b0104773SPascal Brand /* Pick up any residual with a byte copier. */ 126b0104773SPascal Brand dst = (char *)aligned_dst; 127b0104773SPascal Brand src = (char *)aligned_src; 128b0104773SPascal Brand } 129b0104773SPascal Brand 130b0104773SPascal Brand while (len0--) 131b0104773SPascal Brand *dst++ = *src++; 132b0104773SPascal Brand 133b0104773SPascal Brand return dst0; 134b0104773SPascal Brand #endif /* not PREFER_SIZE_OVER_SPEED */ 135b0104773SPascal Brand } 136