1 /* 2 * Copyright (C) 2007 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 /** @file 20 * 21 * Optimised string operations 22 * 23 */ 24 25 FILE_LICENCE ( GPL2_OR_LATER ); 26 27 #include <string.h> 28 29 /** 30 * Copy memory area 31 * 32 * @v dest Destination address 33 * @v src Source address 34 * @v len Length 35 * @ret dest Destination address 36 */ 37 void * __memcpy ( void *dest, const void *src, size_t len ) { 38 void *edi = dest; 39 const void *esi = src; 40 int discard_ecx; 41 42 /* We often do large dword-aligned and dword-length block 43 * moves. Using movsl rather than movsb speeds these up by 44 * around 32%. 45 */ 46 if ( len >> 2 ) { 47 __asm__ __volatile__ ( "rep movsl" 48 : "=&D" ( edi ), "=&S" ( esi ), 49 "=&c" ( discard_ecx ) 50 : "0" ( edi ), "1" ( esi ), 51 "2" ( len >> 2 ) 52 : "memory" ); 53 } 54 if ( len & 0x02 ) { 55 __asm__ __volatile__ ( "movsw" : "=&D" ( edi ), "=&S" ( esi ) 56 : "0" ( edi ), "1" ( esi ) : "memory" ); 57 } 58 if ( len & 0x01 ) { 59 __asm__ __volatile__ ( "movsb" : "=&D" ( edi ), "=&S" ( esi ) 60 : "0" ( edi ), "1" ( esi ) : "memory" ); 61 } 62 return dest; 63 } 64