/* * Copyright (c) 2010, ETH Zurich. * All rights reserved. * * This file is distributed under the terms in the attached LICENSE file. * If you do not find this file, copies can be found by writing to: * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. */ #include #include #define LOWBITS (sizeof(uintptr_t)-1) void *memmove(void *s1, const void *s2, size_t n) { uintptr_t from = (uintptr_t)s2; uintptr_t to = (uintptr_t)s1; if (to <= from) { // Work forwards if (((from ^ to) & LOWBITS) == 0) { // They have the same alignment // Copy bytes until aligned to a word boundary while (n != 0 && ((from & LOWBITS) != 0)) { *(char *)to = *(const char *)from; from++; to++; n--; } // Copy words while(n >= sizeof(uintptr_t)) { *(uintptr_t *)to = *(const uintptr_t *)from; from += sizeof(uintptr_t); to += sizeof(uintptr_t); n -= sizeof(uintptr_t); } } // Copy (remaining) bytes while (n != 0) { *(char *)to = *(const char *)from; from++; to++; n--; } } else { // Work backwards from += n; to += n; if (((from ^ to) & LOWBITS) == 0) { // They have the same alignment // Copy bytes until aligned to a word boundary while (n != 0 && ((from & LOWBITS) != 0)) { from--; to--; *(char *)to = *(const char *)from; n--; } // Copy words while(n >= sizeof(uintptr_t)) { from -= sizeof(uintptr_t); to -= sizeof(uintptr_t); *(uintptr_t *)to = *(const uintptr_t *)from; n -= sizeof(uintptr_t); } } // Copy (remaining) bytes while (n != 0) { from--; to--; *(char *)to = *(const char *)from; n--; } } return s1; }