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