18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch> 38c2ecf20Sopenharmony_ci * Copyright (C) 2004 Microtronix Datacom Ltd 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 68c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 78c2ecf20Sopenharmony_ci * for more details. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/types.h> 118c2ecf20Sopenharmony_ci#include <linux/string.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_civoid *memmove(void *d, const void *s, size_t count) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci unsigned long dst, src; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci if (!count) 188c2ecf20Sopenharmony_ci return d; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci if (d < s) { 218c2ecf20Sopenharmony_ci dst = (unsigned long) d; 228c2ecf20Sopenharmony_ci src = (unsigned long) s; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci if ((count < 8) || ((dst ^ src) & 3)) 258c2ecf20Sopenharmony_ci goto restup; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci if (dst & 1) { 288c2ecf20Sopenharmony_ci *(char *)dst++ = *(char *)src++; 298c2ecf20Sopenharmony_ci count--; 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci if (dst & 2) { 328c2ecf20Sopenharmony_ci *(short *)dst = *(short *)src; 338c2ecf20Sopenharmony_ci src += 2; 348c2ecf20Sopenharmony_ci dst += 2; 358c2ecf20Sopenharmony_ci count -= 2; 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci while (count > 3) { 388c2ecf20Sopenharmony_ci *(long *)dst = *(long *)src; 398c2ecf20Sopenharmony_ci src += 4; 408c2ecf20Sopenharmony_ci dst += 4; 418c2ecf20Sopenharmony_ci count -= 4; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_cirestup: 448c2ecf20Sopenharmony_ci while (count--) 458c2ecf20Sopenharmony_ci *(char *)dst++ = *(char *)src++; 468c2ecf20Sopenharmony_ci } else { 478c2ecf20Sopenharmony_ci dst = (unsigned long) d + count; 488c2ecf20Sopenharmony_ci src = (unsigned long) s + count; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci if ((count < 8) || ((dst ^ src) & 3)) 518c2ecf20Sopenharmony_ci goto restdown; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (dst & 1) { 548c2ecf20Sopenharmony_ci src--; 558c2ecf20Sopenharmony_ci dst--; 568c2ecf20Sopenharmony_ci count--; 578c2ecf20Sopenharmony_ci *(char *)dst = *(char *)src; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci if (dst & 2) { 608c2ecf20Sopenharmony_ci src -= 2; 618c2ecf20Sopenharmony_ci dst -= 2; 628c2ecf20Sopenharmony_ci count -= 2; 638c2ecf20Sopenharmony_ci *(short *)dst = *(short *)src; 648c2ecf20Sopenharmony_ci } 658c2ecf20Sopenharmony_ci while (count > 3) { 668c2ecf20Sopenharmony_ci src -= 4; 678c2ecf20Sopenharmony_ci dst -= 4; 688c2ecf20Sopenharmony_ci count -= 4; 698c2ecf20Sopenharmony_ci *(long *)dst = *(long *)src; 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_cirestdown: 728c2ecf20Sopenharmony_ci while (count--) { 738c2ecf20Sopenharmony_ci src--; 748c2ecf20Sopenharmony_ci dst--; 758c2ecf20Sopenharmony_ci *(char *)dst = *(char *)src; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci return d; 808c2ecf20Sopenharmony_ci} 81