1 /*
  2  *  This program is free software; you can redistribute it and/or modify
  3  *  it under the terms of the GNU General Public License as published by
  4  *  the Free Software Foundation; either version 2 of the License, or
  5  *  (at your option) any later version.
  6  *
  7  *  This program is distributed in the hope that it will be useful,
  8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10  *  GNU Library General Public License for more details.
 11  *
 12  *  You should have received a copy of the GNU General Public License
 13  *  along with this program; if not, write to the Free Software
 14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 15  *
 16  * Copyright (C) 2005,2006 Ralf Huesing <ralf@stormbind.net>
 17  *
 18  */
 19 
 20 #include "rh_memory.h"
 21 
 22 void * rh_memcpy (void *pdst, const void *src, size_t n)
 23 {
 24         char    *dst = pdst;
 25 
 26         /* copy mostly "inlined" on short buffers
 27          * the switch() performes very well (-: */
 28         if (n < PAGE_ALIGN_THRESOLD+WORD_SIZE) {
 29 byte_cpy:
 30                 for (;;) {
 31                         switch (n) {
 32                         case  0:  return pdst;
 33                         case  1:  rh_memcpy1 (dst, src); return pdst;
 34                         case  2:  rh_memcpy2 (dst, src); return pdst;
 35                         case  3:  rh_memcpy3 (dst, src); return pdst;
 36                         case  4:  rh_memcpy4 (dst, src); return pdst;
 37                         case  5:  rh_memcpy5 (dst, src); return pdst;
 38                         case  6:  rh_memcpy6 (dst, src); return pdst;
 39                         case  7:  rh_memcpy7 (dst, src); return pdst;
 40                         case  8:  rh_memcpy8 (dst, src); return pdst;
 41                         case  9:  rh_memcpy9 (dst, src); return pdst;
 42                         case 10: rh_memcpy10 (dst, src); return pdst;
 43                         case 11: rh_memcpy11 (dst, src); return pdst;
 44                         case 12: rh_memcpy12 (dst, src); return pdst;
 45                         case 13: rh_memcpy13 (dst, src); return pdst;
 46                         case 14: rh_memcpy14 (dst, src); return pdst;
 47                         case 15: rh_memcpy15 (dst, src); return pdst;
 48                         case 16: rh_memcpy16 (dst, src); return pdst;
 49                         }
 50 
 51                         /* copy two words.
 52                          * they are always smaller then 16 byte on 32/64bit */
 53                         do {
 54                                 WORD_CPY(dst,src,0);
 55                                 WORD_CPY(dst,src,1);
 56                                 WORD_INC(dst,2);
 57                                 WORD_INC(src,2);
 58                         } while ( (n-=(WORD_SIZE*2)) > (WORD_SIZE*2)-1);
 59 
 60                 } /* for (;;) */
 61         }
 62         
 63         /* align `dst' on a word boundary */
 64         while (WORD_OFFSET(dst)) {
 65                 BYTE_CPY(dst,src,0);
 66                 --n;
 67                 BYTE_INC(src, 1);
 68                 BYTE_INC(dst, 1);
 69         }
 70 
 71         /* align `dst' on the fourth word-boundary in the current page */
 72         switch ( (PAGE_OFFSET(dst) / 4) % WORD_SIZE ) {
 73         case 3:
 74                 WORD_CPY(dst,src,0);
 75                 WORD_CPY(dst,src,1);
 76                 WORD_CPY(dst,src,2);
 77                 WORD_INC(dst, 3);
 78                 WORD_INC(src, 3);
 79                 n -= WORD_SIZE * 3;
 80                 break;
 81         case 2:
 82                 WORD_CPY(dst,src,0);
 83                 WORD_CPY(dst,src,1);
 84                 WORD_INC(dst, 2);
 85                 WORD_INC(src, 2);
 86                 n -= WORD_SIZE * 2;
 87                 break;
 88         case 1:
 89                 WORD_CPY(dst,src,0);
 90                 WORD_INC(dst, 1);
 91                 WORD_INC(src, 1);
 92                 n -= WORD_SIZE * 1;             
 93         }
 94         
 95         /* copy four words at once */
 96         for (;n > (WORD_SIZE*4)-1; n -= WORD_SIZE*4) {
 97                 WORD_CPY(dst,src,0);
 98                 WORD_CPY(dst,src,1);
 99                 WORD_CPY(dst,src,2);
100                 WORD_CPY(dst,src,3);
101                 
102                 WORD_INC(src, 4);
103                 WORD_INC(dst, 4);
104         }
105                 
106         /* copy remaining words/bytes */
107         goto byte_cpy;
108 }


syntax highlighted by Code2HTML, v. 0.9.1