1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */ 2f5967101SBorislav Petkov#include <linux/linkage.h> 3784d5699SAl Viro#include <asm/export.h> 4f5967101SBorislav Petkov 5f5967101SBorislav Petkov#include <asm/asm.h> 6f5967101SBorislav Petkov 7f5967101SBorislav Petkov/* 8f5967101SBorislav Petkov * unsigned int __sw_hweight32(unsigned int w) 9f5967101SBorislav Petkov * %rdi: w 10f5967101SBorislav Petkov */ 116dcc5627SJiri SlabySYM_FUNC_START(__sw_hweight32) 12f5967101SBorislav Petkov 13f5967101SBorislav Petkov#ifdef CONFIG_X86_64 14f5967101SBorislav Petkov movl %edi, %eax # w 15f5967101SBorislav Petkov#endif 16f5967101SBorislav Petkov __ASM_SIZE(push,) %__ASM_REG(dx) 17f5967101SBorislav Petkov movl %eax, %edx # w -> t 18f5967101SBorislav Petkov shrl %edx # t >>= 1 19f5967101SBorislav Petkov andl $0x55555555, %edx # t &= 0x55555555 20f5967101SBorislav Petkov subl %edx, %eax # w -= t 21f5967101SBorislav Petkov 22f5967101SBorislav Petkov movl %eax, %edx # w -> t 23f5967101SBorislav Petkov shrl $2, %eax # w_tmp >>= 2 24f5967101SBorislav Petkov andl $0x33333333, %edx # t &= 0x33333333 25f5967101SBorislav Petkov andl $0x33333333, %eax # w_tmp &= 0x33333333 26f5967101SBorislav Petkov addl %edx, %eax # w = w_tmp + t 27f5967101SBorislav Petkov 28f5967101SBorislav Petkov movl %eax, %edx # w -> t 29f5967101SBorislav Petkov shrl $4, %edx # t >>= 4 30f5967101SBorislav Petkov addl %edx, %eax # w_tmp += t 31f5967101SBorislav Petkov andl $0x0f0f0f0f, %eax # w_tmp &= 0x0f0f0f0f 32f5967101SBorislav Petkov imull $0x01010101, %eax, %eax # w_tmp *= 0x01010101 33f5967101SBorislav Petkov shrl $24, %eax # w = w_tmp >> 24 34f5967101SBorislav Petkov __ASM_SIZE(pop,) %__ASM_REG(dx) 35*f94909ceSPeter Zijlstra RET 366dcc5627SJiri SlabySYM_FUNC_END(__sw_hweight32) 37784d5699SAl ViroEXPORT_SYMBOL(__sw_hweight32) 38f5967101SBorislav Petkov 396dcc5627SJiri SlabySYM_FUNC_START(__sw_hweight64) 40f5967101SBorislav Petkov#ifdef CONFIG_X86_64 4165ea11ecSVille Syrjälä pushq %rdi 42f5967101SBorislav Petkov pushq %rdx 43f5967101SBorislav Petkov 44f5967101SBorislav Petkov movq %rdi, %rdx # w -> t 45f5967101SBorislav Petkov movabsq $0x5555555555555555, %rax 46f5967101SBorislav Petkov shrq %rdx # t >>= 1 47f5967101SBorislav Petkov andq %rdx, %rax # t &= 0x5555555555555555 48f5967101SBorislav Petkov movabsq $0x3333333333333333, %rdx 49f5967101SBorislav Petkov subq %rax, %rdi # w -= t 50f5967101SBorislav Petkov 51f5967101SBorislav Petkov movq %rdi, %rax # w -> t 52f5967101SBorislav Petkov shrq $2, %rdi # w_tmp >>= 2 53f5967101SBorislav Petkov andq %rdx, %rax # t &= 0x3333333333333333 54f5967101SBorislav Petkov andq %rdi, %rdx # w_tmp &= 0x3333333333333333 55f5967101SBorislav Petkov addq %rdx, %rax # w = w_tmp + t 56f5967101SBorislav Petkov 57f5967101SBorislav Petkov movq %rax, %rdx # w -> t 58f5967101SBorislav Petkov shrq $4, %rdx # t >>= 4 59f5967101SBorislav Petkov addq %rdx, %rax # w_tmp += t 60f5967101SBorislav Petkov movabsq $0x0f0f0f0f0f0f0f0f, %rdx 61f5967101SBorislav Petkov andq %rdx, %rax # w_tmp &= 0x0f0f0f0f0f0f0f0f 62f5967101SBorislav Petkov movabsq $0x0101010101010101, %rdx 63f5967101SBorislav Petkov imulq %rdx, %rax # w_tmp *= 0x0101010101010101 64f5967101SBorislav Petkov shrq $56, %rax # w = w_tmp >> 56 65f5967101SBorislav Petkov 66f5967101SBorislav Petkov popq %rdx 6765ea11ecSVille Syrjälä popq %rdi 68*f94909ceSPeter Zijlstra RET 69f5967101SBorislav Petkov#else /* CONFIG_X86_32 */ 70f5967101SBorislav Petkov /* We're getting an u64 arg in (%eax,%edx): unsigned long hweight64(__u64 w) */ 71f5967101SBorislav Petkov pushl %ecx 72f5967101SBorislav Petkov 73f5967101SBorislav Petkov call __sw_hweight32 74f5967101SBorislav Petkov movl %eax, %ecx # stash away result 75f5967101SBorislav Petkov movl %edx, %eax # second part of input 76f5967101SBorislav Petkov call __sw_hweight32 77f5967101SBorislav Petkov addl %ecx, %eax # result 78f5967101SBorislav Petkov 79f5967101SBorislav Petkov popl %ecx 80*f94909ceSPeter Zijlstra RET 81f5967101SBorislav Petkov#endif 826dcc5627SJiri SlabySYM_FUNC_END(__sw_hweight64) 83784d5699SAl ViroEXPORT_SYMBOL(__sw_hweight64) 84