xref: /DragonOS/kernel/src/arch/x86_64/math/bitcount.h (revision 2813126e3190c9b3c1a836a647b259a7adbe0cf3)
1 #include <common/stddef.h>
2 
3 /**
4  * @brief 统计二进制数的前导0
5  *
6  * @param x 待统计的数
7  * @return int 结果
8  */
__clz(uint32_t x)9 static __always_inline int __clz(uint32_t x)
10 {
11     asm volatile("bsr %%eax, %%eax\n\t"
12                  "xor $0x1f, %%eax\n\t"
13                  : "=a"(x)
14                  : "a"(x)
15                  : "memory");
16     return x;
17 }
18 
19 /**
20  * @brief 统计二进制数的前导0 (宽度为unsigned long)
21  *
22  * @param x 待统计的数
23  * @return int 结果
24  */
__clzl(unsigned long x)25 static __always_inline int __clzl(unsigned long x)
26 {
27     int res = 0;
28     asm volatile("cltq\n\t"
29                  "bsr %%rax, %%rax\n\t"
30                  "xor $0x3f, %%rax\n\t"
31                  "mov %%eax,%0\n\t"
32                  : "=m"(res)
33                  : "a"(x)
34                  : "memory");
35     return res;
36 }
37 
38 /**
39  * @brief 统计二进制数的前导0(宽度为unsigned long long)
40  *
41  * @param x 待统计的数
42  * @return int 结果
43  */
__clzll(unsigned long long x)44 static __always_inline int __clzll(unsigned long long x)
45 {
46     int res = 0;
47     asm volatile("cltq\n\t"
48                  "bsr %%rax, %%rax\n\t"
49                  "xor $0x3f, %%rax\n\t"
50                  "mov %%eax,%0\n\t"
51                  : "=m"(res)
52                  : "a"(x)
53                  : "memory");
54     return res;
55 }
56 
__ctz(uint32_t x)57 static __always_inline int __ctz(uint32_t x)
58 {
59     asm volatile("tzcnt %%eax, %%eax":"=a"(x):"a"(x):"memory");
60     return x;
61 }
62 
__ctzl(unsigned long x)63 static __always_inline int __ctzl(unsigned long x)
64 {
65     asm volatile("tzcnt %%rax, %%rax":"=a"(x):"a"(x):"memory");
66     return x;
67 }
68 
69 #define __ctzll __ctzl