Subversion Repositories Kolibri OS

Rev

Rev 4872 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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