xref: /DragonOS/kernel/src/arch/x86_64/math/bitcount.h (revision 196b75dc17b5cc2ed84301bce776e496ddfe1ed1)
1 #include <common/stddef.h>
2 
3 /**
4  * @brief 统计二进制数的前导0
5  *
6  * @param x 待统计的数
7  * @return int 结果
8  */
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  */
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  */
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 
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 
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