1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_X86_HWEIGHT_H 3 #define _ASM_X86_HWEIGHT_H 4 5 #include <asm/cpufeatures.h> 6 7 #ifdef CONFIG_64BIT 8 #define REG_IN "D" 9 #define REG_OUT "a" 10 #else 11 #define REG_IN "a" 12 #define REG_OUT "a" 13 #endif 14 15 static __always_inline unsigned int __arch_hweight32(unsigned int w) 16 { 17 unsigned int res; 18 19 asm_inline (ALTERNATIVE("call __sw_hweight32", 20 "popcntl %[val], %[cnt]", X86_FEATURE_POPCNT) 21 : [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT 22 : [val] REG_IN (w)); 23 24 return res; 25 } 26 27 static inline unsigned int __arch_hweight16(unsigned int w) 28 { 29 return __arch_hweight32(w & 0xffff); 30 } 31 32 static inline unsigned int __arch_hweight8(unsigned int w) 33 { 34 return __arch_hweight32(w & 0xff); 35 } 36 37 #ifdef CONFIG_X86_32 38 static inline unsigned long __arch_hweight64(__u64 w) 39 { 40 return __arch_hweight32((u32)w) + 41 __arch_hweight32((u32)(w >> 32)); 42 } 43 #else 44 static __always_inline unsigned long __arch_hweight64(__u64 w) 45 { 46 unsigned long res; 47 48 asm_inline (ALTERNATIVE("call __sw_hweight64", 49 "popcntq %[val], %[cnt]", X86_FEATURE_POPCNT) 50 : [cnt] "=" REG_OUT (res), ASM_CALL_CONSTRAINT 51 : [val] REG_IN (w)); 52 53 return res; 54 } 55 #endif /* CONFIG_X86_32 */ 56 57 #endif 58