From: Zhaoxiu Zeng <zhaoxiu.z...@gmail.com>

Use runtime patching for ppc64, lifted from hweight_64

Signed-off-by: Zhaoxiu Zeng <zhaoxiu.z...@gmail.com>
---
 arch/powerpc/include/asm/bitops.h |  11 +++
 arch/powerpc/lib/Makefile         |   2 +-
 arch/powerpc/lib/parity_64.S      | 142 ++++++++++++++++++++++++++++++++++++++
 arch/powerpc/lib/ppc_ksyms.c      |   5 ++
 4 files changed, 159 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/lib/parity_64.S

diff --git a/arch/powerpc/include/asm/bitops.h 
b/arch/powerpc/include/asm/bitops.h
index 59abc62..cd34030 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -269,8 +269,19 @@ unsigned int __arch_hweight16(unsigned int w);
 unsigned int __arch_hweight32(unsigned int w);
 unsigned long __arch_hweight64(__u64 w);
 #include <asm-generic/bitops/const_hweight.h>
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+       w &= 0xf;
+       return ((PARITY_MAGIC) >> w) & 1;
+}
+unsigned int __arch_parity8(unsigned int w);
+unsigned int __arch_parity16(unsigned int w);
+unsigned int __arch_parity32(unsigned int w);
+unsigned int __arch_parity64(__u64 w);
+#include <asm-generic/bitops/const_parity.h>
 #else
 #include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
 #endif
 
 #include <asm-generic/bitops/find.h>
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index ba21be1..cae2e7f 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_PPC32)   += div64.o copy_32.o
 
 obj64-y        += copypage_64.o copyuser_64.o usercopy_64.o mem_64.o 
hweight_64.o \
           copyuser_power7.o string_64.o copypage_power7.o memcpy_power7.o \
-          memcpy_64.o memcmp_64.o
+          memcpy_64.o memcmp_64.o parity_64.o
 
 obj64-$(CONFIG_SMP)    += locks.o
 obj64-$(CONFIG_ALTIVEC)        += vmx-helper.o
diff --git a/arch/powerpc/lib/parity_64.S b/arch/powerpc/lib/parity_64.S
new file mode 100644
index 0000000..7eff686
--- /dev/null
+++ b/arch/powerpc/lib/parity_64.S
@@ -0,0 +1,142 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Author: Zhaoxiu Zeng <zhaoxiu.z...@gmail.com>
+ */
+
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+
+/*
+ * This file contains the generic code to calculate the odd parity
+ * of N-bits number, and the POPCNT feature sections.
+ *
+ * Note: This code relies on -mminimal-toc
+ */
+
+/*
+ * unsigned int __arch_parity8(unsigned int w)
+ */
+_GLOBAL(__arch_parity8)
+BEGIN_FTR_SECTION
+       srdi    r4,r3,4
+       xor     r3,r3,r4
+       clrldi  r3,r3,64-4
+       li      r4,0x6996
+       srd     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+FTR_SECTION_ELSE
+       PPC_POPCNTB(R3,R3)
+       clrldi  r3,r3,64-1
+       blr
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+/*
+ * unsigned int __arch_parity16(unsigned int w)
+ */
+_GLOBAL(__arch_parity16)
+BEGIN_FTR_SECTION
+       srdi    r4,r3,8
+       xor     r3,r3,r4
+       srdi    r4,r3,4
+       xor     r3,r3,r4
+       clrldi  r3,r3,64-4
+       li      r4,0x6996
+       srd     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+FTR_SECTION_ELSE
+  BEGIN_FTR_SECTION_NESTED(50)
+       PPC_POPCNTB(R3,R3)
+       srdi    r4,r3,8
+       add     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+  FTR_SECTION_ELSE_NESTED(50)
+       clrlwi  r3,r3,16
+       PPC_POPCNTW(R3,R3)
+       clrldi  r3,r3,64-1
+       blr
+  ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 50)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+/*
+ * unsigned int __arch_parity32(unsigned int w)
+ */
+_GLOBAL(__arch_parity32)
+BEGIN_FTR_SECTION
+       srdi    r4,r3,16
+       xor     r3,r3,r4
+       srdi    r4,r3,8
+       xor     r3,r3,r4
+       srdi    r4,r3,4
+       xor     r3,r3,r4
+       clrldi  r3,r3,64-4
+       li      r4,0x6996
+       srd     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+FTR_SECTION_ELSE
+  BEGIN_FTR_SECTION_NESTED(51)
+       PPC_POPCNTB(R3,R3)
+       srdi    r4,r3,16
+       add     r3,r4,r3
+       srdi    r4,r3,8
+       add     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+  FTR_SECTION_ELSE_NESTED(51)
+       PPC_POPCNTW(R3,R3)
+       clrldi  r3,r3,64-1
+       blr
+  ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 51)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
+
+/*
+ * unsigned int __arch_parity64(__u64 w)
+ */
+_GLOBAL(__arch_parity64)
+BEGIN_FTR_SECTION
+       srdi    r4,r3,32
+       xor     r3,r3,r4
+       srdi    r4,r3,16
+       xor     r3,r3,r4
+       srdi    r4,r3,8
+       xor     r3,r3,r4
+       srdi    r4,r3,4
+       xor     r3,r3,r4
+       clrldi  r3,r3,64-4
+       li      r4,0x6996
+       srd     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+FTR_SECTION_ELSE
+  BEGIN_FTR_SECTION_NESTED(52)
+       PPC_POPCNTB(R3,R3)
+       srdi    r4,r3,32
+       add     r3,r4,r3
+       srdi    r4,r3,16
+       add     r3,r4,r3
+       srdi    r4,r3,8
+       add     r3,r4,r3
+       clrldi  r3,r3,64-1
+       blr
+  FTR_SECTION_ELSE_NESTED(52)
+       PPC_POPCNTD(R3,R3)
+       clrldi  r3,r3,64-1
+       blr
+  ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 52)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB)
diff --git a/arch/powerpc/lib/ppc_ksyms.c b/arch/powerpc/lib/ppc_ksyms.c
index c422812..1ccfc29 100644
--- a/arch/powerpc/lib/ppc_ksyms.c
+++ b/arch/powerpc/lib/ppc_ksyms.c
@@ -30,4 +30,9 @@ EXPORT_SYMBOL(__arch_hweight8);
 EXPORT_SYMBOL(__arch_hweight16);
 EXPORT_SYMBOL(__arch_hweight32);
 EXPORT_SYMBOL(__arch_hweight64);
+
+EXPORT_SYMBOL(__arch_parity8);
+EXPORT_SYMBOL(__arch_parity16);
+EXPORT_SYMBOL(__arch_parity32);
+EXPORT_SYMBOL(__arch_parity64);
 #endif
-- 
2.5.0


_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to