Path: blob/master/arch/x86/include/asm/arch_hweight.h
10821 views
#ifndef _ASM_X86_HWEIGHT_H1#define _ASM_X86_HWEIGHT_H23#ifdef CONFIG_64BIT4/* popcnt %edi, %eax -- redundant REX prefix for alignment */5#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"6/* popcnt %rdi, %rax */7#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"8#define REG_IN "D"9#define REG_OUT "a"10#else11/* popcnt %eax, %eax */12#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"13#define REG_IN "a"14#define REG_OUT "a"15#endif1617/*18* __sw_hweightXX are called from within the alternatives below19* and callee-clobbered registers need to be taken care of. See20* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective21* compiler switches.22*/23static inline unsigned int __arch_hweight32(unsigned int w)24{25unsigned int res = 0;2627asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT)28: "="REG_OUT (res)29: REG_IN (w));3031return res;32}3334static inline unsigned int __arch_hweight16(unsigned int w)35{36return __arch_hweight32(w & 0xffff);37}3839static inline unsigned int __arch_hweight8(unsigned int w)40{41return __arch_hweight32(w & 0xff);42}4344static inline unsigned long __arch_hweight64(__u64 w)45{46unsigned long res = 0;4748#ifdef CONFIG_X86_3249return __arch_hweight32((u32)w) +50__arch_hweight32((u32)(w >> 32));51#else52asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)53: "="REG_OUT (res)54: REG_IN (w));55#endif /* CONFIG_X86_32 */5657return res;58}5960#endif616263