diff options
author | Matthew Wilcox <mawilcox@microsoft.com> | 2017-09-08 19:14:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-08 21:26:48 -0400 |
commit | fd1d362600e2d2edb6262d8e05661424c1a315bf (patch) | |
tree | a7386f39d0c7ba19711542ad74c55681842add70 | |
parent | 4c51248533adcfb01ba704ce5993ecbad5cc4c99 (diff) |
ARM: implement memset32 & memset64
Reuse the existing optimised memset implementation to implement an
optimised memset32 and memset64.
Link: http://lkml.kernel.org/r/20170720184539.31609-5-willy@infradead.org
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
Reviewed-by: Russell King <rmk+kernel@armlinux.org.uk>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: David Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/arm/include/asm/string.h | 14 | ||||
-rw-r--r-- | arch/arm/kernel/armksyms.c | 2 | ||||
-rw-r--r-- | arch/arm/lib/memset.S | 24 |
3 files changed, 34 insertions, 6 deletions
diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aad0fc1..fe1c6af3a1b1 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h | |||
@@ -24,6 +24,20 @@ extern void * memchr(const void *, int, __kernel_size_t); | |||
24 | #define __HAVE_ARCH_MEMSET | 24 | #define __HAVE_ARCH_MEMSET |
25 | extern void * memset(void *, int, __kernel_size_t); | 25 | extern void * memset(void *, int, __kernel_size_t); |
26 | 26 | ||
27 | #define __HAVE_ARCH_MEMSET32 | ||
28 | extern void *__memset32(uint32_t *, uint32_t v, __kernel_size_t); | ||
29 | static inline void *memset32(uint32_t *p, uint32_t v, __kernel_size_t n) | ||
30 | { | ||
31 | return __memset32(p, v, n * 4); | ||
32 | } | ||
33 | |||
34 | #define __HAVE_ARCH_MEMSET64 | ||
35 | extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); | ||
36 | static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) | ||
37 | { | ||
38 | return __memset64(p, v, n * 8, v >> 32); | ||
39 | } | ||
40 | |||
27 | extern void __memzero(void *ptr, __kernel_size_t n); | 41 | extern void __memzero(void *ptr, __kernel_size_t n); |
28 | 42 | ||
29 | #define memset(p,v,n) \ | 43 | #define memset(p,v,n) \ |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 8e8d20cdbce7..5266fd9ad6b4 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -87,6 +87,8 @@ EXPORT_SYMBOL(__raw_writesl); | |||
87 | EXPORT_SYMBOL(strchr); | 87 | EXPORT_SYMBOL(strchr); |
88 | EXPORT_SYMBOL(strrchr); | 88 | EXPORT_SYMBOL(strrchr); |
89 | EXPORT_SYMBOL(memset); | 89 | EXPORT_SYMBOL(memset); |
90 | EXPORT_SYMBOL(__memset32); | ||
91 | EXPORT_SYMBOL(__memset64); | ||
90 | EXPORT_SYMBOL(memcpy); | 92 | EXPORT_SYMBOL(memcpy); |
91 | EXPORT_SYMBOL(memmove); | 93 | EXPORT_SYMBOL(memmove); |
92 | EXPORT_SYMBOL(memchr); | 94 | EXPORT_SYMBOL(memchr); |
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S index 3c65e3bd790f..ed6d35d9cdb5 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S | |||
@@ -28,7 +28,7 @@ UNWIND( .fnstart ) | |||
28 | 1: orr r1, r1, r1, lsl #8 | 28 | 1: orr r1, r1, r1, lsl #8 |
29 | orr r1, r1, r1, lsl #16 | 29 | orr r1, r1, r1, lsl #16 |
30 | mov r3, r1 | 30 | mov r3, r1 |
31 | cmp r2, #16 | 31 | 7: cmp r2, #16 |
32 | blt 4f | 32 | blt 4f |
33 | 33 | ||
34 | #if ! CALGN(1)+0 | 34 | #if ! CALGN(1)+0 |
@@ -41,7 +41,7 @@ UNWIND( .fnend ) | |||
41 | UNWIND( .fnstart ) | 41 | UNWIND( .fnstart ) |
42 | UNWIND( .save {r8, lr} ) | 42 | UNWIND( .save {r8, lr} ) |
43 | mov r8, r1 | 43 | mov r8, r1 |
44 | mov lr, r1 | 44 | mov lr, r3 |
45 | 45 | ||
46 | 2: subs r2, r2, #64 | 46 | 2: subs r2, r2, #64 |
47 | stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. | 47 | stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time. |
@@ -73,11 +73,11 @@ UNWIND( .fnend ) | |||
73 | UNWIND( .fnstart ) | 73 | UNWIND( .fnstart ) |
74 | UNWIND( .save {r4-r8, lr} ) | 74 | UNWIND( .save {r4-r8, lr} ) |
75 | mov r4, r1 | 75 | mov r4, r1 |
76 | mov r5, r1 | 76 | mov r5, r3 |
77 | mov r6, r1 | 77 | mov r6, r1 |
78 | mov r7, r1 | 78 | mov r7, r3 |
79 | mov r8, r1 | 79 | mov r8, r1 |
80 | mov lr, r1 | 80 | mov lr, r3 |
81 | 81 | ||
82 | cmp r2, #96 | 82 | cmp r2, #96 |
83 | tstgt ip, #31 | 83 | tstgt ip, #31 |
@@ -114,7 +114,7 @@ UNWIND( .fnstart ) | |||
114 | tst r2, #4 | 114 | tst r2, #4 |
115 | strne r1, [ip], #4 | 115 | strne r1, [ip], #4 |
116 | /* | 116 | /* |
117 | * When we get here, we've got less than 4 bytes to zero. We | 117 | * When we get here, we've got less than 4 bytes to set. We |
118 | * may have an unaligned pointer as well. | 118 | * may have an unaligned pointer as well. |
119 | */ | 119 | */ |
120 | 5: tst r2, #2 | 120 | 5: tst r2, #2 |
@@ -135,3 +135,15 @@ UNWIND( .fnstart ) | |||
135 | UNWIND( .fnend ) | 135 | UNWIND( .fnend ) |
136 | ENDPROC(memset) | 136 | ENDPROC(memset) |
137 | ENDPROC(mmioset) | 137 | ENDPROC(mmioset) |
138 | |||
139 | ENTRY(__memset32) | ||
140 | UNWIND( .fnstart ) | ||
141 | mov r3, r1 @ copy r1 to r3 and fall into memset64 | ||
142 | UNWIND( .fnend ) | ||
143 | ENDPROC(__memset32) | ||
144 | ENTRY(__memset64) | ||
145 | UNWIND( .fnstart ) | ||
146 | mov ip, r0 @ preserve r0 as return value | ||
147 | b 7b @ jump into the middle of memset | ||
148 | UNWIND( .fnend ) | ||
149 | ENDPROC(__memset64) | ||