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