diff --git a/kernel/arch/x86_64/math/bitcount.h b/kernel/arch/x86_64/math/bitcount.h new file mode 100644 index 00000000..307d6842 --- /dev/null +++ b/kernel/arch/x86_64/math/bitcount.h @@ -0,0 +1,55 @@ +#include + +/** + * @brief 统计二进制数的前导0 + * + * @param x 待统计的数 + * @return int 结果 + */ +static __always_inline int __clz(uint32_t x) +{ + asm volatile("bsr %%eax, %%eax\n\t" + "xor $0x1f, %%eax\n\t" + : "=a"(x) + : "a"(x) + : "memory"); + return x; +} + +/** + * @brief 统计二进制数的前导0 (宽度为unsigned long) + * + * @param x 待统计的数 + * @return int 结果 + */ +static __always_inline int __clzl(unsigned long x) +{ + int res = 0; + asm volatile("cltq\n\t" + "bsr %%rax, %%rax\n\t" + "xor $0x3f, %%rax\n\t" + "mov %%eax,%0\n\t" + : "=m"(res) + : "a"(x) + : "memory"); + return res; +} + +/** + * @brief 统计二进制数的前导0(宽度为unsigned long long) + * + * @param x 待统计的数 + * @return int 结果 + */ +static __always_inline int __clzll(unsigned long long x) +{ + int res = 0; + asm volatile("cltq\n\t" + "bsr %%rax, %%rax\n\t" + "xor $0x3f, %%rax\n\t" + "mov %%eax,%0\n\t" + : "=m"(res) + : "a"(x) + : "memory"); + return res; +} \ No newline at end of file diff --git a/kernel/common/math.h b/kernel/common/math.h index 9d76645a..6e38a669 100644 --- a/kernel/common/math.h +++ b/kernel/common/math.h @@ -1,3 +1,10 @@ #pragma once #include "stddef.h" -int64_t pow(int64_t x, int y); \ No newline at end of file +#include +#if ARCH(I386) || ARCH(X86_64) +#include +#else +#error Arch not supported. +#endif + +int64_t pow(int64_t x, int y);