aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-3.2/309-optimize_mips_memcpy_memset_cache.patch
blob: f3eebc6c2a6d5ef44662c5be276898c5c882de35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
--- a/arch/mips/lib/memset.S
+++ b/arch/mips/lib/memset.S
@@ -19,6 +19,8 @@
 #define LONG_S_R sdr
 #endif
 
+#include "prefetch.h"
+
 #define EX(insn,reg,addr,handler)			\
 9:	insn	reg, addr;				\
 	.section __ex_table,"a"; 			\
@@ -75,6 +77,8 @@ FEXPORT(__bzero)
 	bnez		t0, .Lsmall_memset
 	 andi		t0, a0, LONGMASK	/* aligned? */
 
+	prefetch_store a0, a2, t2, t3, t4
+
 #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
 	beqz		t0, 1f
 	 PTR_SUBU	t0, LONGSIZE		/* alignment in bytes */
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -354,7 +354,7 @@ unsigned long get_wchan(struct task_stru
 #define prefetch(x) __builtin_prefetch((x), 0, 1)
 
 #define ARCH_HAS_PREFETCHW
-#define prefetchw(x) __builtin_prefetch((x), 1, 1)
+#define prefetchw(x) do {} while (0)
 
 #endif
 
--- /dev/null
+++ b/arch/mips/lib/prefetch.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012  Felix Fietkau <nbd@openwrt.org>
+ */
+
+.macro	prefetch_store	dst, size, temp1, temp2, temp3
+#ifdef CONFIG_CPU_MIPS32
+	li		\temp1, ((1 << CONFIG_MIPS_L1_CACHE_SHIFT) - 1)
+	nor		\temp1, \temp1, \temp1
+
+	and		\temp2, \size, \temp1
+	beqz		\temp2, 2f
+	 nop
+
+	move		\temp2, \dst
+	PTR_ADDIU	\temp2, ((1 << CONFIG_MIPS_L1_CACHE_SHIFT) - 1)
+	and		\temp2, \temp2, \temp1
+
+	move		\temp3, \dst
+	PTR_ADDU	\temp3, \size
+	and		\temp3, \temp3, \temp1
+
+1:	beq		\temp2, \temp3, 2f
+	 nop
+
+	pref		30, 0(\temp2)
+
+	b		1b
+	  PTR_ADDIU	\temp2, (1 << CONFIG_MIPS_L1_CACHE_SHIFT)
+2:
+#endif
+.endm
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -182,6 +182,8 @@
 	.set	at=v1
 #endif
 
+#include "prefetch.h"
+
 /*
  * A combined memcpy/__copy_user
  * __copy_user sets len to 0 for success; else to an upper bound of
@@ -199,6 +201,8 @@ FEXPORT(__copy_user)
 	 */
 #define rem t8
 
+	prefetch_store a0, a2, t0, t1, t2
+
 	R10KCBARRIER(0(ra))
 	/*
 	 * The "issue break"s below are very approximate.
--- a/arch/mips/lib/memcpy-inatomic.S
+++ b/arch/mips/lib/memcpy-inatomic.S
@@ -182,6 +182,8 @@
 	.set	at=v1
 #endif
 
+#include "prefetch.h"
+
 /*
  * A combined memcpy/__copy_user
  * __copy_user sets len to 0 for success; else to an upper bound of
@@ -196,6 +198,8 @@ LEAF(__copy_user_inatomic)
 	 */
 #define rem t8
 
+	prefetch_store dst, len, t0, t1, t2
+
 	/*
 	 * The "issue break"s below are very approximate.
 	 * Issue delays for dcache fills will perturb the schedule, as will