Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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