summaryrefslogtreecommitdiff
path: root/arch/m68knommu/lib/memmove.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-02-15 17:51:18 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-02-15 17:51:18 -0800
commit048f039f3ee39417d5a6a1eb73bf01f935e9ed3f (patch)
treeb7064e7874528e72500e1ed57bc054974822687c /arch/m68knommu/lib/memmove.c
parentb90be8662b1d7bd84637edb8f96e904f865a2fe2 (diff)
parent86d306c96046be597147d9f8ff163a052b3845d8 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu: m68knommu: set flow handler for secondary interrupt controller of 5249 m68knommu: remove use of IRQ_FLG_LOCK from 68360 platform support m68knommu: fix dereference of port.tty m68knommu: add missing linker __modver section m68knommu: fix mis-named variable int set_irq_chip loop m68knommu: add optimize memmove() function m68k: remove arch specific non-optimized memcmp() m68knommu: fix use of un-defined _TIF_WORK_MASK m68knommu: Rename m548x_wdt.c to m54xx_wdt.c m68knommu: fix m548x_wdt.c compilation after headers renaming m68knommu: Remove dependencies on nonexistent M68KNOMMU
Diffstat (limited to 'arch/m68knommu/lib/memmove.c')
-rw-r--r--arch/m68knommu/lib/memmove.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/arch/m68knommu/lib/memmove.c b/arch/m68knommu/lib/memmove.c
new file mode 100644
index 000000000000..b3dcfe9dab7e
--- /dev/null
+++ b/arch/m68knommu/lib/memmove.c
@@ -0,0 +1,105 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#define __IN_STRING_C
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+ void *xdest = dest;
+ size_t temp;
+
+ if (!n)
+ return xdest;
+
+ if (dest < src) {
+ if ((long)dest & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ *cdest++ = *csrc++;
+ dest = cdest;
+ src = csrc;
+ n--;
+ }
+ if (n > 2 && (long)dest & 2) {
+ short *sdest = dest;
+ const short *ssrc = src;
+ *sdest++ = *ssrc++;
+ dest = sdest;
+ src = ssrc;
+ n -= 2;
+ }
+ temp = n >> 2;
+ if (temp) {
+ long *ldest = dest;
+ const long *lsrc = src;
+ temp--;
+ do
+ *ldest++ = *lsrc++;
+ while (temp--);
+ dest = ldest;
+ src = lsrc;
+ }
+ if (n & 2) {
+ short *sdest = dest;
+ const short *ssrc = src;
+ *sdest++ = *ssrc++;
+ dest = sdest;
+ src = ssrc;
+ }
+ if (n & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ *cdest = *csrc;
+ }
+ } else {
+ dest = (char *)dest + n;
+ src = (const char *)src + n;
+ if ((long)dest & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ *--cdest = *--csrc;
+ dest = cdest;
+ src = csrc;
+ n--;
+ }
+ if (n > 2 && (long)dest & 2) {
+ short *sdest = dest;
+ const short *ssrc = src;
+ *--sdest = *--ssrc;
+ dest = sdest;
+ src = ssrc;
+ n -= 2;
+ }
+ temp = n >> 2;
+ if (temp) {
+ long *ldest = dest;
+ const long *lsrc = src;
+ temp--;
+ do
+ *--ldest = *--lsrc;
+ while (temp--);
+ dest = ldest;
+ src = lsrc;
+ }
+ if (n & 2) {
+ short *sdest = dest;
+ const short *ssrc = src;
+ *--sdest = *--ssrc;
+ dest = sdest;
+ src = ssrc;
+ }
+ if (n & 1) {
+ char *cdest = dest;
+ const char *csrc = src;
+ *--cdest = *--csrc;
+ }
+ }
+ return xdest;
+}
+EXPORT_SYMBOL(memmove);