|
@@ -7,7 +7,10 @@
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
* published by the Free Software Foundation.
|
|
|
*/
|
|
|
+#include <linux/hardirq.h>
|
|
|
#include <asm-generic/xor.h>
|
|
|
+#include <asm/hwcap.h>
|
|
|
+#include <asm/neon.h>
|
|
|
|
|
|
#define __XOR(a1, a2) a1 ^= a2
|
|
|
|
|
@@ -138,4 +141,74 @@ static struct xor_block_template xor_block_arm4regs = {
|
|
|
xor_speed(&xor_block_arm4regs); \
|
|
|
xor_speed(&xor_block_8regs); \
|
|
|
xor_speed(&xor_block_32regs); \
|
|
|
+ NEON_TEMPLATES; \
|
|
|
} while (0)
|
|
|
+
|
|
|
+#ifdef CONFIG_KERNEL_MODE_NEON
|
|
|
+
|
|
|
+extern struct xor_block_template const xor_block_neon_inner;
|
|
|
+
|
|
|
+static void
|
|
|
+xor_neon_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
|
|
|
+{
|
|
|
+ if (in_interrupt()) {
|
|
|
+ xor_arm4regs_2(bytes, p1, p2);
|
|
|
+ } else {
|
|
|
+ kernel_neon_begin();
|
|
|
+ xor_block_neon_inner.do_2(bytes, p1, p2);
|
|
|
+ kernel_neon_end();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+xor_neon_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
|
|
|
+ unsigned long *p3)
|
|
|
+{
|
|
|
+ if (in_interrupt()) {
|
|
|
+ xor_arm4regs_3(bytes, p1, p2, p3);
|
|
|
+ } else {
|
|
|
+ kernel_neon_begin();
|
|
|
+ xor_block_neon_inner.do_3(bytes, p1, p2, p3);
|
|
|
+ kernel_neon_end();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+xor_neon_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
|
|
|
+ unsigned long *p3, unsigned long *p4)
|
|
|
+{
|
|
|
+ if (in_interrupt()) {
|
|
|
+ xor_arm4regs_4(bytes, p1, p2, p3, p4);
|
|
|
+ } else {
|
|
|
+ kernel_neon_begin();
|
|
|
+ xor_block_neon_inner.do_4(bytes, p1, p2, p3, p4);
|
|
|
+ kernel_neon_end();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+xor_neon_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
|
|
|
+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
|
|
|
+{
|
|
|
+ if (in_interrupt()) {
|
|
|
+ xor_arm4regs_5(bytes, p1, p2, p3, p4, p5);
|
|
|
+ } else {
|
|
|
+ kernel_neon_begin();
|
|
|
+ xor_block_neon_inner.do_5(bytes, p1, p2, p3, p4, p5);
|
|
|
+ kernel_neon_end();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static struct xor_block_template xor_block_neon = {
|
|
|
+ .name = "neon",
|
|
|
+ .do_2 = xor_neon_2,
|
|
|
+ .do_3 = xor_neon_3,
|
|
|
+ .do_4 = xor_neon_4,
|
|
|
+ .do_5 = xor_neon_5
|
|
|
+};
|
|
|
+
|
|
|
+#define NEON_TEMPLATES \
|
|
|
+ do { if (cpu_has_neon()) xor_speed(&xor_block_neon); } while (0)
|
|
|
+#else
|
|
|
+#define NEON_TEMPLATES
|
|
|
+#endif
|