Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753033AbcDNDKF (ORCPT ); Wed, 13 Apr 2016 23:10:05 -0400 Received: from m50-138.163.com ([123.125.50.138]:47766 "EHLO m50-138.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752980AbcDNDKB (ORCPT ); Wed, 13 Apr 2016 23:10:01 -0400 From: zengzhaoxiu@163.com To: linux-kernel@vger.kernel.org, sam@ravnborg.org Cc: Zhaoxiu Zeng , "David S. Miller" , "wim.coekaerts@oracle.com" , Guenter Roeck , Julian Calaby , sparclinux@vger.kernel.org Subject: [PATCH V3 08/29] Add sparc-specific parity functions Date: Thu, 14 Apr 2016 11:08:01 +0800 Message-Id: <1460603291-4851-1-git-send-email-zengzhaoxiu@163.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1460601525-3822-1-git-send-email-zengzhaoxiu@163.com> References: <1460601525-3822-1-git-send-email-zengzhaoxiu@163.com> X-CM-TRANSID: C9GowAD3_4eoCQ9XI77WAg--.52402S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxuw15uFWfXFW3uFy3Aw4fXwb_yoWxGF4rp3 WkCrn5Kr40q34UZrW7CF42vFn3tws3W3Z7Wr9Ikry8trnrJr1UJrn29ayDAry29r18uay8 WFZxWFykWa1ktaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07bUiihUUUUU= X-Originating-IP: [112.95.225.98] X-CM-SenderInfo: p2hqw6xkdr5xrx6rljoofrz/1tbivw1LgFWBRQ-AAgAAsl Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6127 Lines: 222 From: Zhaoxiu Zeng Use runtime patching for sparc64, lifted from hweight Signed-off-by: Zhaoxiu Zeng --- arch/sparc/include/asm/bitops_32.h | 1 + arch/sparc/include/asm/bitops_64.h | 18 ++++++ arch/sparc/kernel/sparc_ksyms_64.c | 6 ++ arch/sparc/lib/Makefile | 2 +- arch/sparc/lib/parity.S | 128 +++++++++++++++++++++++++++++++++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/lib/parity.S diff --git a/arch/sparc/include/asm/bitops_32.h b/arch/sparc/include/asm/bitops_32.h index 600ed1d..8c41896 100644 --- a/arch/sparc/include/asm/bitops_32.h +++ b/arch/sparc/include/asm/bitops_32.h @@ -98,6 +98,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) #include #include #include +#include #include #include #include diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h index 2d52240..999d504 100644 --- a/arch/sparc/include/asm/bitops_64.h +++ b/arch/sparc/include/asm/bitops_64.h @@ -47,6 +47,24 @@ unsigned int __arch_hweight16(unsigned int w); unsigned int __arch_hweight8(unsigned int w); #include + +/* + * parityN: returns the parity of a N-bit word, + * i.e. the number of 1-bits in w modulo 2. + */ + +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 + #include #endif /* __KERNEL__ */ diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c index 9e034f2..7ee0818 100644 --- a/arch/sparc/kernel/sparc_ksyms_64.c +++ b/arch/sparc/kernel/sparc_ksyms_64.c @@ -45,6 +45,12 @@ EXPORT_SYMBOL(__arch_hweight16); EXPORT_SYMBOL(__arch_hweight32); EXPORT_SYMBOL(__arch_hweight64); +/* from parity.S */ +EXPORT_SYMBOL(__arch_parity8); +EXPORT_SYMBOL(__arch_parity16); +EXPORT_SYMBOL(__arch_parity32); +EXPORT_SYMBOL(__arch_parity64); + /* from ffs_ffz.S */ EXPORT_SYMBOL(ffs); EXPORT_SYMBOL(__ffs); diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 3269b02..2dbbcb1 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -39,7 +39,7 @@ lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o parity.o obj-$(CONFIG_SPARC64) += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o diff --git a/arch/sparc/lib/parity.S b/arch/sparc/lib/parity.S new file mode 100644 index 0000000..ff84234 --- /dev/null +++ b/arch/sparc/lib/parity.S @@ -0,0 +1,128 @@ +/* + * 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 + */ + +#include + +/* + * This file contains the generic code to calculate the odd parity + * of N-bits number, and the popc-patches. + */ + + .text + .align 32 + +/* + * unsigned int __arch_parity8(unsigned int w) + */ +ENTRY(__arch_parity8) + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity8) + .section .popc_6insn_patch, "ax" + .word __arch_parity8 + sllx %o0, 64-8, %g1 + popc %g1, %o0 + retl + and %o0, 1, %o0 + nop + nop + .previous + +/* + * unsigned int __arch_parity16(unsigned int w) + */ +ENTRY(__arch_parity16) + srl %o0, 8, %g1 + xor %o0, %g1, %o0 + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity16) + .section .popc_6insn_patch, "ax" + .word __arch_parity16 + sllx %o0, 64-16, %g1 + popc %g1, %o0 + retl + and %o0, 1, %o0 + nop + nop + .previous + +/* + * unsigned int __arch_parity32(unsigned int w) + */ +ENTRY(__arch_parity32) + srl %o0, 16, %g1 + xor %o0, %g1, %o0 + srl %o0, 8, %g1 + xor %o0, %g1, %o0 + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity32) + .section .popc_6insn_patch, "ax" + .word __arch_parity32 + sllx %o0, 64-32, %g1 + popc %g1, %o0 + retl + and %o0, 1, %o0 + nop + nop + .previous + +/* + * unsigned int __arch_parity64(__u64 w) + */ +ENTRY(__arch_parity64) + srlx %o0, 32, %g1 + xor %o0, %g1, %o0 + srl %o0, 16, %g1 + xor %o0, %g1, %o0 + srl %o0, 8, %g1 + xor %o0, %g1, %o0 + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity64) + .section .popc_3insn_patch, "ax" + .word __arch_parity64 + popc %o0, %o0 + retl + and %o0, 1, %o0 + .previous -- 2.5.0