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