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