1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2d61931d8SBorislav Petkov #ifndef _ASM_X86_HWEIGHT_H 3d61931d8SBorislav Petkov #define _ASM_X86_HWEIGHT_H 4d61931d8SBorislav Petkov 5cd4d09ecSBorislav Petkov #include <asm/cpufeatures.h> 6cd4d09ecSBorislav Petkov 7d61931d8SBorislav Petkov #ifdef CONFIG_64BIT 8f5967101SBorislav Petkov /* popcnt %edi, %eax */ 9f5967101SBorislav Petkov #define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7" 10d61931d8SBorislav Petkov /* popcnt %rdi, %rax */ 11c59bd568SH. Peter Anvin #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7" 12d61931d8SBorislav Petkov #define REG_IN "D" 13d61931d8SBorislav Petkov #define REG_OUT "a" 14d61931d8SBorislav Petkov #else 15d61931d8SBorislav Petkov /* popcnt %eax, %eax */ 16c59bd568SH. Peter Anvin #define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0" 17d61931d8SBorislav Petkov #define REG_IN "a" 18d61931d8SBorislav Petkov #define REG_OUT "a" 19d61931d8SBorislav Petkov #endif 20d61931d8SBorislav Petkov 21f5967101SBorislav Petkov #define __HAVE_ARCH_SW_HWEIGHT 22f5967101SBorislav Petkov 23d14edb16SDenys Vlasenko static __always_inline unsigned int __arch_hweight32(unsigned int w) 24d61931d8SBorislav Petkov { 25f5967101SBorislav Petkov unsigned int res; 26d61931d8SBorislav Petkov 27c59bd568SH. Peter Anvin asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) 28d61931d8SBorislav Petkov : "="REG_OUT (res) 29d61931d8SBorislav Petkov : REG_IN (w)); 30d61931d8SBorislav Petkov 31d61931d8SBorislav Petkov return res; 32d61931d8SBorislav Petkov } 33d61931d8SBorislav Petkov 34d61931d8SBorislav Petkov static inline unsigned int __arch_hweight16(unsigned int w) 35d61931d8SBorislav Petkov { 36d61931d8SBorislav Petkov return __arch_hweight32(w & 0xffff); 37d61931d8SBorislav Petkov } 38d61931d8SBorislav Petkov 39d61931d8SBorislav Petkov static inline unsigned int __arch_hweight8(unsigned int w) 40d61931d8SBorislav Petkov { 41d61931d8SBorislav Petkov return __arch_hweight32(w & 0xff); 42d61931d8SBorislav Petkov } 43d61931d8SBorislav Petkov 44d14edb16SDenys Vlasenko #ifdef CONFIG_X86_32 45d61931d8SBorislav Petkov static inline unsigned long __arch_hweight64(__u64 w) 46d61931d8SBorislav Petkov { 47d14edb16SDenys Vlasenko return __arch_hweight32((u32)w) + 48d14edb16SDenys Vlasenko __arch_hweight32((u32)(w >> 32)); 49d14edb16SDenys Vlasenko } 50d14edb16SDenys Vlasenko #else 51d14edb16SDenys Vlasenko static __always_inline unsigned long __arch_hweight64(__u64 w) 52d14edb16SDenys Vlasenko { 53f5967101SBorislav Petkov unsigned long res; 54d61931d8SBorislav Petkov 55c59bd568SH. Peter Anvin asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) 56d61931d8SBorislav Petkov : "="REG_OUT (res) 57d61931d8SBorislav Petkov : REG_IN (w)); 58d61931d8SBorislav Petkov 59d61931d8SBorislav Petkov return res; 60d61931d8SBorislav Petkov } 61d14edb16SDenys Vlasenko #endif /* CONFIG_X86_32 */ 62d61931d8SBorislav Petkov 63d61931d8SBorislav Petkov #endif 64