Subversion Repositories Kolibri OS

Rev

Rev 6934 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5270 serge 1
#ifndef _ASM_X86_HWEIGHT_H
2
#define _ASM_X86_HWEIGHT_H
3
 
7143 serge 4
#include 
5
 
5270 serge 6
#ifdef CONFIG_64BIT
7
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
8
#define POPCNT32 ".byte 0xf3,0x40,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
/*
21
 * __sw_hweightXX are called from within the alternatives below
22
 * and callee-clobbered registers need to be taken care of. See
23
 * ARCH_HWEIGHT_CFLAGS in  for the respective
24
 * compiler switches.
25
 */
6082 serge 26
static __always_inline unsigned int __arch_hweight32(unsigned int w)
5270 serge 27
{
6082 serge 28
    unsigned int res = w - ((w >> 1) & 0x55555555);
29
    res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
30
    res = (res + (res >> 4)) & 0x0F0F0F0F;
31
    res = res + (res >> 8);
32
    return (res + (res >> 16)) & 0x000000FF;
5270 serge 33
}
34
 
35
static inline unsigned int __arch_hweight16(unsigned int w)
36
{
37
	return __arch_hweight32(w & 0xffff);
38
}
39
 
40
static inline unsigned int __arch_hweight8(unsigned int w)
41
{
42
	return __arch_hweight32(w & 0xff);
43
}
44
 
6082 serge 45
#ifdef CONFIG_X86_32
5270 serge 46
static inline unsigned long __arch_hweight64(__u64 w)
47
{
48
	return  __arch_hweight32((u32)w) +
49
		__arch_hweight32((u32)(w >> 32));
6082 serge 50
}
5270 serge 51
#else
6082 serge 52
static __always_inline unsigned long __arch_hweight64(__u64 w)
53
{
54
	unsigned long res = 0;
55
 
5270 serge 56
	asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
57
		     : "="REG_OUT (res)
58
		     : REG_IN (w));
59
 
60
	return res;
61
}
6082 serge 62
#endif /* CONFIG_X86_32 */
5270 serge 63
 
64
#endif