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
  13void *memmove(void *d, const void *s, size_t count)
  14{
  15        unsigned long dst, src;
  16
  17        if (!count)
  18                return d;
  19
  20        if (d < s) {
  21                dst = (unsigned long) d;
  22                src = (unsigned long) s;
  23
  24                if ((count < 8) || ((dst ^ src) & 3))
  25                        goto restup;
  26
  27                if (dst & 1) {
  28                        *(char *)dst++ = *(char *)src++;
  29                        count--;
  30                }
  31                if (dst & 2) {
  32                        *(short *)dst = *(short *)src;
  33                        src += 2;
  34                        dst += 2;
  35                        count -= 2;
  36                }
  37                while (count > 3) {
  38                        *(long *)dst = *(long *)src;
  39                        src += 4;
  40                        dst += 4;
  41                        count -= 4;
  42                }
  43restup:
  44                while (count--)
  45                        *(char *)dst++ = *(char *)src++;
  46        } else {
  47                dst = (unsigned long) d + count;
  48                src = (unsigned long) s + count;
  49
  50                if ((count < 8) || ((dst ^ src) & 3))
  51                        goto restdown;
  52
  53                if (dst & 1) {
  54                        src--;
  55                        dst--;
  56                        count--;
  57                        *(char *)dst = *(char *)src;
  58                }
  59                if (dst & 2) {
  60                        src -= 2;
  61                        dst -= 2;
  62                        count -= 2;
  63                        *(short *)dst = *(short *)src;
  64                }
  65                while (count > 3) {
  66                        src -= 4;
  67                        dst -= 4;
  68                        count -= 4;
  69                        *(long *)dst = *(long *)src;
  70                }
  71restdown:
  72                while (count--) {
  73                        src--;
  74                        dst--;
  75                        *(char *)dst = *(char *)src;
  76                }
  77        }
  78
  79        return d;
  80}
  81