↑ 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