104 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			104 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * This file is subject to the terms and conditions of the GNU General Public | ||
|  |  * License.  See the file COPYING in the main directory of this archive | ||
|  |  * for more details. | ||
|  |  */ | ||
|  | 
 | ||
|  | #include <linux/module.h>
 | ||
|  | #include <linux/string.h>
 | ||
|  | 
 | ||
|  | void *memmove(void *dest, const void *src, size_t n) | ||
|  | { | ||
|  | 	void *xdest = dest; | ||
|  | 	size_t temp; | ||
|  | 
 | ||
|  | 	if (!n) | ||
|  | 		return xdest; | ||
|  | 
 | ||
|  | 	if (dest < src) { | ||
|  | 		if ((long)dest & 1) { | ||
|  | 			char *cdest = dest; | ||
|  | 			const char *csrc = src; | ||
|  | 			*cdest++ = *csrc++; | ||
|  | 			dest = cdest; | ||
|  | 			src = csrc; | ||
|  | 			n--; | ||
|  | 		} | ||
|  | 		if (n > 2 && (long)dest & 2) { | ||
|  | 			short *sdest = dest; | ||
|  | 			const short *ssrc = src; | ||
|  | 			*sdest++ = *ssrc++; | ||
|  | 			dest = sdest; | ||
|  | 			src = ssrc; | ||
|  | 			n -= 2; | ||
|  | 		} | ||
|  | 		temp = n >> 2; | ||
|  | 		if (temp) { | ||
|  | 			long *ldest = dest; | ||
|  | 			const long *lsrc = src; | ||
|  | 			temp--; | ||
|  | 			do | ||
|  | 				*ldest++ = *lsrc++; | ||
|  | 			while (temp--); | ||
|  | 			dest = ldest; | ||
|  | 			src = lsrc; | ||
|  | 		} | ||
|  | 		if (n & 2) { | ||
|  | 			short *sdest = dest; | ||
|  | 			const short *ssrc = src; | ||
|  | 			*sdest++ = *ssrc++; | ||
|  | 			dest = sdest; | ||
|  | 			src = ssrc; | ||
|  | 		} | ||
|  | 		if (n & 1) { | ||
|  | 			char *cdest = dest; | ||
|  | 			const char *csrc = src; | ||
|  | 			*cdest = *csrc; | ||
|  | 		} | ||
|  | 	} else { | ||
|  | 		dest = (char *)dest + n; | ||
|  | 		src = (const char *)src + n; | ||
|  | 		if ((long)dest & 1) { | ||
|  | 			char *cdest = dest; | ||
|  | 			const char *csrc = src; | ||
|  | 			*--cdest = *--csrc; | ||
|  | 			dest = cdest; | ||
|  | 			src = csrc; | ||
|  | 			n--; | ||
|  | 		} | ||
|  | 		if (n > 2 && (long)dest & 2) { | ||
|  | 			short *sdest = dest; | ||
|  | 			const short *ssrc = src; | ||
|  | 			*--sdest = *--ssrc; | ||
|  | 			dest = sdest; | ||
|  | 			src = ssrc; | ||
|  | 			n -= 2; | ||
|  | 		} | ||
|  | 		temp = n >> 2; | ||
|  | 		if (temp) { | ||
|  | 			long *ldest = dest; | ||
|  | 			const long *lsrc = src; | ||
|  | 			temp--; | ||
|  | 			do | ||
|  | 				*--ldest = *--lsrc; | ||
|  | 			while (temp--); | ||
|  | 			dest = ldest; | ||
|  | 			src = lsrc; | ||
|  | 		} | ||
|  | 		if (n & 2) { | ||
|  | 			short *sdest = dest; | ||
|  | 			const short *ssrc = src; | ||
|  | 			*--sdest = *--ssrc; | ||
|  | 			dest = sdest; | ||
|  | 			src = ssrc; | ||
|  | 		} | ||
|  | 		if (n & 1) { | ||
|  | 			char *cdest = dest; | ||
|  | 			const char *csrc = src; | ||
|  | 			*--cdest = *--csrc; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	return xdest; | ||
|  | } | ||
|  | EXPORT_SYMBOL(memmove); |