summaryrefslogtreecommitdiffstats
path: root/kernel/arch/sparc/lib/memmove.S
diff options
context:
space:
mode:
authorYunhong Jiang <yunhong.jiang@intel.com>2015-08-04 12:17:53 -0700
committerYunhong Jiang <yunhong.jiang@intel.com>2015-08-04 15:44:42 -0700
commit9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch)
tree1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/arch/sparc/lib/memmove.S
parent98260f3884f4a202f9ca5eabed40b1354c489b29 (diff)
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base. It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and the base is: commit 0917f823c59692d751951bf5ea699a2d1e2f26a2 Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Sat Jul 25 12:13:34 2015 +0200 Prepare v4.1.3-rt3 Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> We lose all the git history this way and it's not good. We should apply another opnfv project repo in future. Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423 Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/arch/sparc/lib/memmove.S')
-rw-r--r--kernel/arch/sparc/lib/memmove.S59
1 files changed, 59 insertions, 0 deletions
diff --git a/kernel/arch/sparc/lib/memmove.S b/kernel/arch/sparc/lib/memmove.S
new file mode 100644
index 000000000..857ad4f89
--- /dev/null
+++ b/kernel/arch/sparc/lib/memmove.S
@@ -0,0 +1,59 @@
+/* memmove.S: Simple memmove implementation.
+ *
+ * Copyright (C) 1997, 2004 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1996, 1997, 1998, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <linux/linkage.h>
+
+ .text
+ENTRY(memmove) /* o0=dst o1=src o2=len */
+ brz,pn %o2, 99f
+ mov %o0, %g1
+
+ cmp %o0, %o1
+ bleu,pt %xcc, 2f
+ add %o1, %o2, %g7
+ cmp %g7, %o0
+ bleu,pt %xcc, memcpy
+ add %o0, %o2, %o5
+ sub %g7, 1, %o1
+
+ sub %o5, 1, %o0
+1: ldub [%o1], %g7
+ subcc %o2, 1, %o2
+ sub %o1, 1, %o1
+ stb %g7, [%o0]
+ bne,pt %icc, 1b
+ sub %o0, 1, %o0
+99:
+ retl
+ mov %g1, %o0
+
+ /* We can't just call memcpy for these memmove cases. On some
+ * chips the memcpy uses cache initializing stores and when dst
+ * and src are close enough, those can clobber the source data
+ * before we've loaded it in.
+ */
+2: or %o0, %o1, %g7
+ or %o2, %g7, %g7
+ andcc %g7, 0x7, %g0
+ bne,pn %xcc, 4f
+ nop
+
+3: ldx [%o1], %g7
+ add %o1, 8, %o1
+ subcc %o2, 8, %o2
+ add %o0, 8, %o0
+ bne,pt %icc, 3b
+ stx %g7, [%o0 - 0x8]
+ ba,a,pt %xcc, 99b
+
+4: ldub [%o1], %g7
+ add %o1, 1, %o1
+ subcc %o2, 1, %o2
+ add %o0, 1, %o0
+ bne,pt %icc, 4b
+ stb %g7, [%o0 - 0x1]
+ ba,a,pt %xcc, 99b
+ENDPROC(memmove)