From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754304AbcEPPu5 (ORCPT ); Mon, 16 May 2016 11:50:57 -0400 Received: from m12-16.163.com ([220.181.12.16]:34786 "EHLO m12-16.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752812AbcEPPuz (ORCPT ); Mon, 16 May 2016 11:50:55 -0400 Subject: Re: [patch V4 09/31] bitops: Add x86-specific parity functions To: Peter Zijlstra References: <1462955158-28394-1-git-send-email-zengzhaoxiu@163.com> <1462958205-24890-1-git-send-email-zengzhaoxiu@163.com> <20160511093139.GA3206@twins.programming.kicks-ass.net> Cc: linux-kernel@vger.kernel.org, bp@suse.de, gnomes@lxorguk.ukuu.org.uk, andi@firstfloor.org, dvyukov@google.com, Zhaoxiu Zeng , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , x86@kernel.org, Denys Vlasenko From: Zhaoxiu Zeng Message-ID: <08232c92-c3ab-9f3e-7c04-a815b04993db@163.com> Date: Mon, 16 May 2016 23:49:05 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 MIME-Version: 1.0 In-Reply-To: <20160511093139.GA3206@twins.programming.kicks-ass.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CM-TRANSID: EMCowACHu8Hx6zlXlg4GAw--.30395S3 X-Coremail-Antispam: 1Uf129KBjvJXoW7Ww4UKr15WFyrJrW3GFyxGrg_yoW8XFyDpr y7Kr90yr4vqF43ZF4rKa95JF1rtr4Yqw4DJr98t3y8XFsruF1UJF1FgFW2krWFkFn5ua4j yw47Xa4jq3WkCaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jMtC7UUUUU= X-Originating-IP: [14.215.38.181] X-CM-SenderInfo: p2hqw6xkdr5xrx6rljoofrz/1tbiGRVrgFXlS1X7TAAAs+ Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2016/5/11 17:31, Peter Zijlstra wrote: > Please use the GEN_*_RMWcc() stuff to avoid the setpo where possible. Setpo is better. In most cases, we need to store the parity, or compare it with other variables. For example, in drivers/net/ethernet/broadcom/tg3.c, static int tg3_test_nvram(struct tg3 *tp) { ...... if (parity8(data[i]) == !!parity[i]) goto out; ...... } If use GEN_BINARY_RMWcc stuff, static inline unsigned int __arch_parity8(unsigned int w) { GEN_BINARY_RMWcc("testb", w, "er", 0xff, "%0", "po"); } gcc's output: 1c2fe: 0f b6 54 05 a0 movzbl -0x60(%rbp,%rax,1),%edx 1c303: 89 55 9c mov %edx,-0x64(%rbp) 1c306: f6 45 9c ff testb $0xff,-0x64(%rbp) 1c30a: 7b 2c jnp 1c338 1c30c: 31 c9 xor %ecx,%ecx 1c30e: 31 d2 xor %edx,%edx 1c310: 80 7c 05 bc 00 cmpb $0x0,-0x44(%rbp,%rax,1) 1c315: 0f 95 c2 setne %dl 1c318: 39 ca cmp %ecx,%edx 1c31a: 75 d8 jne 1c2f4 ...... 1c338: b9 01 00 00 00 mov $0x1,%ecx 1c33d: eb cf jmp 1c30e Else if use setpo, static inline unsigned int __arch_parity8(unsigned int w) { u8 res; asm("test $0xff, %1; setpo %0" : "=qm" (res) : "rm" (w) : "memory"); return res; } gcc's output: 1c2fe: 31 c9 xor %ecx,%ecx 1c300: 0f b6 44 15 a0 movzbl -0x60(%rbp,%rdx,1),%eax 1c305: a9 ff 00 00 00 test $0xff,%eax 1c30a: 0f 9b c0 setnp %al 1c30d: 80 7c 15 bc 00 cmpb $0x0,-0x44(%rbp,%rdx,1) 1c312: 0f b6 c0 movzbl %al,%eax 1c315: 0f 95 c1 setne %cl 1c318: 39 c8 cmp %ecx,%eax 1c31a: 75 d8 jne 1c2f4