home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / memory / src / copymem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  3.4 KB  |  162 lines

  1. /*
  2.     (C) 1995 AROS - The Amiga Replacement OS
  3.     $Id: copymem.c 1.1 1995/11/14 22:31:07 digulla Exp digulla $
  4.     $Log: copymem.c $
  5.  * Revision 1.1  1995/11/14  22:31:07  digulla
  6.  * Initial revision
  7.  *
  8.     Desc:
  9.     Lang: english
  10. */
  11. #include "exec_intern.h"
  12. #include <aros/machine.h>
  13.  
  14. /*****************************************************************************
  15.  
  16.     NAME */
  17.     #include <exec/types.h>
  18.     #include <clib/exec_protos.h>
  19.  
  20.     __AROS_LH3I(void, CopyMem,
  21.  
  22. /*  SYNOPSIS */
  23.     __AROS_LA(APTR         , source, A0),
  24.     __AROS_LA(APTR         , dest, A1),
  25.     __AROS_LA(unsigned long, size, D0),
  26.  
  27. /*  LOCATION */
  28.     struct ExecBase *, SysBase, 104, Exec)
  29.  
  30. /*  FUNCTION
  31.     This is a fast memory to memory copy function. It copies
  32.     arbitrary amounts of memory with arbitrary alignments. The
  33.     routine tries to be smart and uses optimized copies if
  34.     this is possible.
  35.  
  36.     INPUTS
  37.     source - These bytes are copied to dest
  38.     dest - This is the destination for size bytes starting at source
  39.     size - This many bytes will be copied.
  40.  
  41.     RESULT
  42.     None.
  43.  
  44.     NOTES
  45.     The routine can't handle situations where the destination is
  46.     somewhere in source (eg. insert elements in an array).
  47.  
  48.     EXAMPLE
  49.     char ptr1[] = "Some text.";
  50.     char ptr2[32];
  51.  
  52.     CopyMem (ptr1, ptr2, strlen (ptr1));
  53.  
  54.     BUGS
  55.  
  56.     SEE ALSO
  57.     CopyMemQuick()
  58.  
  59.     INTERNALS
  60.  
  61.     HISTORY
  62.     21-10-95    digulla automatically created from
  63.                 include:clib/exec_protos.h
  64.                 Written the code.
  65.     26-10-95    digulla adjusted to new calling scheme
  66.     17-12-95    digulla Incorporated code by Matthias Fleischner
  67.  
  68. *****************************************************************************/
  69. {
  70.     __AROS_FUNC_INIT
  71.     UBYTE *src=(UBYTE *)source,*dst=(UBYTE *)dest;
  72.     ULONG mis,low,high;
  73.  
  74.     /*
  75.     I try to fall back to copying LONGs if possible. To do this I copy
  76.     the misaligned leading bytes of the source first. I use sizeof(LONG)
  77.     instead of LONGALIGN because it is sometimes faster.
  78.     */
  79.     mis = (ULONG)src&(sizeof(LONG)-1);
  80.     if(mis>size)
  81.     mis=size;
  82.     size-=mis;
  83.  
  84.     if(mis)
  85.       do
  86.     *dst++=*src++;
  87.       while(--mis);
  88.  
  89.     /*
  90.     The source has the right alignment now. All I need to do is to
  91.     check if this is true for the destination, too.
  92.     */
  93.     if(!((ULONG)dst&(LONGALIGN-1)))
  94.     {
  95.     /* Yes. I may copy LONGs. */
  96.     LONG *s=(LONG *)src,*d=(LONG *)dst;
  97.     ULONG longs;
  98.  
  99.     /* How many of them? */
  100.     longs=size/sizeof(LONG);
  101.  
  102.     /*
  103.         To minimize the loop overhead I copy more than one (eight) LONG per
  104.         iteration. Therefore I need to split size into size/8 and the rest.
  105.     */
  106.     low =longs&7;
  107.     high=longs/8;
  108.  
  109.     /* Then copy for both parts */
  110.     if(low)
  111.         do
  112.         *d++=*s++;
  113.         while(--low);
  114.  
  115.     if(high)
  116.         do
  117.         {
  118.         *d++=*s++;
  119.         *d++=*s++;
  120.         *d++=*s++;
  121.         *d++=*s++;
  122.         *d++=*s++;
  123.         *d++=*s++;
  124.         *d++=*s++;
  125.         *d++=*s++;
  126.         }while(--high);
  127.  
  128.     /* Get the rest. */
  129.     size&=sizeof(LONG)-1;
  130.     src=(UBYTE *)s;
  131.     dst=(UBYTE *)d;
  132.     }
  133.  
  134.     /* The remaining job can only be done by copying single bytes. */
  135.     low =size&7;
  136.     high=size/8;
  137.  
  138.     /* Copy for both parts */
  139.     if(low)
  140.       do
  141.     *dst++=*src++;
  142.       while(--low);
  143.  
  144.     /*
  145.     Partly unrolled copying loop. The predecrement helps the compiler to
  146.     find the best possible loop. The if is necessary to do this.
  147.     */
  148.     if(high)
  149.     do
  150.     {
  151.         *dst++=*src++;
  152.         *dst++=*src++;
  153.         *dst++=*src++;
  154.         *dst++=*src++;
  155.         *dst++=*src++;
  156.         *dst++=*src++;
  157.         *dst++=*src++;
  158.         *dst++=*src++;
  159.     }while(--high);
  160.     __AROS_FUNC_EXIT
  161. } /* CopyMem */
  162.