Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
memmove.c
Go to the documentation of this file.
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation, version 2.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  * NON INFRINGEMENT. See the GNU General Public License for
12  * more details.
13  */
14 
15 #include <linux/types.h>
16 #include <linux/string.h>
17 #include <linux/module.h>
18 
19 void *memmove(void *dest, const void *src, size_t n)
20 {
21  if ((const char *)src >= (char *)dest + n
22  || (char *)dest >= (const char *)src + n) {
23  /* We found no overlap, so let memcpy do all the heavy
24  * lifting (prefetching, etc.)
25  */
26  return memcpy(dest, src, n);
27  }
28 
29  if (n != 0) {
30  const uint8_t *in;
31  uint8_t x;
32  uint8_t *out;
33  int stride;
34 
35  if (src < dest) {
36  /* copy backwards */
37  in = (const uint8_t *)src + n - 1;
38  out = (uint8_t *)dest + n - 1;
39  stride = -1;
40  } else {
41  /* copy forwards */
42  in = (const uint8_t *)src;
43  out = (uint8_t *)dest;
44  stride = 1;
45  }
46 
47  /* Manually software-pipeline this loop. */
48  x = *in;
49  in += stride;
50 
51  while (--n != 0) {
52  *out = x;
53  out += stride;
54  x = *in;
55  in += stride;
56  }
57 
58  *out = x;
59  }
60 
61  return dest;
62 }