linux/arch/nios2/lib/memmove.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
   3 * Copyright (C) 2004 Microtronix Datacom Ltd
   4 *
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 */
   9
  10#include <linux/types.h>
  11#include <linux/string.h>
  12
  13#ifdef __HAVE_ARCH_MEMMOVE
  14void *memmove(void *d, const void *s, size_t count)
  15{
  16        unsigned long dst, src;
  17
  18        if (!count)
  19                return d;
  20
  21        if (d < s) {
  22                dst = (unsigned long) d;
  23                src = (unsigned long) s;
  24
  25                if ((count < 8) || ((dst ^ src) & 3))
  26                        goto restup;
  27
  28                if (dst & 1) {
  29                        *(char *)dst++ = *(char *)src++;
  30                        count--;
  31                }
  32                if (dst & 2) {
  33                        *(short *)dst = *(short *)src;
  34                        src += 2;
  35                        dst += 2;
  36                        count -= 2;
  37                }
  38                while (count > 3) {
  39                        *(long *)dst = *(long *)src;
  40                        src += 4;
  41                        dst += 4;
  42                        count -= 4;
  43                }
  44restup:
  45                while (count--)
  46                        *(char *)dst++ = *(char *)src++;
  47        } else {
  48                dst = (unsigned long) d + count;
  49                src = (unsigned long) s + count;
  50
  51                if ((count < 8) || ((dst ^ src) & 3))
  52                        goto restdown;
  53
  54                if (dst & 1) {
  55                        src--;
  56                        dst--;
  57                        count--;
  58                        *(char *)dst = *(char *)src;
  59                }
  60                if (dst & 2) {
  61                        src -= 2;
  62                        dst -= 2;
  63                        count -= 2;
  64                        *(short *)dst = *(short *)src;
  65                }
  66                while (count > 3) {
  67                        src -= 4;
  68                        dst -= 4;
  69                        count -= 4;
  70                        *(long *)dst = *(long *)src;
  71                }
  72restdown:
  73                while (count--) {
  74                        src--;
  75                        dst--;
  76                        *(char *)dst = *(char *)src;
  77                }
  78        }
  79
  80        return d;
  81}
  82#endif /* __HAVE_ARCH_MEMMOVE */
  83