home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / exec / copymem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-09  |  3.6 KB  |  177 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: copymem.c,v 1.10 1997/01/01 03:46:07 ldp Exp $
  4.     $Log: copymem.c,v $
  5.     Revision 1.10  1997/01/01 03:46:07  ldp
  6.     Committed Amiga native (support) code
  7.  
  8.     Changed clib to proto
  9.  
  10.     Revision 1.9  1996/12/10 13:51:41  aros
  11.     Moved all #include's in the first column so makedepend can see it.
  12.  
  13.     Revision 1.8  1996/10/24 15:50:46  aros
  14.     Use the official AROS macros over the __AROS versions.
  15.  
  16.     Revision 1.7  1996/10/23 14:21:28  aros
  17.     Renamed a few macros from XYZ to AROS_XYZ so we know which if from AROS and
  18.     which not.
  19.  
  20.     Revision 1.6  1996/10/19 17:07:25  aros
  21.     Include <aros/machine.h> instead of machine.h
  22.  
  23.     Revision 1.5  1996/09/13 17:51:22  digulla
  24.     Use IPTR
  25.  
  26.     Revision 1.4  1996/08/13 13:55:59  digulla
  27.     Replaced AROS_LA by AROS_LHA
  28.     Replaced some AROS_LH*I by AROS_LH*
  29.     Sorted and added includes
  30.  
  31.     Revision 1.3  1996/08/01 17:41:07  digulla
  32.     Added standard header for all files
  33.  
  34.     Desc:
  35.     Lang:
  36. */
  37. #include <aros/libcall.h>
  38. #include <aros/machine.h>
  39. #include <proto/exec.h>
  40.  
  41. /*****************************************************************************
  42.  
  43.     NAME */
  44.  
  45.     AROS_LH3I(void, CopyMem,
  46.  
  47. /*  SYNOPSIS */
  48.     AROS_LHA(APTR,  source, A0),
  49.     AROS_LHA(APTR,  dest,   A1),
  50.     AROS_LHA(ULONG, size,   D0),
  51.  
  52. /*  LOCATION */
  53.     struct ExecBase *, SysBase, 104, Exec)
  54.  
  55. /*  FUNCTION
  56.     Copy some memory from one destination in memory to another using
  57.     a fast copying method.
  58.  
  59.     INPUTS
  60.     source - Pointer to source area
  61.     dest   - Pointer to destination
  62.     size   - number of bytes to copy
  63.  
  64.     RESULT
  65.  
  66.     NOTES
  67.     The source and destination area are not allowed to overlap.
  68.  
  69.     EXAMPLE
  70.  
  71.     BUGS
  72.  
  73.     SEE ALSO
  74.     CopyMemQuick()
  75.  
  76.     INTERNALS
  77.  
  78.     HISTORY
  79.     24-10-95    Created by M. Fleischer
  80.  
  81. ******************************************************************************/
  82. {
  83.     AROS_LIBFUNC_INIT
  84.  
  85.     UBYTE *src=(UBYTE *)source,*dst=(UBYTE *)dest;
  86.     ULONG mis,low,high;
  87.  
  88.     /*
  89.     I try to fall back to copying LONGs if possible. To do this I copy
  90.     the misaligned leading bytes of the source first. I use sizeof(LONG)
  91.     instead of LONGALIGN because it is sometimes faster.
  92.     */
  93.     mis =(IPTR)src&(sizeof(LONG)-1);
  94.     if(mis>size)
  95.     mis=size;
  96.     size-=mis;
  97.  
  98.     if(mis)
  99.       do
  100.     *dst++=*src++;
  101.       while(--mis);
  102.  
  103.     /*
  104.     The source has the right alignment now. All I need to do is to
  105.     check if this is true for the destination, too.
  106.     */
  107.     if(!((IPTR)dst&(AROS_LONGALIGN-1)))
  108.     {
  109.     /* Yes. I may copy LONGs. */
  110.     LONG *s=(LONG *)src,*d=(LONG *)dst;
  111.     ULONG longs;
  112.  
  113.     /* How many of them? */
  114.     longs=size/sizeof(LONG);
  115.  
  116.     /*
  117.         To minimize the loop overhead I copy more than one (eight) LONG per
  118.         iteration. Therefore I need to split size into size/8 and the rest.
  119.     */
  120.     low =longs&7;
  121.     high=longs/8;
  122.  
  123.     /* Then copy for both parts */
  124.     if(low)
  125.         do
  126.         *d++=*s++;
  127.         while(--low);
  128.  
  129.     if(high)
  130.         do
  131.         {
  132.         *d++=*s++;
  133.         *d++=*s++;
  134.         *d++=*s++;
  135.         *d++=*s++;
  136.         *d++=*s++;
  137.         *d++=*s++;
  138.         *d++=*s++;
  139.         *d++=*s++;
  140.         }while(--high);
  141.  
  142.     /* Get the rest. */
  143.     size&=sizeof(LONG)-1;
  144.     src=(UBYTE *)s;
  145.     dst=(UBYTE *)d;
  146.     }
  147.  
  148.     /* The remaining job can only be done by copying single bytes. */
  149.     low =size&7;
  150.     high=size/8;
  151.  
  152.     /* Copy for both parts */
  153.     if(low)
  154.       do
  155.     *dst++=*src++;
  156.       while(--low);
  157.  
  158.     /*
  159.     Partly unrolled copying loop. The predecrement helps the compiler to
  160.     find the best possible loop. The if is necessary to do this.
  161.     */
  162.     if(high)
  163.     do
  164.     {
  165.         *dst++=*src++;
  166.         *dst++=*src++;
  167.         *dst++=*src++;
  168.         *dst++=*src++;
  169.         *dst++=*src++;
  170.         *dst++=*src++;
  171.         *dst++=*src++;
  172.         *dst++=*src++;
  173.     }while(--high);
  174.     AROS_LIBFUNC_EXIT
  175. } /* CopyMem */
  176.  
  177.