Subversion Repositories Kolibri OS

Rev

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